1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - libraries - snd - common
3 File: snd_work.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-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/snd/common/work.h>
19
20 #ifndef SDK_FROM_TOOL
21
22 #else
23
24 #define REG_SND_SOUND0CNT_E_SHIFT 31
25 #define REG_SND_SOUND0CNT_E_SIZE 1
26 #define REG_SND_SOUND0CNT_E_MASK 0x80000000
27
28 #define REG_SND_SOUND0CNT_FORMAT_SHIFT 29
29 #define REG_SND_SOUND0CNT_FORMAT_SIZE 2
30 #define REG_SND_SOUND0CNT_FORMAT_MASK 0x60000000
31
32 #define REG_SND_SOUND0CNT_REPEAT_SHIFT 27
33 #define REG_SND_SOUND0CNT_REPEAT_SIZE 2
34 #define REG_SND_SOUND0CNT_REPEAT_MASK 0x18000000
35
36 #define REG_SND_SOUND0CNT_DUTY_SHIFT 24
37 #define REG_SND_SOUND0CNT_DUTY_SIZE 3
38 #define REG_SND_SOUND0CNT_DUTY_MASK 0x07000000
39
40 #define REG_SND_SOUND0CNT_PAN_SHIFT 16
41 #define REG_SND_SOUND0CNT_PAN_SIZE 7
42 #define REG_SND_SOUND0CNT_PAN_MASK 0x007f0000
43
44 #define REG_SND_SOUND0CNT_HOLD_SHIFT 15
45 #define REG_SND_SOUND0CNT_HOLD_SIZE 1
46 #define REG_SND_SOUND0CNT_HOLD_MASK 0x00008000
47
48 #define REG_SND_SOUND0CNT_SHIFT_SHIFT 8
49 #define REG_SND_SOUND0CNT_SHIFT_SIZE 2
50 #define REG_SND_SOUND0CNT_SHIFT_MASK 0x00000300
51
52 #define REG_SND_SOUND0CNT_VOLUME_SHIFT 0
53 #define REG_SND_SOUND0CNT_VOLUME_SIZE 7
54 #define REG_SND_SOUND0CNT_VOLUME_MASK 0x0000007f
55
56 #define SDK_ASSERT(exp) ((void) 0)
57 #define SDK_NULL_ASSERT(exp) ((void) 0)
58 #define SDK_MINMAX_ASSERT(exp, min, max) ((void) 0)
59
60 #endif
61
62 /******************************************************************************
63 Private variable
64 ******************************************************************************/
65
66 SNDSharedWork *SNDi_SharedWork;
67
68 #ifdef SDK_ARM7
69
70 SNDWork SNDi_Work;
71
72 #endif /* SDK_ARM7 */
73
74 /******************************************************************************
75 Static function declarations
76 ******************************************************************************/
77 static const void *ConvAddr(const void *p, const void *baseFrom, const void *baseTo);
78
79 /******************************************************************************
80 Inline functions
81 ******************************************************************************/
82
83 /*---------------------------------------------------------------------------*
84 Name: ConvAddr
85
86 Description: Performs address conversion.
87
88 Arguments: p - Original address to convert
89 baseFrom - Base address of the original address
90 baseFrom - Base address of the address after conversion
91
92 Returns: Address after conversion.
93 *---------------------------------------------------------------------------*/
94 #ifndef _MSC_VER
95 static inline
96 #else
97 __inline
98 #endif
ConvAddr(const void * p,const void * baseFrom,const void * baseTo)99 const void *ConvAddr(const void *p, const void *baseFrom, const void *baseTo)
100 {
101 if (p == NULL)
102 return NULL;
103 return (const char *)baseTo + ((const char *)p - (const char *)baseFrom);
104 }
105
106 /******************************************************************************
107 Public functions
108 ******************************************************************************/
109
110 /*---------------------------------------------------------------------------*
111 Name: SND_GetPlayerStatus
112
113 Description: Gets the player status.
114
115 Arguments: None.
116
117 Returns: Player status bit mask.
118 Active if a bit is on.
119 *---------------------------------------------------------------------------*/
SND_GetPlayerStatus(void)120 u32 SND_GetPlayerStatus(void)
121 {
122 SDK_NULL_ASSERT(SNDi_SharedWork);
123
124 #ifdef SDK_ARM9
125 DC_InvalidateRange((void *)&SNDi_SharedWork->playerStatus,
126 sizeof(SNDi_SharedWork->playerStatus));
127 #endif
128
129 return SNDi_SharedWork->playerStatus;
130 }
131
132 /*---------------------------------------------------------------------------*
133 Name: SND_GetChannelStatus
134
135 Description: Gets the channel status.
136
137 Arguments: None.
138
139 Returns: Channel status bit mask.
140 Active if a bit is on.
141 *---------------------------------------------------------------------------*/
SND_GetChannelStatus(void)142 u32 SND_GetChannelStatus(void)
143 {
144 SDK_NULL_ASSERT(SNDi_SharedWork);
145
146 #ifdef SDK_ARM9
147 DC_InvalidateRange((void *)&SNDi_SharedWork->channelStatus,
148 sizeof(SNDi_SharedWork->channelStatus));
149 #endif
150
151 return SNDi_SharedWork->channelStatus;
152 }
153
154 /*---------------------------------------------------------------------------*
155 Name: SND_GetCaptureStatus
156
157 Description: Gets the capture status.
158
159 Arguments: None.
160
161 Returns: Capture status bit mask.
162 Active if a bit is on.
163 *---------------------------------------------------------------------------*/
SND_GetCaptureStatus(void)164 u32 SND_GetCaptureStatus(void)
165 {
166 SDK_NULL_ASSERT(SNDi_SharedWork);
167
168 #ifdef SDK_ARM9
169 DC_InvalidateRange((void *)&SNDi_SharedWork->captureStatus,
170 sizeof(SNDi_SharedWork->captureStatus));
171 #endif
172
173 return SNDi_SharedWork->captureStatus;
174 }
175
176 /*---------------------------------------------------------------------------*
177 Name: SND_GetPlayerTickCounter
178
179 Description: Gets the player's tick counter.
180
181 Arguments: playerNo - Player number
182
183 Returns: Tick counter value.
184 *---------------------------------------------------------------------------*/
SND_GetPlayerTickCounter(int playerNo)185 u32 SND_GetPlayerTickCounter(int playerNo)
186 {
187 SDK_NULL_ASSERT(SNDi_SharedWork);
188 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
189
190 #ifdef SDK_ARM9
191 DC_InvalidateRange((void *)&SNDi_SharedWork->player[playerNo].tickCounter,
192 sizeof(SNDi_SharedWork->player[playerNo].tickCounter));
193 #endif
194
195 return SNDi_SharedWork->player[playerNo].tickCounter;
196 }
197
198 /*---------------------------------------------------------------------------*
199 Name: SND_GetPlayerLocalVariable
200
201 Description: Gets the sequence local variables.
202
203 Arguments: playerNo - Player number
204 varNo - Variable number
205
206 Returns: Value of the variable.
207 *---------------------------------------------------------------------------*/
SND_GetPlayerLocalVariable(int playerNo,int varNo)208 s16 SND_GetPlayerLocalVariable(int playerNo, int varNo)
209 {
210 SDK_NULL_ASSERT(SNDi_SharedWork);
211 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
212 SDK_MINMAX_ASSERT(varNo, 0, SND_PLAYER_VARIABLE_NUM - 1);
213
214 #ifdef SDK_ARM9
215 DC_InvalidateRange((void *)&SNDi_SharedWork->player[playerNo].variable[varNo],
216 sizeof(SNDi_SharedWork->player[playerNo].variable[varNo]));
217 #endif
218
219 return SNDi_SharedWork->player[playerNo].variable[varNo];
220 }
221
222 /*---------------------------------------------------------------------------*
223 Name: SND_GetPlayerGlobalVariable
224
225 Description: Gets the sequence global variable.
226
227 Arguments: varNo - Variable number
228
229 Returns: Value of the variable.
230 *---------------------------------------------------------------------------*/
SND_GetPlayerGlobalVariable(int varNo)231 s16 SND_GetPlayerGlobalVariable(int varNo)
232 {
233 SDK_NULL_ASSERT(SNDi_SharedWork);
234 SDK_MINMAX_ASSERT(varNo, 0, SND_GLOBAL_VARIABLE_NUM - 1);
235
236 #ifdef SDK_ARM9
237 DC_InvalidateRange((void *)&SNDi_SharedWork->globalVariable[varNo],
238 sizeof(SNDi_SharedWork->globalVariable[varNo]));
239 #endif
240
241 return SNDi_SharedWork->globalVariable[varNo];
242 }
243
244 /*---------------------------------------------------------------------------*
245 Name: SND_ReadChannelInfo
246
247 Description: Reads the channel information.
248
249 Arguments: driverInfo - Driver information structure
250 chNo - Channel number
251 chInfo - Channel information structure that stores the obtained information
252
253 Returns: Whether read was successful.
254 *---------------------------------------------------------------------------*/
SND_ReadChannelInfo(const SNDDriverInfo * driverInfo,int chNo,SNDChannelInfo * chInfo)255 BOOL SND_ReadChannelInfo(const SNDDriverInfo * driverInfo, int chNo, SNDChannelInfo * chInfo)
256 {
257 u32 lockedChannel;
258
259 SDK_NULL_ASSERT(driverInfo);
260 SDK_NULL_ASSERT(chInfo);
261
262 if (chNo < SND_CHANNEL_MIN || SND_CHANNEL_MAX < chNo)
263 return FALSE;
264
265 lockedChannel = driverInfo->lockedChannels;
266 chInfo->lockFlag = (lockedChannel & (1 << chNo)) ? TRUE : FALSE;
267
268 if (chInfo->lockFlag)
269 {
270 const u32 chCtrl = driverInfo->chCtrl[chNo];
271
272 chInfo->activeFlag = (chCtrl & REG_SND_SOUND0CNT_E_MASK) ? TRUE : FALSE;
273
274 {
275 const u8 volume =
276 (u8)((chCtrl & REG_SND_SOUND0CNT_VOLUME_MASK) >> REG_SND_SOUND0CNT_VOLUME_SHIFT);
277 const SNDChannelDataShift shift =
278 (SNDChannelDataShift)((chCtrl & REG_SND_SOUND0CNT_SHIFT_MASK) >>
279 REG_SND_SOUND0CNT_SHIFT_SHIFT);
280
281 chInfo->volume = volume;
282 chInfo->volume <<= 4;
283 switch (shift)
284 {
285 case SND_CHANNEL_DATASHIFT_NONE:
286 break;
287 case SND_CHANNEL_DATASHIFT_1BIT:
288 chInfo->volume >>= 1;
289 break;
290 case SND_CHANNEL_DATASHIFT_2BIT:
291 chInfo->volume >>= 2;
292 break;
293 case SND_CHANNEL_DATASHIFT_4BIT:
294 chInfo->volume >>= 4;
295 break;
296 }
297 }
298
299 chInfo->pan = (u8)((chCtrl & REG_SND_SOUND0CNT_PAN_MASK) >> REG_SND_SOUND0CNT_PAN_SHIFT);
300 }
301 else
302 {
303 const SNDExChannel *chp = &driverInfo->work.channel[chNo];
304 SDK_NULL_ASSERT(chp);
305
306 chInfo->activeFlag = chp->active_flag;
307 chInfo->envStatus = (SNDEnvStatus)(chp->env_status);
308
309 {
310 const u8 volume = (u8)(chp->volume & 0xff);
311 const SNDChannelDataShift shift = (SNDChannelDataShift)(chp->volume >> 8);
312
313 chInfo->volume = volume;
314 chInfo->volume <<= 4;
315 switch (shift)
316 {
317 case SND_CHANNEL_DATASHIFT_NONE:
318 break;
319 case SND_CHANNEL_DATASHIFT_1BIT:
320 chInfo->volume >>= 1;
321 break;
322 case SND_CHANNEL_DATASHIFT_2BIT:
323 chInfo->volume >>= 2;
324 break;
325 case SND_CHANNEL_DATASHIFT_4BIT:
326 chInfo->volume >>= 4;
327 break;
328 }
329 }
330
331 chInfo->pan = chp->pan;
332 }
333
334 return TRUE;
335 }
336
337 /*---------------------------------------------------------------------------*
338 Name: SND_ReadPlayerInfo
339
340 Description: Reads the player information.
341
342 Arguments: driverInfo - Driver information structure
343 playerNo - Player number
344 playerInfo - Player information structure that stores the obtained information
345
346 Returns: Whether read was successful.
347 *---------------------------------------------------------------------------*/
SND_ReadPlayerInfo(const SNDDriverInfo * driverInfo,int playerNo,SNDPlayerInfo * playerInfo)348 BOOL SND_ReadPlayerInfo(const SNDDriverInfo * driverInfo, int playerNo, SNDPlayerInfo * playerInfo)
349 {
350 const SNDPlayer *player;
351 int trackNo;
352
353 SDK_NULL_ASSERT(driverInfo);
354 SDK_NULL_ASSERT(playerInfo);
355
356 if (playerNo < SND_PLAYER_MIN || SND_PLAYER_MAX < playerNo)
357 return FALSE;
358
359 player = &driverInfo->work.player[playerNo];
360 SDK_NULL_ASSERT(player);
361
362 playerInfo->trackBitMask = 0;
363 for (trackNo = 0; trackNo < SND_TRACK_NUM_PER_PLAYER; trackNo++)
364 {
365 if (player->tracks[trackNo] != SND_INVALID_TRACK_INDEX)
366 {
367 playerInfo->trackBitMask |= (1 << trackNo);
368 }
369 }
370
371 playerInfo->activeFlag = player->active_flag;
372 playerInfo->pauseFlag = player->pause_flag;
373 playerInfo->tempo = player->tempo;
374 playerInfo->volume = player->volume;
375
376 return TRUE;
377 }
378
379 /*---------------------------------------------------------------------------*
380 Name: SND_ReadTrackInfo
381
382 Description: Reads the track information.
383
384 Arguments: driverInfo - Driver information structure
385 playerNo - Player number
386 trackNo - Track number
387 trackInfo - Track information structure that stores the obtained information
388
389 Returns: Whether read was successful.
390 *---------------------------------------------------------------------------*/
SND_ReadTrackInfo(const SNDDriverInfo * driverInfo,int playerNo,int trackNo,SNDTrackInfo * trackInfo)391 BOOL SND_ReadTrackInfo(const SNDDriverInfo * driverInfo, int playerNo, int trackNo,
392 SNDTrackInfo * trackInfo)
393 {
394 const SNDPlayer *player;
395 const SNDTrack *track;
396 u8 trackID;
397
398 SDK_NULL_ASSERT(driverInfo);
399 SDK_NULL_ASSERT(trackInfo);
400
401 if (playerNo < SND_PLAYER_MIN || SND_PLAYER_MAX < playerNo)
402 return FALSE;
403 if (trackNo < 0 || SND_TRACK_NUM_PER_PLAYER - 1 < trackNo)
404 return FALSE;
405
406 player = &driverInfo->work.player[playerNo];
407 SDK_NULL_ASSERT(player);
408
409 trackID = player->tracks[trackNo];
410 if (trackID == SND_INVALID_TRACK_INDEX)
411 return FALSE;
412
413 track = &driverInfo->work.track[trackID];
414 SDK_NULL_ASSERT(track);
415
416 trackInfo->prgNo = track->prgNo;
417 trackInfo->volume = track->volume;
418 trackInfo->volume2 = track->volume2;
419 trackInfo->pitchBend = track->pitch_bend;
420 trackInfo->bendRange = track->bend_range;
421 trackInfo->pan = (u8)(track->pan + SND_CHANNEL_PAN_CENTER);
422 trackInfo->transpose = track->transpose;
423
424 {
425 const SNDExChannel *chp =
426 (const SNDExChannel *)ConvAddr(track->channel_list, driverInfo->workAddress,
427 &driverInfo->work);
428
429 trackInfo->chCount = 0;
430 while (chp != NULL)
431 {
432 trackInfo->channel[trackInfo->chCount] = chp->myNo;
433 trackInfo->chCount++;
434
435 chp =
436 (const SNDExChannel *)ConvAddr(chp->nextLink, driverInfo->workAddress,
437 &driverInfo->work);
438 }
439 }
440
441 return TRUE;
442 }
443
444 #ifdef SDK_ARM7
445
SND_SetPlayerLocalVariable(int playerNo,int varNo,s16 var)446 void SND_SetPlayerLocalVariable(int playerNo, int varNo, s16 var)
447 {
448 SDK_NULL_ASSERT(SNDi_SharedWork);
449 SDK_MINMAX_ASSERT(playerNo, SND_PLAYER_MIN, SND_PLAYER_MAX);
450 SDK_MINMAX_ASSERT(varNo, 0, SND_PLAYER_VARIABLE_NUM - 1);
451
452 SNDi_SharedWork->player[playerNo].variable[varNo] = var;
453 }
454
SND_SetPlayerGlobalVariable(int varNo,s16 var)455 void SND_SetPlayerGlobalVariable(int varNo, s16 var)
456 {
457 SDK_NULL_ASSERT(SNDi_SharedWork);
458 SDK_MINMAX_ASSERT(varNo, 0, SND_GLOBAL_VARIABLE_NUM - 1);
459
460 SNDi_SharedWork->globalVariable[varNo] = var;
461 }
462
SND_UpdateSharedWork(void)463 void SND_UpdateSharedWork(void)
464 {
465 u16 channelStatus = 0;
466 u16 captureStatus = 0;
467 int chNo;
468
469 if (SNDi_SharedWork == NULL)
470 return;
471
472 for (chNo = 0; chNo < SND_CHANNEL_NUM; chNo++)
473 {
474 if (SND_IsChannelActive(chNo))
475 {
476 channelStatus |= (1 << chNo);
477 }
478 }
479
480 if (SND_IsCaptureActive(SND_CAPTURE_0))
481 captureStatus |= (1 << 0);
482 if (SND_IsCaptureActive(SND_CAPTURE_1))
483 captureStatus |= (1 << 1);
484
485 SNDi_SharedWork->channelStatus = channelStatus;
486 SNDi_SharedWork->captureStatus = captureStatus;
487 }
488
489 #endif /* SDK_ARM7 */
490
491 /******************************************************************************
492 Private function
493 ******************************************************************************/
494
SNDi_GetFinishedCommandTag(void)495 u32 SNDi_GetFinishedCommandTag(void)
496 {
497 SDK_NULL_ASSERT(SNDi_SharedWork);
498
499 #ifdef SDK_ARM9
500 DC_InvalidateRange((void *)&SNDi_SharedWork->finishCommandTag,
501 sizeof(SNDi_SharedWork->finishCommandTag));
502 #endif
503
504 return SNDi_SharedWork->finishCommandTag;
505 }
506
507 #ifdef SDK_ARM9
508
SNDi_InitSharedWork(SNDSharedWork * work)509 void SNDi_InitSharedWork(SNDSharedWork *work)
510 {
511 int playerNo, variableNo;
512
513 work->playerStatus = 0;
514 work->channelStatus = 0;
515 work->captureStatus = 0;
516 work->finishCommandTag = 0;
517
518 for (playerNo = 0; playerNo < SND_PLAYER_NUM; playerNo++)
519 {
520 work->player[playerNo].tickCounter = 0;
521 for (variableNo = 0; variableNo < SND_PLAYER_VARIABLE_NUM; variableNo++)
522 {
523 work->player[playerNo].variable[variableNo] = SND_DEFAULT_VARIABLE;
524 }
525 }
526 for (variableNo = 0; variableNo < SND_GLOBAL_VARIABLE_NUM; variableNo++)
527 {
528 work->globalVariable[variableNo] = SND_DEFAULT_VARIABLE;
529 }
530
531 DC_FlushRange(work, sizeof(SNDSharedWork));
532 }
533
534 #endif /* SDK_ARM9 */
535
536 /*====== End of work.c ======*/
537