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