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