mirror of
https://github.com/rvtr/TwlIPL_commit-99.git
synced 2025-10-31 06:21:11 -04:00
582 lines
17 KiB
C
Executable File
582 lines
17 KiB
C
Executable File
/*---------------------------------------------------------------------------*
|
||
Project: NITRO-System - libraries - snd
|
||
File: stream.c
|
||
|
||
Copyright 2004-2008 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Revision: 172 $
|
||
*---------------------------------------------------------------------------*/
|
||
#include <nnsys/snd/stream.h>
|
||
|
||
#include <nitro/snd.h>
|
||
#include <nnsys/misc.h>
|
||
#include <nnsys/snd/resource_mgr.h>
|
||
|
||
/******************************************************************************
|
||
structure definition
|
||
******************************************************************************/
|
||
|
||
typedef struct NNSSndStrmChannel
|
||
{
|
||
void* buffer;
|
||
int volume;
|
||
} NNSSndStrmChannel;
|
||
|
||
/******************************************************************************
|
||
static variable
|
||
******************************************************************************/
|
||
|
||
static NNSSndStrmChannel sStrmChannel[ SND_CHANNEL_NUM ];
|
||
static NNSFndList sStrmList;
|
||
|
||
/******************************************************************************
|
||
static function declaration
|
||
******************************************************************************/
|
||
|
||
static void ShutdownStrm( NNSSndStrm* stream );
|
||
static void ForceStopStrm( NNSSndStrm* stream );
|
||
static void AlarmCallback( void* arg );
|
||
static void StrmCallback( NNSSndStrm* stream, NNSSndStrmCallbackStatus status );
|
||
static void BeginSleep( void* arg );
|
||
static void EndSleep( void* arg );
|
||
|
||
/******************************************************************************
|
||
public functions
|
||
******************************************************************************/
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmInit
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmInit( NNSSndStrm* stream )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
{
|
||
static BOOL bInitialized = FALSE;
|
||
|
||
if ( ! bInitialized ) {
|
||
NNS_FND_INIT_LIST( &sStrmList, NNSSndStrm, link );
|
||
|
||
bInitialized = TRUE;
|
||
}
|
||
}
|
||
|
||
PM_SetSleepCallbackInfo( &stream->preSleepInfo, BeginSleep, stream );
|
||
PM_SetSleepCallbackInfo( &stream->postSleepInfo, EndSleep, stream );
|
||
|
||
stream->chBitMask = 0;
|
||
stream->numChannels = 0;
|
||
stream->activeFlag = FALSE;
|
||
stream->startFlag = FALSE;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmAllocChannel
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>p<EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>̊m<CC8A><6D>
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
numChannels - <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD>
|
||
chNoList - <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>ԍ<EFBFBD><D48D><EFBFBD><EFBFBD>X<EFBFBD>g
|
||
|
||
Returns: <20>m<EFBFBD>ۂɐ<DB82><C990><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǂ<EFBFBD><C782><EFBFBD>
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL NNS_SndStrmAllocChannel( NNSSndStrm* stream, int numChannels, const u8 chNoList[] )
|
||
{
|
||
u32 chBitMask;
|
||
int i;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
NNS_MINMAX_ASSERT( numChannels, 1, SND_CHANNEL_NUM );
|
||
|
||
chBitMask = 0;
|
||
for( i = 0; i < numChannels ; i++ )
|
||
{
|
||
NNS_MINMAX_ASSERT( chNoList[ i ], SND_CHANNEL_MIN, SND_CHANNEL_MAX );
|
||
|
||
stream->channelNo[ i ] = chNoList[ i ];
|
||
chBitMask |= ( 1 << chNoList[ i ] );
|
||
}
|
||
|
||
if ( ! NNS_SndLockChannel( chBitMask ) ) {
|
||
return FALSE;
|
||
}
|
||
|
||
stream->numChannels = numChannels;
|
||
stream->chBitMask = chBitMask;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmFreeChannel
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>p<EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>̉<EFBFBD><CC89><EFBFBD>
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmFreeChannel( NNSSndStrm* stream )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( stream->chBitMask == 0 ) return;
|
||
|
||
NNS_SndUnlockChannel( stream->chBitMask );
|
||
|
||
stream->chBitMask = 0;
|
||
stream->numChannels = 0;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmSetup
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃Z<CC83>b<EFBFBD>g<EFBFBD>A<EFBFBD>b<EFBFBD>v
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
format - <20>f<EFBFBD>[<5B>^<5E>t<EFBFBD>H<EFBFBD>[<5B>}<7D>b<EFBFBD>g
|
||
buffer - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>̐擪<CC90>A<EFBFBD>h<EFBFBD><68><EFBFBD>X
|
||
bufSize - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>̃T<CC83>C<EFBFBD>Y
|
||
timer - <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>^<5E>C<EFBFBD>}<7D>[<5B>l
|
||
interval - <20>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD>Ԋu
|
||
callback - <20>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD><EFBFBD>
|
||
arg - <20>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
|
||
|
||
Returns: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǂ<EFBFBD><C782><EFBFBD>
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL NNS_SndStrmSetup(
|
||
NNSSndStrm* stream,
|
||
NNSSndStrmFormat format,
|
||
void* buffer,
|
||
u32 bufSize,
|
||
int timer,
|
||
int interval,
|
||
NNSSndStrmCallback callback,
|
||
void* arg
|
||
)
|
||
{
|
||
NNSSndStrmChannel* chp;
|
||
unsigned int samples;
|
||
unsigned int alarmTimer;
|
||
int chNo;
|
||
int index;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
NNS_ASSERTMSG( ( (u32)buffer & 0x1f ) == 0, "buffer address must be aligned to 32 bytes boundary.");
|
||
NNS_ASSERTMSG( ( bufSize % ( interval * stream->numChannels * 32 ) ) == 0,
|
||
"buffer size must be a multiple of interval * numChannels * 32.");
|
||
NNS_MINMAX_ASSERT( timer, NNS_SND_STRM_TIMER_MIN, NNS_SND_STRM_TIMER_MAX );
|
||
NNS_NULL_ASSERT( callback );
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~ */
|
||
if ( stream->activeFlag ) {
|
||
NNS_SndStrmStop( stream );
|
||
}
|
||
|
||
/* <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>̃o<CC83>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>̌v<CC8C>Z */
|
||
bufSize /= 32 * interval * stream->numChannels;
|
||
stream->chBufLen = bufSize * interval * 32;
|
||
|
||
/* <20>T<EFBFBD><54><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD>̌v<CC8C>Z */
|
||
samples = stream->chBufLen;
|
||
if ( format == NNS_SND_STRM_FORMAT_PCM16 ) samples >>= 1;
|
||
|
||
/* <20>^<5E>C<EFBFBD>}<7D>[<5B>l<EFBFBD>̌v<CC8C>Z */
|
||
NNS_ASSERTMSG( ( samples % interval ) == 0, "interval must be a multiple of sample count." );
|
||
alarmTimer = timer * samples / interval;
|
||
|
||
/* <20><><EFBFBD>\<5C>[<5B>X<EFBFBD>̊m<CC8A><6D> */
|
||
stream->alarmNo = NNS_SndAllocAlarm();
|
||
if ( stream->alarmNo < 0 ) return FALSE;
|
||
|
||
/* <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>̃Z<CC83>b<EFBFBD>g<EFBFBD>A<EFBFBD>b<EFBFBD>v */
|
||
for( index = 0; index < stream->numChannels ; index++ )
|
||
{
|
||
chNo = stream->channelNo[ index ];
|
||
|
||
chp = & sStrmChannel[ chNo ];
|
||
|
||
chp->buffer = (u8*)buffer + stream->chBufLen * index;
|
||
NNS_ALIGN4_ASSERT( chp->buffer );
|
||
|
||
chp->volume = 0;
|
||
|
||
SND_SetupChannelPcm(
|
||
chNo,
|
||
(SNDWaveFormat)format,
|
||
chp->buffer,
|
||
SND_CHANNEL_LOOP_REPEAT,
|
||
0,
|
||
(int)( stream->chBufLen >> 2 ),
|
||
127,
|
||
SND_CHANNEL_DATASHIFT_NONE,
|
||
timer << 5,
|
||
64
|
||
);
|
||
}
|
||
|
||
/* <20>A<EFBFBD><41><EFBFBD>[<5B><><EFBFBD>̐ݒ<CC90> */
|
||
SND_SetupAlarm(
|
||
stream->alarmNo,
|
||
alarmTimer,
|
||
alarmTimer,
|
||
AlarmCallback,
|
||
stream
|
||
);
|
||
|
||
/* <20><><EFBFBD>X<EFBFBD>g<EFBFBD>ւ̓o<CC93>^ */
|
||
NNS_FndAppendListObject( &sStrmList, stream );
|
||
|
||
/* <20>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD>[<5B>^<5E>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD> */
|
||
stream->format = format;
|
||
stream->interval = interval;
|
||
stream->callback = callback;
|
||
stream->callbackArg = arg;
|
||
stream->curBuffer = 0;
|
||
|
||
stream->volume = 0;
|
||
|
||
stream->activeFlag = TRUE;
|
||
|
||
/* <20>Z<EFBFBD>b<EFBFBD>g<EFBFBD>A<EFBFBD>b<EFBFBD>v<EFBFBD>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD>Ăяo<D18F><6F> */
|
||
{
|
||
OSIntrMode old = OS_DisableInterrupts();
|
||
|
||
stream->interval = 1;
|
||
StrmCallback( stream, NNS_SND_STRM_CALLBACK_SETUP );
|
||
stream->interval = interval;
|
||
|
||
(void)OS_RestoreInterrupts( old );
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmStart
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̍Đ<CC8D><C490>J<EFBFBD>n
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmStart( NNSSndStrm* stream )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
SND_StartTimer(
|
||
stream->chBitMask,
|
||
0,
|
||
(u32)( 1 << stream->alarmNo ),
|
||
0
|
||
);
|
||
|
||
if ( ! stream->startFlag )
|
||
{
|
||
PM_PrependPreSleepCallback( & stream->preSleepInfo );
|
||
PM_AppendPostSleepCallback( & stream->postSleepInfo );
|
||
|
||
stream->startFlag = TRUE;
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmStop
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̍Đ<CC8D><C490><EFBFBD><EFBFBD>~
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmStop( NNSSndStrm* stream )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( ! stream->activeFlag ) return;
|
||
|
||
ForceStopStrm( stream );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmSetVolume
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>{<7B><><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>̕ύX
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
volume - <20>{<7B><><EFBFBD><EFBFBD><EFBFBD>[<5B><>
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmSetVolume( NNSSndStrm* stream, int volume )
|
||
{
|
||
u16 chVolume;
|
||
int vol;
|
||
int chNo;
|
||
int i;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
stream->volume = volume;
|
||
|
||
for( i = 0 ; i < stream->numChannels ; i++ )
|
||
{
|
||
chNo = stream->channelNo[ i ];
|
||
vol = stream->volume + sStrmChannel[ chNo ].volume;
|
||
chVolume = SND_CalcChannelVolume( vol );
|
||
|
||
SND_SetChannelVolume(
|
||
(u32)( 1 << chNo ),
|
||
chVolume & 0xff,
|
||
(SNDChannelDataShift)( chVolume >> 8 )
|
||
);
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmSetChannelVolume
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>{<7B><><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>̕ύX
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
chNo - <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>ԍ<EFBFBD>
|
||
volume - <20>{<7B><><EFBFBD><EFBFBD><EFBFBD>[<5B><>
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmSetChannelVolume( NNSSndStrm* stream, int chNo, int volume )
|
||
{
|
||
u16 chVolume;
|
||
int vol;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( chNo > stream->numChannels - 1 ) return;
|
||
|
||
chNo = stream->channelNo[ chNo ];
|
||
sStrmChannel[ chNo ].volume = volume;
|
||
|
||
vol = stream->volume + sStrmChannel[ chNo ].volume;
|
||
chVolume = SND_CalcChannelVolume( vol );
|
||
|
||
SND_SetChannelVolume(
|
||
(u32)( 1 << chNo ),
|
||
chVolume & 0xff,
|
||
(SNDChannelDataShift)( chVolume >> 8 )
|
||
);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: NNS_SndStrmSetChannelPan
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>p<EFBFBD><70><EFBFBD>̕ύX
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
chNo - <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD>ԍ<EFBFBD>
|
||
pan - <20>p<EFBFBD><70>.
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void NNS_SndStrmSetChannelPan( NNSSndStrm* stream, int chNo, int pan )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
NNS_MINMAX_ASSERT( pan, NNS_SND_STRM_PAN_MIN, NNS_SND_STRM_PAN_MAX );
|
||
|
||
if ( chNo > stream->numChannels - 1 ) return;
|
||
|
||
SND_SetChannelPan( (u32)( 1 << stream->channelNo[ chNo ] ) , pan );
|
||
}
|
||
|
||
/******************************************************************************
|
||
static functions
|
||
******************************************************************************/
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: ForceStopStrm
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̋<EFBFBD><CC8B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g.
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void ForceStopStrm( NNSSndStrm* stream )
|
||
{
|
||
u32 commandTag;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( stream->startFlag )
|
||
{
|
||
SND_StopTimer(
|
||
stream->chBitMask,
|
||
0,
|
||
(u32)( 1 << stream->alarmNo ),
|
||
0
|
||
);
|
||
|
||
PM_DeletePreSleepCallback( & stream->preSleepInfo );
|
||
PM_DeletePostSleepCallback( & stream->postSleepInfo );
|
||
|
||
stream->startFlag = FALSE;
|
||
|
||
commandTag = SND_GetCurrentCommandTag();
|
||
(void)SND_FlushCommand( SND_COMMAND_BLOCK );
|
||
SND_WaitForCommandProc( commandTag );
|
||
}
|
||
|
||
ShutdownStrm( stream );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: ShutdownStrm
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C282><EFBFBD>
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void ShutdownStrm( NNSSndStrm* stream )
|
||
{
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
NNS_SndFreeAlarm( stream->alarmNo );
|
||
|
||
NNS_FndRemoveListObject( & sStrmList, stream );
|
||
|
||
stream->activeFlag = FALSE;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: AlarmCallback
|
||
|
||
Description: <20>A<EFBFBD><41><EFBFBD>[<5B><><EFBFBD>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N
|
||
|
||
Arguments: arg - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void AlarmCallback( void* arg )
|
||
{
|
||
StrmCallback( (NNSSndStrm*)arg, NNS_SND_STRM_CALLBACK_INTERVAL );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: StrmCallback
|
||
|
||
Description: <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N
|
||
|
||
Arguments: stream - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
status - <20>R<EFBFBD>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD>X<EFBFBD>e<EFBFBD>[<5B>^<5E>X
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void StrmCallback( NNSSndStrm* stream, NNSSndStrmCallbackStatus status )
|
||
{
|
||
static void* buffer[ NNS_SND_STRM_CHANNEL_MAX ];
|
||
const unsigned long blockSize = stream->chBufLen / stream->interval;
|
||
const unsigned long offset = blockSize * stream->curBuffer;
|
||
int index;
|
||
int chNo;
|
||
|
||
for( index = 0; index < stream->numChannels ; index++ )
|
||
{
|
||
chNo = stream->channelNo[ index ];
|
||
|
||
buffer[ index ] = (u8*)( sStrmChannel[ chNo ].buffer ) + offset;
|
||
}
|
||
|
||
stream->callback(
|
||
status,
|
||
stream->numChannels,
|
||
buffer,
|
||
blockSize,
|
||
stream->format,
|
||
stream->callbackArg
|
||
);
|
||
|
||
stream->curBuffer++;
|
||
if ( stream->curBuffer >= stream->interval ) stream->curBuffer = 0;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: BeginSleep
|
||
|
||
Description: <20>X<EFBFBD><58><EFBFBD>[<5B>v<EFBFBD><76><EFBFBD>[<5B>h<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD>
|
||
|
||
Arguments: arg - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void BeginSleep( void* arg )
|
||
{
|
||
NNSSndStrm* stream = (NNSSndStrm*)arg;
|
||
u32 commandTag;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( ! stream->startFlag ) return;
|
||
|
||
SND_StopTimer(
|
||
stream->chBitMask,
|
||
0,
|
||
(u32)( 1 << stream->alarmNo ),
|
||
0
|
||
);
|
||
|
||
commandTag = SND_GetCurrentCommandTag();
|
||
(void)SND_FlushCommand( SND_COMMAND_BLOCK );
|
||
SND_WaitForCommandProc( commandTag );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: EndSleep
|
||
|
||
Description: <20>X<EFBFBD><58><EFBFBD>[<5B>v<EFBFBD><76><EFBFBD>[<5B>h<EFBFBD>㏈<EFBFBD><E38F88>
|
||
|
||
Arguments: arg - <20>X<EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void EndSleep( void* arg )
|
||
{
|
||
NNSSndStrm* stream = (NNSSndStrm*)arg;
|
||
|
||
NNS_NULL_ASSERT( stream );
|
||
|
||
if ( ! stream->startFlag ) return;
|
||
|
||
while ( stream->curBuffer != 0 ) {
|
||
OSIntrMode old = OS_DisableInterrupts();
|
||
|
||
StrmCallback( stream, NNS_SND_STRM_CALLBACK_INTERVAL );
|
||
|
||
(void)OS_RestoreInterrupts( old );
|
||
}
|
||
|
||
SND_StartTimer(
|
||
stream->chBitMask,
|
||
0,
|
||
(u32)( 1 << stream->alarmNo ),
|
||
0
|
||
);
|
||
}
|
||
|
||
/*====== End of stream.c ======*/
|
||
|