1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - libraries - snd - ARM9
3 File: snd_interface.c
4
5 Copyright 2004-2008 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 $Date:: 2008-11-28#$
14 $Rev: 9435 $
15 $Author: ida $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/snd/ARM9/interface.h>
19
20 #include <nitro/misc.h>
21 #include <nitro/snd/common/command.h>
22 #include <nitro/snd/common/seq.h>
23 #include <nitro/snd/common/alarm.h>
24
25 /******************************************************************************
26 Macro definitions
27 ******************************************************************************/
28 #define PushCommand( c, a0, a1, a2, a3 ) PushCommand_impl( (c), (u32)(a0), (u32)(a1), (u32)(a2), (u32)(a3) )
29
30 #define GetOffset( type, member ) ( (u32)( &((type*)0)->member ) )
31 #define GetSize( type, member ) ( sizeof( ((type*)0)->member ) )
32
33 /******************************************************************************
34 Static function declarations
35 ******************************************************************************/
36 static void PushCommand_impl(SNDCommandID command, u32 arg0, u32 arg1, u32 arg2, u32 arg3);
37
38 /******************************************************************************
39 Public functions
40 ******************************************************************************/
41
42 /*---------------------------------------------------------------------------*
43 Name: SND_StartSeq
44
45 Description: Starts the sequence.
46
47 Arguments: playerNo - Player number
48 seqBase - Sequence data base address.
49 seqOffset - Sequence data offset.
50 bank_p - Bank pointer.
51
52 Returns: None.
53 *---------------------------------------------------------------------------*/
SND_StartSeq(int playerNo,const void * base,u32 offset,const struct SNDBankData * bank)54 void SND_StartSeq(int playerNo, const void *base, u32 offset, const struct SNDBankData *bank)
55 {
56 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
57 SDK_NULL_ASSERT(base);
58 SDK_NULL_ASSERT(bank);
59
60 PushCommand(SND_COMMAND_START_SEQ, playerNo, base, offset, bank);
61 }
62
63 /*---------------------------------------------------------------------------*
64 Name: SND_StopSeq
65
66 Description: Stops the sequence.
67
68 Arguments: playerNo - Player number
69
70 Returns: None.
71 *---------------------------------------------------------------------------*/
SND_StopSeq(int playerNo)72 void SND_StopSeq(int playerNo)
73 {
74 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
75
76 PushCommand(SND_COMMAND_STOP_SEQ, playerNo, 0, 0, 0);
77 }
78
79 /*---------------------------------------------------------------------------*
80 Name: SND_PrepareSeq
81
82 Description: Prepares for sequence playback.
83
84 Arguments: playerNo - Player number
85 seqBase - Sequence data base address.
86 seqOffset - Sequence data offset.
87 bank_p - Bank pointer.
88
89 Returns: None.
90 *---------------------------------------------------------------------------*/
SND_PrepareSeq(int playerNo,const void * base,u32 offset,const struct SNDBankData * bank)91 void SND_PrepareSeq(int playerNo, const void *base, u32 offset, const struct SNDBankData *bank)
92 {
93 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
94 SDK_NULL_ASSERT(base);
95 SDK_NULL_ASSERT(bank);
96
97 PushCommand(SND_COMMAND_PREPARE_SEQ, playerNo, base, offset, bank);
98 }
99
100 /*---------------------------------------------------------------------------*
101 Name: SND_StartPreparedSeq
102
103 Description: Begins playback of the prepared sequence.
104
105 Arguments: playerNo - Player number
106
107 Returns: None.
108 *---------------------------------------------------------------------------*/
SND_StartPreparedSeq(int playerNo)109 void SND_StartPreparedSeq(int playerNo)
110 {
111 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
112
113 PushCommand(SND_COMMAND_START_PREPARED_SEQ, playerNo, 0, 0, 0);
114 }
115
116 /*---------------------------------------------------------------------------*
117 Name: SND_PauseSeq
118
119 Description: Pauses or resumes the sequence.
120
121 Arguments: playerNo - Player number
122 flag - TRUE to pause, FALSE to resume.
123
124 Returns: None.
125 *---------------------------------------------------------------------------*/
SND_PauseSeq(int playerNo,BOOL flag)126 void SND_PauseSeq(int playerNo, BOOL flag)
127 {
128 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
129
130 PushCommand(SND_COMMAND_PAUSE_SEQ, playerNo, flag, 0, 0);
131 }
132
SND_SetPlayerTempoRatio(int playerNo,int ratio)133 void SND_SetPlayerTempoRatio(int playerNo, int ratio)
134 {
135 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
136
137 SNDi_SetPlayerParam(playerNo,
138 GetOffset(SNDPlayer, tempo_ratio),
139 (u32)ratio, GetSize(SNDPlayer, tempo_ratio));
140 }
141
SND_SetPlayerVolume(int playerNo,int volume)142 void SND_SetPlayerVolume(int playerNo, int volume)
143 {
144 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
145 SDK_MINMAX_ASSERT(volume, -32768, 0);
146
147 SNDi_SetPlayerParam(playerNo,
148 GetOffset(SNDPlayer, extFader), (u32)volume, GetSize(SNDPlayer, extFader));
149 }
150
SND_SetPlayerChannelPriority(int playerNo,int prio)151 void SND_SetPlayerChannelPriority(int playerNo, int prio)
152 {
153 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
154 SDK_MINMAX_ASSERT(prio, 0, 127);
155
156 SNDi_SetPlayerParam(playerNo, GetOffset(SNDPlayer, prio), (u32)prio, GetSize(SNDPlayer, prio));
157 }
158
SND_SetPlayerLocalVariable(int playerNo,int varNo,s16 var)159 void SND_SetPlayerLocalVariable(int playerNo, int varNo, s16 var)
160 {
161 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
162 SDK_MINMAX_ASSERT(varNo, 0, SND_PLAYER_VARIABLE_NUM - 1);
163
164 PushCommand(SND_COMMAND_PLAYER_LOCAL_VAR, playerNo, varNo, var, 0);
165 }
166
SND_SetPlayerGlobalVariable(int varNo,s16 var)167 void SND_SetPlayerGlobalVariable(int varNo, s16 var)
168 {
169 SDK_MINMAX_ASSERT(varNo, 0, SND_GLOBAL_VARIABLE_NUM - 1);
170
171 PushCommand(SND_COMMAND_PLAYER_GLOBAL_VAR, varNo, var, 0, 0);
172 }
173
SND_SetTrackVolume(int playerNo,u32 trackBitMask,int volume)174 void SND_SetTrackVolume(int playerNo, u32 trackBitMask, int volume)
175 {
176 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
177 SDK_MINMAX_ASSERT(volume, -32768, 0);
178
179 SNDi_SetTrackParam(playerNo, trackBitMask,
180 GetOffset(SNDTrack, extFader), (u32)volume, GetSize(SNDTrack, extFader));
181 }
182
SND_SetTrackPitch(int playerNo,u32 trackBitMask,int pitch)183 void SND_SetTrackPitch(int playerNo, u32 trackBitMask, int pitch)
184 {
185 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
186 SDK_MINMAX_ASSERT(pitch, -32768, 32767);
187
188 SNDi_SetTrackParam(playerNo, trackBitMask,
189 GetOffset(SNDTrack, ext_pitch), (u32)pitch, GetSize(SNDTrack, ext_pitch));
190 }
191
SND_SetTrackPan(int playerNo,u32 trackBitMask,int pan)192 void SND_SetTrackPan(int playerNo, u32 trackBitMask, int pan)
193 {
194 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
195 SDK_MINMAX_ASSERT(pan, -128, 127);
196
197 SNDi_SetTrackParam(playerNo, trackBitMask,
198 GetOffset(SNDTrack, ext_pan), (u32)pan, GetSize(SNDTrack, ext_pan));
199 }
200
SND_SetTrackPanRange(int playerNo,u32 trackBitMask,int panRange)201 void SND_SetTrackPanRange(int playerNo, u32 trackBitMask, int panRange)
202 {
203 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
204 SDK_MINMAX_ASSERT(panRange, 0, 127);
205
206 SNDi_SetTrackParam(playerNo, trackBitMask,
207 GetOffset(SNDTrack, pan_range), (u32)panRange, GetSize(SNDTrack, pan_range));
208 }
209
SND_SetTrackModDepth(int playerNo,u32 trackBitMask,int depth)210 void SND_SetTrackModDepth(int playerNo, u32 trackBitMask, int depth)
211 {
212 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
213 SDK_MINMAX_ASSERT(depth, 0, 255);
214
215 SNDi_SetTrackParam(playerNo, trackBitMask,
216 GetOffset(SNDTrack, mod.depth), (u32)depth, GetSize(SNDTrack, mod.depth));
217 }
218
SND_SetTrackModSpeed(int playerNo,u32 trackBitMask,int speed)219 void SND_SetTrackModSpeed(int playerNo, u32 trackBitMask, int speed)
220 {
221 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
222 SDK_MINMAX_ASSERT(speed, 0, 255);
223
224 SNDi_SetTrackParam(playerNo, trackBitMask,
225 GetOffset(SNDTrack, mod.speed), (u32)speed, GetSize(SNDTrack, mod.speed));
226 }
227
SND_SetTrackAllocatableChannel(int playerNo,u32 trackBitMask,u32 chBitMask)228 void SND_SetTrackAllocatableChannel(int playerNo, u32 trackBitMask, u32 chBitMask)
229 {
230 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
231 SDK_MINMAX_ASSERT(chBitMask, 0, 0xffff);
232
233 PushCommand(SND_COMMAND_ALLOCATABLE_CHANNEL, playerNo, trackBitMask, chBitMask, 0);
234 }
235
SND_StartTimer(u32 chBitMask,u32 capBitMask,u32 alarmBitMask,u32 flags)236 void SND_StartTimer(u32 chBitMask, u32 capBitMask, u32 alarmBitMask, u32 flags)
237 {
238 PushCommand(SND_COMMAND_START_TIMER, chBitMask, capBitMask, alarmBitMask, flags);
239 }
240
SND_StopTimer(u32 chBitMask,u32 capBitMask,u32 alarmBitMask,u32 flags)241 void SND_StopTimer(u32 chBitMask, u32 capBitMask, u32 alarmBitMask, u32 flags)
242 {
243 int alarmNo;
244 u32 mask = alarmBitMask;
245
246 for (alarmNo = 0; alarmNo < SND_ALARM_NUM && mask != 0; alarmNo++, mask >>= 1)
247 {
248 if ((mask & 0x01) == 0)
249 continue;
250 SNDi_IncAlarmId(alarmNo);
251 }
252
253 PushCommand(SND_COMMAND_STOP_TIMER, chBitMask, capBitMask, alarmBitMask, flags);
254 }
255
SND_SetupCapture(SNDCapture capture,SNDCaptureFormat format,void * buffer_p,u32 length,BOOL loopFlag,SNDCaptureIn in,SNDCaptureOut out)256 void SND_SetupCapture(SNDCapture capture,
257 SNDCaptureFormat format,
258 void *buffer_p, u32 length, BOOL loopFlag, SNDCaptureIn in, SNDCaptureOut out)
259 {
260 PushCommand(SND_COMMAND_SETUP_CAPTURE,
261 buffer_p,
262 length, capture << 31 | format << 30 | loopFlag << 29 | in << 28 | out << 27, 0);
263 }
264
SND_SetupAlarm(int alarmNo,u32 tick,u32 period,SNDAlarmHandler handler,void * arg)265 void SND_SetupAlarm(int alarmNo, u32 tick, u32 period, SNDAlarmHandler handler, void *arg)
266 {
267 u8 id = SNDi_SetAlarmHandler(alarmNo,
268 handler,
269 arg);
270
271 PushCommand(SND_COMMAND_SETUP_ALARM, alarmNo, tick, period, id);
272 }
273
SND_SetTrackMute(int playerNo,u32 trackBitMask,BOOL flag)274 void SND_SetTrackMute(int playerNo, u32 trackBitMask, BOOL flag)
275 {
276 PushCommand(SND_COMMAND_MUTE_TRACK, playerNo, trackBitMask,
277 flag ? SND_SEQ_MUTE_STOP : SND_SEQ_MUTE_OFF, 0);
278 }
279
SND_SetTrackMuteEx(int playerNo,u32 trackBitMask,SNDSeqMute mute)280 void SND_SetTrackMuteEx(int playerNo, u32 trackBitMask, SNDSeqMute mute)
281 {
282 PushCommand(SND_COMMAND_MUTE_TRACK, playerNo, trackBitMask, mute, 0);
283 }
284
SND_StopUnlockedChannel(u32 chBitMask,u32 flags)285 void SND_StopUnlockedChannel(u32 chBitMask, u32 flags)
286 {
287 PushCommand(SND_COMMAND_STOP_UNLOCKED_CHANNEL, chBitMask, flags, 0, 0);
288 }
289
SND_LockChannel(u32 chBitMask,u32 flags)290 void SND_LockChannel(u32 chBitMask, u32 flags)
291 {
292 PushCommand(SND_COMMAND_LOCK_CHANNEL, chBitMask, flags, 0, 0);
293 }
294
SND_UnlockChannel(u32 chBitMask,u32 flags)295 void SND_UnlockChannel(u32 chBitMask, u32 flags)
296 {
297 PushCommand(SND_COMMAND_UNLOCK_CHANNEL, chBitMask, flags, 0, 0);
298 }
299
SND_SetChannelTimer(u32 chBitMask,int timer)300 void SND_SetChannelTimer(u32 chBitMask, int timer)
301 {
302 PushCommand(SND_COMMAND_CHANNEL_TIMER, chBitMask, timer, 0, 0);
303 }
304
SND_SetChannelVolume(u32 chBitMask,int volume,SNDChannelDataShift shift)305 void SND_SetChannelVolume(u32 chBitMask, int volume, SNDChannelDataShift shift)
306 {
307 PushCommand(SND_COMMAND_CHANNEL_VOLUME, chBitMask, volume, shift, 0);
308 }
309
SND_SetChannelPan(u32 chBitMask,int pan)310 void SND_SetChannelPan(u32 chBitMask, int pan)
311 {
312 PushCommand(SND_COMMAND_CHANNEL_PAN, chBitMask, pan, 0, 0);
313 }
314
SND_SetupChannelPcm(int chNo,SNDWaveFormat format,const void * dataaddr,SNDChannelLoop loop,int loopStart,int loopLen,int volume,SNDChannelDataShift shift,int timer,int pan)315 void SND_SetupChannelPcm(int chNo,
316 SNDWaveFormat format,
317 const void *dataaddr,
318 SNDChannelLoop loop,
319 int loopStart,
320 int loopLen, int volume, SNDChannelDataShift shift, int timer, int pan)
321 {
322 PushCommand(SND_COMMAND_SETUP_CHANNEL_PCM,
323 timer << 16 | chNo,
324 dataaddr,
325 volume << 24 | shift << 22 | loopLen,
326 loop << 26 | format << 24 | pan << 16 | loopStart);
327 }
328
SND_SetupChannelPsg(int chNo,SNDDuty duty,int volume,SNDChannelDataShift shift,int timer,int pan)329 void SND_SetupChannelPsg(int chNo,
330 SNDDuty duty, int volume, SNDChannelDataShift shift, int timer, int pan)
331 {
332 PushCommand(SND_COMMAND_SETUP_CHANNEL_PSG, chNo, shift << 8 | volume, timer << 8 | pan, duty);
333 }
334
SND_SetupChannelNoise(int chNo,int volume,SNDChannelDataShift shift,int timer,int pan)335 void SND_SetupChannelNoise(int chNo, int volume, SNDChannelDataShift shift, int timer, int pan)
336 {
337 PushCommand(SND_COMMAND_SETUP_CHANNEL_NOISE, chNo, shift << 8 | volume, timer << 8 | pan, 0);
338 }
339
SND_InvalidateSeqData(const void * start,const void * end)340 void SND_InvalidateSeqData(const void *start, const void *end)
341 {
342 PushCommand(SND_COMMAND_INVALIDATE_SEQ, start, end, 0, 0);
343 }
344
SND_InvalidateBankData(const void * start,const void * end)345 void SND_InvalidateBankData(const void *start, const void *end)
346 {
347 PushCommand(SND_COMMAND_INVALIDATE_BANK, start, end, 0, 0);
348 }
349
SND_InvalidateWaveData(const void * start,const void * end)350 void SND_InvalidateWaveData(const void *start, const void *end)
351 {
352 PushCommand(SND_COMMAND_INVALIDATE_WAVE, start, end, 0, 0);
353 }
354
SND_SetMasterVolume(int volume)355 void SND_SetMasterVolume(int volume)
356 {
357 PushCommand(SND_COMMAND_MASTER_VOLUME, volume, 0, 0, 0);
358 }
359
SND_SetOutputSelector(SNDOutput left,SNDOutput right,SNDChannelOut channel1,SNDChannelOut channel3)360 void SND_SetOutputSelector(SNDOutput left,
361 SNDOutput right, SNDChannelOut channel1, SNDChannelOut channel3)
362 {
363 PushCommand(SND_COMMAND_OUTPUT_SELECTOR, left, right, channel1, channel3);
364 }
365
SND_SetMasterPan(int pan)366 void SND_SetMasterPan(int pan)
367 {
368 SDK_MINMAX_ASSERT(pan, SND_CHANNEL_PAN_MIN, SND_CHANNEL_PAN_MAX);
369
370 PushCommand(SND_COMMAND_MASTER_PAN, pan, 0, 0, 0);
371 }
372
SND_ResetMasterPan(void)373 void SND_ResetMasterPan(void)
374 {
375 PushCommand(SND_COMMAND_MASTER_PAN, -1, 0, 0, 0);
376 }
377
SND_ReadDriverInfo(struct SNDDriverInfo * info)378 void SND_ReadDriverInfo(struct SNDDriverInfo *info)
379 {
380 PushCommand(SND_COMMAND_READ_DRIVER_INFO, info, 0, 0, 0);
381 }
382
383 /******************************************************************************
384 Private function
385 ******************************************************************************/
386
SNDi_SetPlayerParam(int playerNo,u32 offset,u32 data,int size)387 void SNDi_SetPlayerParam(int playerNo, u32 offset, u32 data, int size)
388 {
389 PushCommand(SND_COMMAND_PLAYER_PARAM, playerNo, offset, data, size);
390 }
391
SNDi_SetTrackParam(int playerNo,u32 trackBitMask,u32 offset,u32 data,int size)392 void SNDi_SetTrackParam(int playerNo, u32 trackBitMask, u32 offset, u32 data, int size)
393 {
394 PushCommand(SND_COMMAND_TRACK_PARAM, size << 24 | playerNo, trackBitMask, offset, data);
395 }
396
SNDi_SetSurroundDecay(int decay)397 void SNDi_SetSurroundDecay(int decay)
398 {
399 PushCommand(SND_COMMAND_SURROUND_DECAY, decay, 0, 0, 0);
400 }
401
SNDi_SkipSeq(int playerNo,u32 tick)402 void SNDi_SkipSeq(int playerNo, u32 tick)
403 {
404 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
405
406 PushCommand(SND_COMMAND_SKIP_SEQ, playerNo, tick, 0, 0);
407 }
408
409 /******************************************************************************
410 Static function
411 ******************************************************************************/
412
PushCommand_impl(SNDCommandID id,u32 arg0,u32 arg1,u32 arg2,u32 arg3)413 static void PushCommand_impl(SNDCommandID id, u32 arg0, u32 arg1, u32 arg2, u32 arg3)
414 {
415 SNDCommand *command = SND_AllocCommand(SND_COMMAND_BLOCK);
416 if (command == NULL)
417 return;
418
419 command->id = id;
420 command->arg[0] = arg0;
421 command->arg[1] = arg1;
422 command->arg[2] = arg2;
423 command->arg[3] = arg3;
424
425 SND_PushCommand(command);
426 }
427
428 /*====== End of snd_interface.c ======*/
429