decoder.h File Reference


Detailed Description

Decoder module C header file.

REVISION

Definition in file decoder.h.

#include "../feature.h"
#include "../TISTD/dectask.h"
#include "../TISTD/idecode.h"
#include "../TISTD/iscrypt.h"
#include "../TISTD/ispecan.h"
#include "../PIPE/pipe.h"
#include "vorbis/OGGV_ogg.h"
#include "../TISTD/wma_ti.h"

Include dependency graph for decoder.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  st_WARNING
 Decoder warning structure. More...
struct  st_DECODER
 Decoder control structure definition. More...

Defines

#define READ_THRESHOLD   0x400
 Threshold to minize the media reading frequency.

Enumerations

enum  DEC_TYPE
 Decoder type definition.

Functions

BOOL DECODER__mp3first (void)
 Function check to set up mp3 decoder input bit stream.
USHORT DECODER__mp3media (void)
 Function serves as the decoder media access task handle.
BOOL DECODER__mp3 (void)
 Function serves as the mp3 decoder task handle.
BOOL DECODER__wavfirst (void)
 Function check to set up WAV decoder input bit stream.
USHORT DECODER__wavmedia (void)
 Function serves as the WAV decoder media access task handle.
BOOL DECODER__wav (void)
 Function serves as the wav decoder task handle.
BOOL DECODER__wmainit (void)
 Function check to init WMA decoder input bit stream.
BOOL DECODER__wmafirst (void)
 Function bridges the WMA subcoder to main decoder handle.
USHORT DECODER__wmamedia (void)
 Function serves as the WMA decoder media access task handle.
BOOL DECODER__wma (void)
 Function serves as the WMA decoder data output task handle.
BOOL DECODER__wmatask (void)
 Function serves as the WMA decoder task handle.
BOOL DECODER__oggfirst (void)
 Function check to set up OGG decoder input bit stream.
USHORT DECODER__oggmedia (void)
 Function serves as the OGG decoder media access task handle.
BOOL DECODER__ogg (void)
 Function serves as the OGG decoder task handle.
int * DECODER_main (void)
 Function fetches decoder output upon PCM request.
void DECODER_cache (void)
 Function serves as the decoder cache task handle.
BOOL DECODER_config (DEC_TYPE)
 Function configures the decoder module.
void DECODER_releaseObj (void)
 Function releases all decoder allocated objects.
BOOL DECODER_cacheInit (void)
 Function initialized the decoder cache.
void DECODER_cacheDepthReset (unsigned short)
 Function resets cache depth controls.
unsigned short DECODER_getData (int *, unsigned long, unsigned short)
 Function feeds data into docoder bit stream/buffer.

Variables

st_DECODER Decoder
 Decoder globals.


Function Documentation

BOOL DECODER__mp3 void   ) 
 

Function serves as the mp3 decoder task handle.

Returns:
FALSE if more data is needed, otherwise TRUE;

Definition at line 69 of file DECODER__mp3.c.

References Audio, st_DECODER::averageWordRate, st_DECODER::decode, st_DECODER::decodeBitstrm, Decoder, st_DECODER::decrypt, st_DECODER::firstPacketOffset, st_DECODER::flag, GEN_zeroOut(), st_DECODER::inputBitstrm, st_AUDIO::offset, st_DECODER::pipe, PIPE_writeNext(), st_AUDIO::playtime, st_PCM::sampleRate, SAUDIOTIME_UPDT, and st_DECODER::status.

Referenced by DECODER__mp3first().

00070 {
00071     PIPE_Obj *      pipe = &Decoder.pipe;
00072     int             error = DECODE_NO_ERROR;
00073     int             dataLength, newDataLength;
00074     BOOL            ret = TRUE;
00075     unsigned long   tmpUL = Audio.playtime;
00076     
00077     // Try to decode as long as output pipe is open.
00078     while( PIPE_writeFrameNum(pipe) ) 
00079     {   
00080         BITSTRM_pack(Decoder.decodeBitstrm); 
00081         dataLength = BITSTRM_numDataWords(Decoder.decodeBitstrm);               
00082     
00083         // is there enough data to be decoded?
00084         if( dataLength < INPUT_BUFFER_SIZE - READ_THRESHOLD ) ret = FALSE;
00085         
00086         if( dataLength < (Decoder.status.frameSize + VBR_RESERVED_FORSAFE) )
00087         {    
00088             // NO. data not enough yet, bring up media task. 
00089             return ret;         
00090         }
00091         
00092         // YES. valid data detected, prepare to decode.         
00093         if ( Decoder.flag & (DEC_FFWD|DEC_FRWD|DEC_MEDIASEEK) )
00094         {
00095             //BITSTRM_remove(Decoder.decodeBitstrm, dataLength);    
00096             //BITSTRM_pack(Decoder.decodeBitstrm);      
00097             BITSTRM_reset(Decoder.decodeBitstrm); 
00098             if(Decoder.flag & DEC_MEDIASEEK) 
00099             {
00100                 mp3ReadPtr = Audio.offset;
00101                 DECODE_reset(Decoder.decode);
00102                 Decoder.flag &= ~DEC_MEDIASEEK;
00103             }
00104             else
00105             {
00106                 if(Decoder.flag & DEC_FFWD) mp3ReadPtr += mp3FastFwdLen;
00107                 else if(mp3ReadPtr>mp3FastFwdLen+Decoder.firstPacketOffset)
00108                     mp3ReadPtr -= mp3FastFwdLen;
00109                 else
00110                 {   
00111                     // Send silence to get rid of the noise.
00112                     mp3Silence = 8;
00113                     mp3ReadPtr = Decoder.firstPacketOffset;             
00114                 }
00115             }           
00116             mp3EndOfReadPtr = mp3ReadPtr;           
00117             Decoder.flag &= ~(DEC_FFWD|DEC_FRWD);
00118             ret = FALSE;
00119             
00120             tmpUL = 0;
00121             if(mp3ReadPtr > Decoder.firstPacketOffset)       
00122                 tmpUL = (mp3ReadPtr-Decoder.firstPacketOffset)/Decoder.averageWordRate;         
00123             
00124             mp3FrameIdx = (tmpUL*(Decoder.status.sampleRate/36))>>4;
00125             break;
00126         }
00127         else
00128         {   
00129             if(mp3Silence)
00130             {
00131                 GEN_zeroOut((UINT16*)pipe->WrFrame.Frame, MP3_PIPE_FRAMELEN);
00132                 mp3Silence--;
00133             }
00134             else
00135             {   
00136                 // decode the bitstream 
00137                 error = DECODE_decode(  Decoder.decode, 
00138                                         Decoder.decodeBitstrm, 
00139                                         (Int *)pipe->WrFrame.Frame);
00140                 
00141                 BITSTRM_pack(Decoder.decodeBitstrm); 
00142                 newDataLength = BITSTRM_numDataWords(Decoder.decodeBitstrm);        
00143                 mp3ReadPtr += dataLength-newDataLength;
00144                 
00145                 if (error == DECODE_NO_ERROR)
00146                 {               
00147                     // Get decode status, which will be checked in codec data 
00148                     // feed routine. 
00149                     DECODE_getStatus(Decoder.decode, &Decoder.status);
00150                     if(Decoder.status.isValid) 
00151                     {
00152                         unsigned long sampleRate = Decoder.status.sampleRate;
00153                         Pcm.sampleRate = sampleRate;
00154                         PCM_samplerateChanged();
00155                         mp3FastFwdLen = 5L*Decoder.status.bitRate>>4;
00156                     
00157                         mp3FrameIdx++;
00158                         tmpUL = (mp3FrameIdx<<4)/(sampleRate/36);
00159                     }
00160                 }
00161             }
00162         }
00163         
00164         // Any error detected?
00165         if (error == DECODE_NO_ERROR) PIPE_writeNext(pipe);
00166         else if(error == DECODE_ERROR)  
00167         {
00168             // Error, resync on the next call. Note that the output 
00169             // pipe frame is kept for next decoding attempt. 
00170             SCRYPT_reset(Decoder.decrypt);
00171             DECODE_reset(Decoder.decode);                   
00172             BITSTRM_reset(Decoder.inputBitstrm); 
00173         }
00174         //else if (error == DECODE_NO_DATA){} 
00175     }   
00176     
00177     // Check to update time.
00178     if ( Audio.playtime != tmpUL )
00179     {
00180         Audio.playtime = tmpUL;
00181         mMSG_send(sysMsgQ, SYS_MSG_ID, SAUDIOTIME_UPDT, DONTCARE, 0);
00182     }           
00183     
00184     return ret;
00185 }        

Here is the call graph for this function:

BOOL DECODER__mp3first void   ) 
 

Function check to set up mp3 decoder input bit stream.

Returns:
TRUE if valid MP3 sync is found, otherwise FALSE.

Definition at line 37 of file DECODER__mp3first.c.

References Audio, st_DECODER::averageWordRate, st_DECODER::decodeBitstrm, Decoder, DECODER__mp3(), st_AUDIO::duration, st_AUDIO::file, st_DECODER::firstPacketOffset, st_DECODER::flag, st_AUDIO::fptr, st_AUDIO::offset, st_PCM::sampleRate, File::size, and st_DECODER::status.

00038 {
00039     USHORT    strmLen;
00040     //USHORT *  pDst;
00041     
00042     /* Locate first available frame sync. */
00043     //while(1)
00044     {       
00045         /* This will cause potential reentry problem in media task!     
00046         BITSTRM_pack(Decoder.inputBitstrm);
00047         strmLen = BITSTRM_numWordsFree(Decoder.inputBitstrm);       
00048         pDst = (unsigned short *)BITSTRM_writePtr(Decoder.inputBitstrm);
00049         strmLen = DECODER_getData((int*)pDst, strmLen);
00050         
00051         // Is data available?
00052         if(strmLen == 0) break;
00053         
00054         // Add to decoder bitstream object.
00055         BITSTRM_add(Decoder.inputBitstrm, strmLen);  
00056         */
00057         
00058         BITSTRM_pack(Decoder.decodeBitstrm);
00059         strmLen = BITSTRM_numDataWords(Decoder.decodeBitstrm); 
00060         if(strmLen > 32)
00061         {
00062             if( DECODER__mp3findSync(&Decoder, 0) == 0 ) 
00063             {
00064                 PCM_samplerateChanged();
00065                 Pcm.sampleRate = Decoder.status.sampleRate;
00066                 // Initialize status frameSize, which will then be used
00067                 // in DECODER__mp3 to determine if enough data is
00068                 // available in input bitstream.
00069                 Decoder.status.frameSize = MAX_INPUT_FRAME_SIZE;
00070                 mp3FastFwdLen = 5L*Decoder.status.bitRate>>4;
00071                 
00072                 BITSTRM_pack(Decoder.decodeBitstrm); 
00073                 strmLen = BITSTRM_numDataWords(Decoder.decodeBitstrm); 
00074                 Decoder.firstPacketOffset = Audio.fptr - strmLen;
00075                 
00076                 Decoder.averageWordRate = 
00077                     (Audio.file.size-Decoder.firstPacketOffset)/(Audio.duration+1);
00078                 if(0 == Decoder.averageWordRate) 
00079                     Decoder.averageWordRate = Decoder.status.bitRate>>4;
00080                 
00081                 if(Audio.offset)
00082                 {
00083                     Decoder.flag |= DEC_FFWD|DEC_MEDIASEEK;
00084                     DECODER__mp3();
00085                 }
00086                 return TRUE;
00087             }
00088         }
00089     }   
00090     // Return FALSE if sync is not found, coder will keep calling this routine
00091     // until sync is found or media has been gone through completely.
00092     return FALSE;
00093 }

Here is the call graph for this function:

USHORT DECODER__mp3media void   ) 
 

Function serves as the decoder media access task handle.

Returns:
Data length in words that are added into bitstream.

Definition at line 38 of file DECODER__mp3media.c.

References Audio, Decoder, DECODER_getData(), st_AUDIO::fptr, and st_DECODER::inputBitstrm.

00039 {
00040     USHORT *        pDst;
00041     USHORT          strmLen;
00042     USHORT          dataLen = 0;
00043     
00044     BITSTRM_pack(Decoder.inputBitstrm);
00045     strmLen = BITSTRM_numWordsFree(Decoder.inputBitstrm); 
00046     
00047     if( (strmLen > READ_THRESHOLD) )
00048     {
00049         Audio.fptr = mp3EndOfReadPtr;
00050         pDst = (unsigned short *)BITSTRM_writePtr(Decoder.inputBitstrm);
00051         dataLen = DECODER_getData((int*)pDst, Audio.fptr, strmLen);
00052         Audio.fptr += dataLen;
00053         mp3EndOfReadPtr = Audio.fptr;
00054         /* Add to decoder bitstream object. */
00055         BITSTRM_add(Decoder.inputBitstrm, dataLen);  
00056     }   
00057     return dataLen; 
00058 }

Here is the call graph for this function:

BOOL DECODER__ogg void   ) 
 

Function serves as the OGG decoder task handle.

Returns:
OGG is responsible to post media task as needed.

Definition at line 38 of file DECODER__ogg.c.

References Decoder.

Referenced by DECODER__oggfirst().

00039 {
00040     OGGV_decode(&Decoder);
00041     return TRUE;
00042 }

BOOL DECODER__oggfirst void   ) 
 

Function check to set up OGG decoder input bit stream.

Returns:
TRUE if valid OGG stream is found, otherwise FALSE.

Definition at line 38 of file DECODER__oggfirst.c.

References Audio, Decoder, DECODER__ogg(), st_DECODER::flag, st_AUDIO::offset, st_PCM::sampleRate, and st_DECODER::status.

00039 {
00040     OGGV_first(&Decoder);
00041     DECODER__ogg();
00042     if(Decoder.status.isValid)  
00043     {
00044         PCM_samplerateChanged();
00045         Pcm.sampleRate = Decoder.status.sampleRate;
00046         // Reset bookmark.
00047         if(Audio.offset)
00048         {
00049             Decoder.flag |= DEC_FFWD|DEC_MEDIASEEK;
00050         }
00051         return TRUE;
00052     }   
00053     return FALSE;
00054 }

Here is the call graph for this function:

USHORT DECODER__oggmedia void   ) 
 

Function serves as the OGG decoder media access task handle.

Returns:
Always return 0OGG is responsible to post coder task as needed.

Definition at line 78 of file DECODER__oggmedia.c.

References Decoder.

00079 {
00080     OGGV_demux(&Decoder);
00081     return 0;
00082 }

BOOL DECODER__wav void   ) 
 

Function serves as the wav decoder task handle.

Returns:
FALSE if more data is needed, otherwise TRUE;

Definition at line 50 of file DECODER__wav.c.

References Audio, st_DECODER::decodeBitstrm, Decoder, DECODER__wavdecode(), st_DECODER::firstPacketOffset, st_DECODER::flag, GEN_zeroOut(), st_AUDIO::offset, st_DECODER::pipe, PIPE_writeNext(), st_AUDIO::playtime, SAUDIOTIME_UPDT, and st_DECODER::status.

Referenced by DECODER__wavfirst().

00051 {
00052     unsigned long   tmpUL;
00053     PIPE_Obj *      pipe = &Decoder.pipe;
00054     int             error = DECODE_NO_ERROR;
00055     int             dataLength;
00056     BOOL            ret = TRUE;
00057     
00058     // Try to decode as long as output pipe is open.
00059     while( PIPE_writeFrameNum(pipe) ) 
00060     {   
00061         BITSTRM_pack(Decoder.decodeBitstrm); 
00062         dataLength = BITSTRM_numDataWords(Decoder.decodeBitstrm);               
00063     
00064         // YES. valid data detected, prepare to decode.         
00065         if ( Decoder.flag & (DEC_FFWD|DEC_FRWD|DEC_MEDIASEEK) )
00066         {
00067             BITSTRM_remove(Decoder.decodeBitstrm, dataLength);          
00068             if(Decoder.flag & DEC_MEDIASEEK) 
00069             {
00070                 wvEndOfReadPtr = Audio.offset;
00071                 Decoder.flag &= ~DEC_MEDIASEEK;
00072             }
00073             else
00074             {
00075                 if(Decoder.flag & DEC_FFWD) wvEndOfReadPtr += wvFastFwdLen;
00076                 else if(wvEndOfReadPtr>wvFastFwdLen+Decoder.firstPacketOffset)
00077                     wvEndOfReadPtr -= wvFastFwdLen;
00078                 else
00079                 {   
00080                     // Send silence to get rid of the noise.
00081                     wvSilence = 6L*Decoder.status.bitRate/8000L;
00082                     wvEndOfReadPtr = Decoder.firstPacketOffset;             
00083                 }
00084             }           
00085             wvReadPtr = wvEndOfReadPtr;         
00086             Decoder.flag &= ~(DEC_FFWD|DEC_FRWD);
00087             ret = FALSE;
00088             break;
00089         }
00090         else
00091         {       
00092             if(wvSilence)
00093             {
00094                 GEN_zeroOut((UINT16*)pipe->WrFrame.Frame, WAV_PIPE_FRAMELEN);
00095                 wvSilence--;
00096             }
00097             else
00098             {
00099                 // is there enough data to be decoded?
00100                 if( dataLength < WAV_INPUT_BUFFER_SIZE - READ_THRESHOLD_WAV ) ret = FALSE;
00101                 
00102                 if( dataLength < (Decoder.status.frameSize) )
00103                 {    
00104                     // NO. data not enough yet, bring up media task. 
00105                     return ret;         
00106                 }
00107                 
00108                 // decode the bitstream 
00109                 error = DECODER__wavdecode(Decoder.decodeBitstrm, (Int *)pipe->WrFrame.Frame);
00110             }
00111             
00112             // no error, output the data, prepare for the next write as well. 
00113             if (error == DECODE_NO_ERROR) PIPE_writeNext(pipe);
00114         }
00115     }   
00116     
00117     BITSTRM_pack(Decoder.decodeBitstrm); 
00118     // Check to update time.
00119     tmpUL = 0;
00120     if(wvReadPtr > Decoder.firstPacketOffset)       
00121         tmpUL = (wvReadPtr-Decoder.firstPacketOffset)/wvAverageWordRate;
00122     if ( Audio.playtime != tmpUL )
00123     {
00124         Audio.playtime = tmpUL;
00125         mMSG_send(sysMsgQ, SYS_MSG_ID, SAUDIOTIME_UPDT, DONTCARE, 0);
00126     }       
00127     
00128     return ret; 
00129 }   

Here is the call graph for this function:

BOOL DECODER__wavfirst void   ) 
 

Function check to set up WAV decoder input bit stream.

Returns:
TRUE if valid WAV header is found, otherwise FALSE.

Definition at line 46 of file DECODER__wavfirst.c.

References Audio, st_DECODER::decodeBitstrm, Decoder, DECODER__wav(), DECODER__wavReadHeader(), st_DECODER::flag, st_AUDIO::offset, st_PCM::sampleRate, and st_DECODER::status.

00047 {
00048     USHORT    strmLen;
00049     //USHORT *  pDst;
00050     
00051     // Check WAV header. */
00052     BITSTRM_pack(Decoder.decodeBitstrm);
00053     strmLen = BITSTRM_numDataWords(Decoder.decodeBitstrm); 
00054     if(strmLen > sizeof(st_WAVHEADER))
00055     {
00056         if( TRUE == DECODER__wavReadHeader(&Decoder) ) 
00057         {
00058             PCM_samplerateChanged();
00059             Pcm.sampleRate = Decoder.status.sampleRate;
00060             // Reset bookmark.
00061             if(Audio.offset) 
00062             {
00063                 Decoder.flag |= DEC_FFWD|DEC_MEDIASEEK;
00064                 DECODER__wav();
00065             }
00066             BITSTRM_pack(Decoder.decodeBitstrm); 
00067             return TRUE;
00068         }
00069     }   
00070     // Return FALSE if header is invalid, coder will keep calling this routine
00071     // until valid header is found or media has been gone through completely.
00072     return FALSE;
00073 }

Here is the call graph for this function:

USHORT DECODER__wavmedia void   ) 
 

Function serves as the WAV decoder media access task handle.

Returns:
Data length in words that are added into bitstream.

Definition at line 41 of file DECODER__wavmedia.c.

References Audio, Decoder, DECODER_getData(), st_AUDIO::fptr, and st_DECODER::inputBitstrm.

00042 {
00043     USHORT *        pDst;
00044     USHORT          strmLen;
00045     USHORT          dataLen = 0;
00046     
00047     BITSTRM_pack(Decoder.inputBitstrm);
00048     strmLen = BITSTRM_numWordsFree(Decoder.inputBitstrm); 
00049     
00050     if( (strmLen > READ_THRESHOLD_WAV) )
00051     {
00052         Audio.fptr = wvEndOfReadPtr;
00053         pDst = (unsigned short *)BITSTRM_writePtr(Decoder.inputBitstrm);
00054         dataLen = DECODER_getData((int*)pDst, Audio.fptr, strmLen);
00055         Audio.fptr += dataLen;
00056         wvEndOfReadPtr = Audio.fptr;
00057         
00058         /* Add to decoder bitstream object. */
00059         BITSTRM_add(Decoder.inputBitstrm, dataLen);  
00060     }   
00061     return dataLen; 
00062 
00063 }

Here is the call graph for this function:

BOOL DECODER__wma void   ) 
 

Function serves as the WMA decoder data output task handle.

Returns:
FALSE if more data is needed, otherwise TRUE; NOTE: this data ouput task always returns TRUE.

Definition at line 61 of file DECODER__wma.c.

References Audio, st_DECODER::averageWordRate, st_DECODER::decode, st_DECODER::decodeBitstrm, Decoder, st_DECODER::decrypt, st_DECODER::firstPacketOffset, st_DECODER::flag, st_DECODER::inputBitstrm, st_DECODER::pipe, PIPE_writeNext(), st_AUDIO::playtime, SAUDIOTIME_UPDT, and st_DECODER::status.

00062 {
00063     PIPE_Obj *      pipe = &Decoder.pipe;
00064     int             error = DECODE_NO_ERROR;
00065     ULONG           tmpUL;
00066     
00067     // Try to decode as long as output pipe is open.
00068     while( PIPE_writeFrameNum(pipe) ) 
00069     {       
00070         if ( Decoder.flag & (DEC_FFWD|DEC_FRWD) )
00071         {
00072             if(0== SEM_count(SEM_subcoder)) SEM_post(SEM_subcoder);
00073         }
00074 
00075         error = DECODE_decode(  Decoder.decode, 
00076                                 Decoder.decodeBitstrm, 
00077                                 (Int *)pipe->WrFrame.Frame );
00078         DECODE_getStatus(Decoder.decode, &Decoder.status);
00079         
00080         if (error == DECODE_NO_ERROR)
00081         {
00082             // no error, so output the data, prepare for the next write as well. 
00083             PIPE_writeNext(pipe);
00084             
00085             //if ( Decoder.status.bitRate ) 
00086             if(Decoder.averageWordRate)
00087             {
00088                 // (wordsize*2)/(bitrate/8)
00089                 //tmpUL = (wmadecode.startOfDataFileAdr-FIRST_PACKET_OFFSET)
00090                 //          /(Decoder.status.bitRate>>4); 
00091                 tmpUL = 0;
00092                 if(wmadecode.startOfDataFileAdr > Decoder.firstPacketOffset)
00093                     tmpUL = (wmadecode.startOfDataFileAdr-Decoder.firstPacketOffset)/
00094                             Decoder.averageWordRate;
00095                 if ( Audio.playtime != tmpUL )
00096                 {
00097                     Audio.playtime = tmpUL;
00098                     mMSG_send(sysMsgQ, SYS_MSG_ID, SAUDIOTIME_UPDT, DONTCARE, 0);
00099                 }
00100             }
00101             
00102         }
00103         else if(error == DECODE_ERROR)  
00104         {
00105             // Error, resync on the next call. Note that the output 
00106             // pipe frame is kept for next decoding attempt. 
00107             SCRYPT_reset(Decoder.decrypt);
00108             DECODE_reset(Decoder.decode);                   
00109             BITSTRM_reset(Decoder.inputBitstrm); 
00110         }
00111         else if(error == DECODE_NO_DATA)
00112         {
00113             if(0 == SEM_count(SEM_subcoder)) SEM_post(SEM_subcoder);
00114             break;
00115         }
00116     }   
00117     
00118     return TRUE;    
00119 }

Here is the call graph for this function:

BOOL DECODER__wmafirst void   ) 
 

Function bridges the WMA subcoder to main decoder handle.

Returns:
TRUE if subcoder has been inited, otherwise FALSE.

Definition at line 90 of file DECODER__wmafirst.c.

References st_CODER::subcoderInit.

00091 {
00092     if(Coder.subcoderInit)  return FALSE;
00093     else                    return TRUE;
00094 }

BOOL DECODER__wmainit void   ) 
 

Function check to init WMA decoder input bit stream.

Returns:
TRUE if valid WMA stream header is found, otherwise FALSE.

Definition at line 41 of file DECODER__wmafirst.c.

References Audio, st_DECODER::averageWordRate, st_DECODER::decode, st_DECODER::decodeBitstrm, Decoder, DECODER__wmatask(), st_AUDIO::duration, st_AUDIO::file, st_DECODER::firstPacketOffset, st_DECODER::flag, st_AUDIO::offset, st_PCM::sampleRate, File::size, and st_DECODER::status.

00042 {
00043     USHORT    strmLen;
00044     
00045     BITSTRM_pack(Decoder.decodeBitstrm);
00046     strmLen = BITSTRM_numDataWords(Decoder.decodeBitstrm); 
00047     if(strmLen > WMA_MAX_INPUT_FRAME_SIZE)
00048     {
00049         // Decode to validate audio data and return status.
00050         WMA_task();
00051         DECODE_getStatus(Decoder.decode, &Decoder.status);
00052         BITSTRM_pack(Decoder.decodeBitstrm); 
00053         
00054         if(Decoder.status.isValid)
00055         {
00056             PCM_samplerateChanged();
00057             Pcm.sampleRate = Decoder.status.sampleRate;
00058             
00059             Decoder.averageWordRate = 
00060                 (Audio.file.size-FIRST_PACKET_OFFSET)/(Audio.duration+1);
00061             if(0 == Decoder.averageWordRate) 
00062                 Decoder.averageWordRate = Decoder.status.bitRate>>4;
00063             
00064             // Aligned on packet length boundary.
00065             wmaFastFwdLen  = 5L*(Decoder.status.bitRate>>4);
00066             wmaFastFwdLen /= Decoder.status.frameSize;
00067             wmaFastFwdLen *= Decoder.status.frameSize;
00068             Decoder.firstPacketOffset = FIRST_PACKET_OFFSET;
00069             
00070             // Seek to start offset.
00071             if(Audio.offset)
00072             { 
00073                 Decoder.flag |= DEC_FFWD|DEC_MEDIASEEK;
00074                 DECODER__wmatask();
00075             }
00076         
00077             return TRUE;
00078         }
00079     }
00080     return FALSE;
00081 }

Here is the call graph for this function:

USHORT DECODER__wmamedia void   ) 
 

Function serves as the WMA decoder media access task handle.

Returns:
Data length in words that are added into bitstream.

Definition at line 41 of file DECODER__wmamedia.c.

References Audio, Decoder, DECODER_getData(), st_AUDIO::fptr, and st_DECODER::inputBitstrm.

00042 {
00043     USHORT *        pDst;
00044     USHORT          strmLen;
00045     USHORT          dataLen = 0;
00046     
00047     BITSTRM_pack(Decoder.inputBitstrm);
00048     strmLen = BITSTRM_numWordsFree(Decoder.inputBitstrm); 
00049     
00050     if( (strmLen > READ_THRESHOLD_WMA) )
00051     {
00052         // Fetch start offset.
00053         Audio.fptr = wmadecode.endOfDataFileAdr;
00054         
00055         pDst = (unsigned short *)BITSTRM_writePtr(Decoder.inputBitstrm);
00056         dataLen = DECODER_getData((int*)pDst, Audio.fptr, strmLen);
00057         Audio.fptr += dataLen;
00058         /* Add to decoder bitstream object. */
00059         BITSTRM_add(Decoder.inputBitstrm, dataLen);  
00060     }   
00061     
00062     if(SEM_count(SEM_subcoder) == 0) SEM_post(SEM_subcoder);
00063     
00064     return dataLen; 
00065 }

Here is the call graph for this function:

BOOL DECODER__wmatask void   ) 
 

Function serves as the WMA decoder task handle.

Returns:
FALSE if more data is needed, otherwise TRUE;

Definition at line 129 of file DECODER__wma.c.

References Audio, st_DECODER::decodeBitstrm, Decoder, st_DECODER::flag, and st_AUDIO::offset.

Referenced by DECODER__wmainit().

00130 {
00131     // Try to decode as long as output buffer is available.
00132     while( sramPP_isWritable( &SRAMPP ) ) 
00133     {   
00134         BITSTRM_pack(Decoder.decodeBitstrm); 
00135         if ( Decoder.flag & (DEC_FFWD|DEC_MEDIASEEK) )
00136         {
00137             seekMode = 1;
00138             if(Decoder.flag & DEC_MEDIASEEK)
00139             {
00140                 g_ErrorRetryPos = Audio.offset<<1;
00141                 Decoder.flag &= ~DEC_MEDIASEEK;
00142             }
00143             else g_ErrorRetryPos += wmaFastFwdLen;
00144             Decoder.flag &= ~DEC_FFWD;
00145         }
00146         else if ( Decoder.flag & DEC_FRWD )
00147         {
00148             seekMode = -1;
00149             g_ErrorRetryPos -= wmaFastFwdLen;
00150             Decoder.flag &= ~DEC_FRWD;
00151         }
00152         WMA_task(); 
00153     }
00154     BITSTRM_pack(Decoder.decodeBitstrm); 
00155     return TRUE;
00156     
00157 }     

void DECODER_cache void   ) 
 

Function serves as the decoder cache task handle.

This task feeds the cache.

Definition at line 156 of file DECODER_getData.c.

References st_CACHE::actvFileSize, st_CACHE::actvStartClus, Audio, st_AUDIO::cachefile, DECODER_cacheDepthReset(), st_CACHE::done, st_CACHE::endSec, FAT_fread(), FAT_fseek(), st_AUDIO::file, st_CODER::flag, NAND_writeSec(), st_CACHE::next, st_CACHE::prev, SCURRENTAUDIOFILE, st_CACHE::secNum, st_CACHE::secOffset, SEEK_HEAD, File::size, SNEXTAUDIOFILE, File::startClus, and st_CACHE::startSec.

00157 {
00158     unsigned short  len;
00159     st_CACHE *      c;
00160     unsigned short  buf[256];   
00161 
00162     if( F_CODER_CACHESETIDLE & Coder.flag )
00163     {
00164         SEM_post(SEM_cacheIdle);
00165         return;
00166     }
00167     
00168     // On entry, check the lower threshold.
00169     if( (!(F_CODER_CACHESHUTDOWN & Coder.flag)) &&
00170         (cacheDepth > cacheLowerThreshold) )
00171     {
00172         CACHE_RETURN();
00173     }
00174         
00175     while(1)
00176     {
00177         if( F_CODER_CACHESHUTDOWN & Coder.flag ) 
00178         {
00179             _cacheShutdown(buf);
00180             SEM_post(SEM_cacheIdle);
00181             CACHE_RETURN();
00182         }
00183         if( F_CODER_CACHESETIDLE & Coder.flag )
00184         {
00185             SEM_post(SEM_cacheIdle);
00186         }
00187         
00188         // Every time cache gets posted, check will be done 
00189         // in the following order,
00190         // 1) Is current audio file in cache queue and has it been fully cached?
00191         // 2) Is it necessary to update cache to read in more new data?
00192 
00193         // File in cache and fully cached, check to read in more.
00194         if( (rdCache->actvStartClus == Audio.file.startClus)&&
00195             (rdCache->actvFileSize == Audio.file.size)&&
00196             (rdCache->done == TRUE) )
00197         {
00198             if(wrCache->done == TRUE)
00199             {
00200                 // Try next file.
00201                 mMSG_send(uiParentMsgQ, SYS_MSG_ID, SNEXTAUDIOFILE, 1, SYS_FOREVER);
00202                     
00203                 // Get a copy of cachefile handle.
00204                 //TSK_disable();
00205                 cachefile = Audio.cachefile;
00206                 //TSK_enable();
00207                 c = _cachePosition(&cachefile);
00208                 
00209                 //if( (c->done == TRUE)&&(c == cacheHead) ) 
00210                 //{
00211                     // Already cached all tracks.
00212                     //msgOUT.id = SYS_MSG_ID;
00213                     //msgOUT.d1 = SCURRENTAUDIOFILE;
00214                     //mMSG_send(uiParentMsgQ, &msgOUT, SYS_FOREVER);
00215                     //CACHE_RETURN();
00216                 //}
00217                 //else 
00218                 
00219                 if( (c->actvStartClus == cachefile.startClus)&&
00220                     (c->actvFileSize  == cachefile.size)&&
00221                     (c->done == TRUE) ) 
00222                 {
00223                     cacheDepth += c->secNum;
00224                     
00225                     if(c->actvStartClus != wrCache->actvStartClus)
00226                     {
00227                         wrCacheSec += c->secNum;
00228                         if(wrCacheSec > SYS_cacheEndSec()) wrCacheSec -= SYS_cacheSecNum();
00229                     }
00230                     CACHE_RETURN();
00231                     //continue;
00232                 }
00233                 else
00234                 {
00235                     FAT_fseek(&cachefile, 0, SEEK_HEAD);
00236                     //TSK_disable();
00237                     cacheTail = c->next;
00238                     cacheTail->actvStartClus = 0;
00239                     cacheTail->done = FALSE;
00240                 
00241                     if(cacheTail == cacheHead) 
00242                         cacheHead = cacheHead->next;
00243 
00244                     wrCache           = c;
00245                     wrCacheSec        =
00246                     wrCache->startSec =
00247                     wrCache->endSec   = c->prev->endSec;
00248                     wrCache->secNum   = 0;
00249                     wrCache->secOffset= 0;
00250                         
00251                     wrCache->actvStartClus = cachefile.startClus;
00252                     wrCache->actvFileSize  = cachefile.size;
00253                     wrCache->done     = FALSE;                              
00254                     //TSK_enable();
00255                 }                   
00256             }
00257         }
00258         else 
00259         {
00260             if( (wrCache->actvStartClus != Audio.file.startClus)||
00261                 (wrCache->actvFileSize  != Audio.file.size)||
00262                 (wrCache != rdCache))
00263             {
00264                 ULONG secOffset = 0;
00265                 
00266                 mMSG_send(uiParentMsgQ, SYS_MSG_ID, SCURRENTAUDIOFILE, DONTCARE, SYS_FOREVER);
00267                 
00268                 //TSK_disable();
00269                 cachefile = Audio.file;
00270                 
00271                 //TSK_enable();
00272                 if(prevOffset > 0x40000)
00273                 {
00274                     secOffset = prevOffset/256;
00275                     FAT_fseek(&cachefile, secOffset*256, SEEK_HEAD);
00276                 }
00277                 else FAT_fseek(&cachefile, 0, SEEK_HEAD);
00278                 
00279                 //TSK_disable();            
00280                 if(wrCache->done == TRUE) 
00281                 {
00282                     wrCacheSec = wrCache->endSec;
00283                     wrCache = wrCache->next;
00284                     wrCache->startSec = wrCacheSec;
00285                 }
00286                 else wrCacheSec = wrCache->startSec;
00287 
00288                 cacheTail = wrCache->next;
00289                 cacheTail->actvStartClus = 0;
00290                 cacheTail->done = FALSE;
00291                 if(cacheTail == cacheHead) 
00292                     cacheHead = cacheHead->next;
00293                 
00294                 wrCache->actvStartClus = cachefile.startClus;
00295                 wrCache->actvFileSize  = cachefile.size;
00296                         
00297                 wrCache->endSec   = wrCacheSec ;
00298                 wrCache->secNum   = 0;
00299                 wrCache->done     = FALSE;
00300                 wrCache->secOffset= secOffset;
00301                 
00302                 rdCache    = wrCache;
00303                 cacheDepth = 0;
00304                 //TSK_enable();
00305             }
00306         }
00307         
00308         // Check cache depth.
00309         if(cacheDepth > cacheUpperThreshold) 
00310         {
00311             DECODER_cacheDepthReset(2);
00312             mMSG_send(uiParentMsgQ, SYS_MSG_ID, SNEXTAUDIOFILE, 0, SYS_FOREVER);
00313             CACHE_RETURN();
00314         }
00315         
00316         if(SYS_nextCacheSec(wrCache->endSec) == cacheHead->startSec)
00317         {
00318             //TSK_disable();
00319             if( (cacheHead != wrCache) )
00320             {
00321                 if(cacheHead != rdCache)  cacheHead = cacheHead->next;
00322                 else CACHE_RETURN();
00323             }
00324             else 
00325             {
00326                 // Cache is full.
00327                 cacheHead->secOffset++;
00328                 cacheHead->secNum--;
00329                 cacheHead->startSec = SYS_nextCacheSec(cacheHead->startSec);
00330             }
00331             //TSK_enable();         
00332         }
00333         
00334         len = FAT_fread(&cachefile, buf, 256);
00335         NAND_writeSec(wrCacheSec, buf, FALSE);
00336         cacheDepth++;
00337         wrCacheSec = SYS_nextCacheSec(wrCacheSec);
00338         wrCache->endSec = wrCacheSec;
00339         wrCache->secNum++;
00340         if(len<256) wrCache->done = TRUE;
00341         
00342         SYS_swWdtReset();
00343     }
00344 }           

Here is the call graph for this function:

void DECODER_cacheDepthReset unsigned short  mode  ) 
 

Function resets cache depth controls.

This function also resets cache check state to verify if file exists in cache.

Parameters:
mode Cache depth control mode. 0: reset to default. 1: Double current. 2: Increment.

Definition at line 406 of file DECODER_getData.c.

Referenced by DECODER_cache(), DECODER_cacheInit(), and UI_PSF_play().

00407 {
00408     TSK_disable();
00409     inCacheState = INCACHE_CHECK;
00410     if(0 == mode)
00411     {
00412         cacheUpperThreshold = 0x1000;
00413         cacheLowerThreshold = 0x800;
00414     }
00415     else 
00416     {
00417         if(1 == mode) // Double upper threshold.
00418         {
00419             cacheUpperThreshold <<= 1;
00420         }
00421         else // Increment upper threshold.
00422         {
00423             cacheUpperThreshold += 0x1000;
00424         }
00425         
00426         if(cacheUpperThreshold >= SYS_cacheSecNum() )
00427         {
00428             // Aligned to NAND page boundary.
00429             cacheUpperThreshold = SYS_cacheSecNum() - 62;
00430         }
00431     }
00432     TSK_enable();
00433 }

BOOL DECODER_config DEC_TYPE  eType  ) 
 

Function configures the decoder module.

Parameters:
eType Decoder type.

Definition at line 97 of file DECODER_config.c.

References st_CODER::cache, st_CODER::cacheInit, Decoder, st_DECODER::flag, st_CODER::mediaInit, st_DECODER::pipe, PIPE_reset(), st_CODER::subcoder, SYS_die(), and st_DECODER::type.

Referenced by AUDIO_config().

00098 {
00099     Decoder.type = eType;
00100     
00101     Coder.subcoder  = DECODER__nullsubcoder;
00102     Coder.cache     = DECODER_cache;
00103     Coder.cacheInit = DECODER_cacheInit;
00104     Coder.mediaInit = NULL;
00105     
00106     _decPipeBuf = (int*)malloc(_DEC_PIPE_BUF_LEN);
00107     if(NULL == _decPipeBuf) SYS_die(SYS_DECODER_CONFIG);
00108     
00109     switch(eType)
00110     {
00111         #ifdef WAV_SUPPORT
00112         case DECWAV:    _wavConfig();       break;
00113         #endif // WAV_SUPPORT
00114         case DECMP3:    _mp3Config();       break;
00115         #ifdef WMA_SUPPORT
00116         case DECWMA:    _wmaConfig();       break;
00117         #endif // WMA_SUPPORT
00118         #ifdef OGG_SUPPORT
00119         case DECOGG:    _oggConfig();       break;          
00120         #endif //OGG_SUPPORT
00121     }
00122    
00123     /* Reset the decoder pipe. */
00124     PIPE_reset(&Decoder.pipe);
00125    
00126     /* Clear decoder file flag. */
00127     Decoder.flag = 0;
00128     
00129     return TRUE;
00130 }

Here is the call graph for this function:

unsigned short DECODER_getData int *  pD,
unsigned long  offset,
unsigned short  reqLen
 

Function feeds data into docoder bit stream/buffer.

A NAND cache is managed here if HDD is present.

Parameters:
pD Decoder input data pointer.
offset Requested data offset in media file.
reqLen Requested data length in words.
Returns:
Available data length in words.

Definition at line 132 of file DECODER_getData.c.

References Audio, FAT_fread(), FAT_fseek(), st_AUDIO::file, File::ptr, and SEEK_MID.

Referenced by DECODER__mp3media(), DECODER__oggRead(), DECODER__wavmedia(), and DECODER__wmamedia().

00133 {
00134     unsigned short  len;
00135     File *          fp = &Audio.file;
00136     if(FALSE == _isCacheHit(fp, offset, &reqLen))
00137     {
00138         if(offset != fp->ptr) FAT_fseek(fp, (long)(offset-fp->ptr), SEEK_MID);
00139         len = FAT_fread(fp, (unsigned short*)pD, reqLen);
00140     }
00141     else
00142     {
00143         len = _cacheRead(offset, (unsigned short*)pD, reqLen);
00144     }
00145     
00146     if(len == 0) DECODER_stop();
00147     
00148     return len;
00149 }

Here is the call graph for this function:

int* DECODER_main void   ) 
 

Function fetches decoder output upon PCM request.

All decoders share this same pipe interface although they might use different sized pipes.

Returns:
Readable pipe frame if data is available, otherwise NULL.

Definition at line 45 of file DECODER_main.c.

References AI_STOP, Decoder, st_DECODER::flag, st_CODER::flag, st_DECODER::pipe, PIPE_readNext(), SAUDIOCTL, SEM_coder, and SENDOFMUSIC.

Referenced by AUDIO_start().

00046 {
00047     PIPE_Obj *  pipe = &Decoder.pipe;
00048     
00049     if(Decoder.flag & DEC_PIPE_READNEXT_PENDING)
00050     {
00051         PIPE_readNext(pipe);
00052         Decoder.flag &= ~DEC_PIPE_READNEXT_PENDING;
00053         
00054         if(SEM_count(SEM_coder) == 0) SEM_post(SEM_coder);
00055     }
00056     
00057     if( PIPE_readFrameNum(pipe) )
00058     {
00059         Decoder.flag |= DEC_PIPE_READNEXT_PENDING;
00060         return pipe->RdFrame.Frame;
00061     }
00062     else if(Coder.flag & F_CODER_DEC_EOF)
00063     {
00064         if(!(Coder.flag&F_CODER_DEC_EOF_POSTED))
00065         {
00066             Coder.flag |= F_CODER_DEC_EOF_POSTED;
00067             mMSG_send(sysMsgQ, SYS_MSG_ID, SAUDIOCTL, AI_STOP, SYS_FOREVER);
00068             mMSG_send(uiChildMsgQ, SYS_MSG_ID, SENDOFMUSIC, DONTCARE, SYS_FOREVER);
00069         }
00070         return NULL;
00071     }
00072     
00073     if(SEM_count(SEM_coder) == 0) SEM_post(SEM_coder);
00074     return NULL;    
00075 }

Here is the call graph for this function:


Variable Documentation

st_DECODER Decoder
 

Decoder globals.

Note that this global will be used by PCM SWIs, it has to be resident all the time.

Definition at line 49 of file DECODER_config.c.

Referenced by AUDIO_setFilePtr(), DECODER__mp3(), DECODER__mp3first(), DECODER__mp3media(), DECODER__ogg(), DECODER__oggfirst(), DECODER__oggmedia(), DECODER__wav(), DECODER__wavdecode(), DECODER__wavfirst(), DECODER__wavmedia(), DECODER__wavReadHeader(), DECODER__wma(), DECODER__wmainit(), DECODER__wmamedia(), DECODER__wmatask(), DECODER_config(), and DECODER_main().


Generated on Wed Jan 19 01:12:53 2005 for neuros-firmware by  doxygen 1.3.9.1