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:

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

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 serves as the mp3 decoder task handle.
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:

|
|
Function check to set up mp3 decoder input bit stream.
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:

|
|
Function serves as the decoder media access task handle.
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:

|
|
Function serves as the OGG decoder task handle.
Definition at line 38 of file DECODER__ogg.c. References Decoder. Referenced by DECODER__oggfirst(). 00039 {
00040 OGGV_decode(&Decoder);
00041 return TRUE;
00042 }
|
|
|
Function check to set up OGG decoder input bit stream.
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:

|
|
Function serves as the OGG decoder media access task handle.
Definition at line 78 of file DECODER__oggmedia.c. References Decoder. 00079 {
00080 OGGV_demux(&Decoder);
00081 return 0;
00082 }
|
|
|
Function serves as the wav decoder task handle.
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:

|
|
Function check to set up WAV decoder input bit stream.
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:

|
|
Function serves as the WAV decoder media access task handle.
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:

|
|
Function serves as the WMA decoder data output task handle.
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:

|
|
Function bridges the WMA subcoder to main decoder handle.
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 }
|
|
|
Function check to init WMA decoder input bit stream.
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:

|
|
Function serves as the WMA decoder media access task handle.
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:

|
|
Function serves as the WMA decoder task handle.
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 }
|
|
|
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:

|
|
Function resets cache depth controls. This function also resets cache check state to verify if file exists in cache.
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 }
|
|
|
Function configures the decoder module.
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:

|
||||||||||||||||
|
Function feeds data into docoder bit stream/buffer. A NAND cache is managed here if HDD is present.
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:

|
|
Function fetches decoder output upon PCM request. All decoders share this same pipe interface although they might use different sized pipes.
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:

|
|
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(). |
1.3.9.1