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