1 /*---------------------------------------------------------------------------*
2   Project:      MIDI adaptor sample demo
3   File:         synth.c
4 
5   Copyright (C)1998-2007 Nintendo  All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: synth.c,v $
14   Revision 1.2  2007/04/17 08:23:52  hiratsu
15   Refactoring.  Removed unused functions and variables.
16 
17   Revision 1.1  2007/04/13 08:39:10  hiratsu
18   Initial check-in.
19   (Most of codes are derived from syndemo.c)
20 
21 
22   $NoKeywords: $
23  *---------------------------------------------------------------------------*/
24 
25 /*---------------------------------------------------------------------------*
26   This program shows how to set up and use the AX
27  *---------------------------------------------------------------------------*/
28 #include "synth.h"
29 
30 #include <string.h>
31 #include <revolution.h>
32 #include <revolution/mix.h>
33 #include <revolution/syn.h>
34 #include <revolution/mem.h>
35 
36 static MEMHeapHandle hExpHeap;
37 
38 
39 SYNSYNTH    synth;
40 
41 
42 /*---------------------------------------------------------------------------*
43  *---------------------------------------------------------------------------*/
callbackDropVoice(void * p)44 static void callbackDropVoice(void *p)
45 {
46     AXVPB *pvpb = p;
47 
48     OSReport("PVPB %.8x is being dropped context %d\n", pvpb, pvpb->userContext);
49 }
50 
51 
52 /*---------------------------------------------------------------------------*
53  *---------------------------------------------------------------------------*/
callbackAudioFrame(void)54 static void callbackAudioFrame(void)
55 {
56     // run the synth
57     SYNRunAudioFrame();
58 
59     // tell the mixer to update settings
60     MIXUpdateSettings();
61 }
62 
63 
64 /*---------------------------------------------------------------------------*
65  *---------------------------------------------------------------------------*/
programChange(u8 prog)66 void programChange(u8 prog)
67 {
68     u8 ch[3];
69     int old;
70 
71     ASSERTMSG(0<=prog && prog<128, "Out of range. (Illegal program number.)");
72 
73     ch[0] = 0xC0;
74     ch[1] = prog;
75     OSReport("program: %d\n", prog);
76 
77     old = OSDisableInterrupts();
78     SYNMidiInput(&synth, ch);
79     OSRestoreInterrupts(old);
80 }
81 
82 
83 /*---------------------------------------------------------------------------*
84  *---------------------------------------------------------------------------*/
input(u8 * ch)85 void input(u8 *ch)
86 {
87     int old = OSDisableInterrupts();
88     SYNMidiInput(&synth, ch);
89     OSRestoreInterrupts(old);
90 }
91 
92 
93 /*---------------------------------------------------------------------------*
94  *---------------------------------------------------------------------------*/
LoadFileIntoRam(char * path)95 static void* LoadFileIntoRam(char *path)
96 {
97     DVDFileInfo handle;
98     u32         round_length;
99     s32         read_length;
100     void        *buffer;
101 
102     // Open File
103     if (!DVDOpen(path, &handle))
104     {
105         OSReport("WARNING! Failed to open %s\n", path);
106         return NULL;
107     }
108 
109     // Make sure file length is not 0
110     if (DVDGetLength(&handle) == 0)
111     {
112         OSReport("WARNING! File length is 0\n");
113         return NULL;
114     }
115 
116     round_length = OSRoundUp32B(DVDGetLength(&handle));
117     buffer       = MEMAllocFromExpHeapEx(hExpHeap, round_length,  32);
118 
119     // Make sure we got a buffer
120     if (buffer == NULL)
121     {
122         OSReport("WARNING! Unable to allocate buffer\n");
123         return NULL;
124     }
125 
126     // Read Files
127     read_length = DVDRead(&handle, buffer, (s32)(round_length), 0);
128 
129     // Make sure we read the file correctly
130     if (read_length <= 0)
131     {
132         OSReport("WARNING! File lenght is wrong\n");
133         return NULL;
134     }
135 
136     return buffer;
137 }
138 
139 /*---------------------------------------------------------------------------*
140  *---------------------------------------------------------------------------*/
initialize(void)141 void initialize(void)
142 {
143     u8         *wavetable;
144     void       *arenaMem2Lo;
145     void       *arenaMem2Hi;
146     u8         *samples;
147     void       *axBuffer;
148     void       *mixBuffer;
149     void       *synBuffer;
150 
151     arenaMem2Lo = OSGetMEM2ArenaLo();
152     arenaMem2Hi = OSGetMEM2ArenaHi();
153     hExpHeap    = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo);
154 
155     AIInit(NULL);
156 
157     axBuffer  = MEMAllocFromExpHeapEx(hExpHeap, AXGetMemorySize(AX_MAX_VOICES), 32);
158     mixBuffer = MEMAllocFromExpHeap(hExpHeap, MIXGetMemorySize(AX_MAX_VOICES));
159     synBuffer = MEMAllocFromExpHeap(hExpHeap, SYNGetMemorySize(AX_MAX_VOICES));
160 
161     AXInitSpecifyMem(AX_MAX_VOICES, axBuffer);
162     MIXInitSpecifyMem(mixBuffer);
163     SYNInitSpecifyMem(synBuffer);
164 
165     wavetable  = LoadFileIntoRam("/axdemo/synth/gm16pcm.wt");
166     samples    = LoadFileIntoRam("/axdemo/synth/gm16pcm.pcm");
167 
168     // register user callback for audio frames notification
169     AXRegisterCallback(&callbackAudioFrame);
170 
171     // initialize synth
172     SYNInitSynth(
173         &synth,             // pointer to synth object
174         wavetable,          // pointer to wavetable
175         samples,            // pointer to samples
176         NULL,               // pointer to zero buffer (no need)
177         16,                 // priority for voice allocation
178         15,                 // priority for notes
179         1                   // priority for notes that have been released
180         );
181 
182     return;
183 
184     // finalize process
185     SYNQuit();
186     MIXQuit();
187     AXQuit();
188 
189     if (wavetable)
190     {
191         MEMFreeToExpHeap(hExpHeap, wavetable);
192     }
193 
194     if (samples)
195     {
196         MEMFreeToExpHeap(hExpHeap, samples);
197     }
198 
199     if (axBuffer)
200     {
201         MEMFreeToExpHeap(hExpHeap, axBuffer);
202     }
203 
204     if (mixBuffer)
205     {
206         MEMFreeToExpHeap(hExpHeap, mixBuffer);
207     }
208 
209     if (synBuffer)
210     {
211         MEMFreeToExpHeap(hExpHeap, synBuffer);
212     }
213 }
214