TwlIPL_commit-99/add-ins/TwlSystem/build/libraries/snd/src/stream.c

582 lines
17 KiB
C
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
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 ======*/