ENCODER__wav.c File Reference


Detailed Description

This module manages the WAV encoder.

REVISION

Definition in file ENCODER__wav.c.

#include "../SYSTEM/sys_hardware.h"
#include "../SYSTEM/sys_main.h"
#include "../SYSTEM/sys_assert.h"
#include "../codec/codec.h"
#include "../coder/coder.h"
#include "../UI/ui.h"
#include "encoder.h"

Include dependency graph for ENCODER__wav.c:

Include dependency graph

Go to the source code of this file.

Functions

BOOL ENCODER__wav (void)
 Function serves as the WAV encoder task handle.
int ENCODER__createWaveHeader (USHORT *hdr)
 Function create wave file header and get parameters from RecordQualty.
int ENCODER__wavEncode (int *in, int *out, int len, int chNum)
 Function serves as the WAV encoder task handle.

Variables

EncoderInputBitstream eib
 encoder input bitstream data object.
EncoderOutputBitstream eob
 encoder output bitstream data object.


Function Documentation

int ENCODER__createWaveHeader USHORT *  hdr  ) 
 

Function create wave file header and get parameters from RecordQualty.

Parameters:
hdr header pointer.
Returns:
zero if header successfully created, otherwise -1.

Definition at line 238 of file ENCODER__wav.c.

References ENCODER_getSource(), ES_SOURCE, st_SYSPARAM::recQuality, and WAV_RECQUALITY_INDEX.

00239 {   
00240     ES_SOURCE es = ENCODER_getSource();
00241     
00242     hdr[0] = 0x5249;    //"RI"
00243     hdr[1] = 0x4646;    //"FF"
00244     
00245     hdr[2] = hdr[3] = 0;//ChunkSize, will be written before file closed.
00246     
00247     hdr[4] = 0x5741;    //"WA"
00248     hdr[5] = 0x5645;    //"VE"
00249     
00250     hdr[6] = 0x666d;    //"fm"
00251     hdr[7] = 0x7420;    //"t "
00252     
00253     hdr[8] = 0x1000;    //Subchunk1Size = 16
00254     hdr[9] = 0;
00255     
00256     hdr[10] = 0x0100;   //AudioFormat = 1 (PCM)
00257     
00258     // Mono mode only in Microphone record. 
00259     if( (ES_MIC == es)||((!SYS_isHDDpresent())&&(WAV_RECQUALITY_INDEX+2 == sysParam.recQuality)) )
00260     {
00261         hdr[11] = 0x0100;   //NumChannels =1
00262         hdr[16] = 0x0200;   //BlockAlign
00263     }
00264     else
00265     {
00266         hdr[11] = 0x0200;   //NumChannels =2    
00267         hdr[16] = 0x0400;   //BlockAlign
00268     }
00269             
00270     // Get sample rate value from RecordQuality 
00271     switch(sysParam.recQuality)
00272     {
00273         case WAV_RECQUALITY_INDEX:                  
00274             hdr[12] = 0x401F;   //SampleRate = 8000, 
00275             hdr[13] = 0;
00276             
00277             if(ES_MIC == es)
00278             {
00279                 hdr[14] = 0x803E;   //ByteRate
00280                 hdr[15] = 0x0000;
00281             }
00282             else
00283             {
00284                 hdr[14] = 0x007D;   //ByteRate
00285                 hdr[15] = 0x0000;
00286             }               
00287             break;
00288             
00289         case WAV_RECQUALITY_INDEX + 1:      
00290             hdr[12] = 0x44AC;   //SampleRate = 44100, 
00291             hdr[13] = 0;
00292             
00293             if(ES_MIC == es)
00294             {
00295                 hdr[14] = 0x8858;   //ByteRate
00296                 hdr[15] = 0x0100;               
00297             }
00298             else
00299             {
00300                 hdr[14] = 0x10B1;   //ByteRate
00301                 hdr[15] = 0x0200;   
00302             }               
00303             break;
00304             
00305         case WAV_RECQUALITY_INDEX + 2:
00306         
00307             hdr[12] = 0x80BB;   //SampleRate = 48000, 
00308             hdr[13] = 0;
00309             
00310             // Due file system overhead, we are not able to support 48KHz WAV 
00311             // stereo recording into NAND flash.
00312             if( (ES_MIC == es)||(!SYS_isHDDpresent()) )
00313             {
00314                 hdr[14] = 0x0077;   //ByteRate
00315                 hdr[15] = 0x0100;   
00316             }   
00317             else
00318             {
00319                 hdr[14] = 0x00EE;   //ByteRate
00320                 hdr[15] = 0x0200;   
00321             }           
00322             break;
00323             
00324         default:
00325             break;
00326     }
00327     
00328     hdr[17] = 0x1000;   //BitsPerSample
00329     
00330     /* add 4 more bytes into hdr. */
00331     hdr[18] = 0x6461;   //"da"
00332     hdr[19] = 0x7461;   //"ta"
00333     
00334     hdr[20] = hdr[21] = 0;  //Subchunk2Size, will be written before file closed.
00335 
00336 
00337     // Assume an arbitrary big size to support revive crashed recording.
00338     {
00339         unsigned long   size = 0x03fffffff;
00340 
00341         // Write file size into wav header (ChunkSize) counted by bytes. 
00342         hdr[2] = ((size * 2) - 8) & 0x0FFFF;
00343         hdr[2] = (hdr[2] << 8) | ((hdr[2] >> 8) & 0x0FF);
00344                 
00345         hdr[3] = (((size * 2) - 8) >> 16) & 0x0FFFF;
00346         hdr[3] = (hdr[3] << 8) | ((hdr[3] >> 8) & 0x0FF);
00347                 
00348         // Write data chunk size into wav header (data SubchunkSize). 
00349         hdr[20] = ((size * 2) - 44)  & 0x0FFFF;
00350         hdr[20] = (hdr[20] << 8) | ((hdr[20] >> 8) & 0x0FF);
00351                 
00352         hdr[21] = (((size * 2) - 44) >> 16) & 0x0FFFF;
00353         hdr[21] = (hdr[21] << 8) | ((hdr[21] >> 8) & 0x0FF);
00354     }
00355     
00356     return 0;
00357 }

Here is the call graph for this function:

BOOL ENCODER__wav void   ) 
 

Function serves as the WAV encoder task handle.

Returns:
Always return TRUE.

Definition at line 74 of file ENCODER__wav.c.

References Audio, st_AUDIO::duration, st_ENCODER::encode, Encoder, ENCODER__wavEncode(), st_CODER::flag, st_ENCODER::garbage, st_ENCODER::mediaPipe, st_ENCODER::pipe, PIPE_readNext(), PIPE_writeNext(), and SAUDIOTIME_UPDT.

00075 {
00076     ULONG               tmpUL;
00077     PIPE_Obj *          pipe      = &Encoder.pipe;
00078     PIPE_Obj *          mediaPipe = &Encoder.mediaPipe; 
00079     EncoderSideInfo *   encode    = &Encoder.encode;
00080     
00081     // Encoder shutting down?
00082     if( Coder.flag & F_CODER_ENCODER_SETIDLE )
00083     {
00084         while( PIPE_writeFrameNum(mediaPipe) )
00085         {
00086             // Check queue to read.
00087             if(fsram_frameNum != MAX_FSRAM_QFRAME)
00088             {
00089                 // Check to rewind. 
00090                 if(fsram_rdptr == ENCODER_FSRAM_BUFLEN) fsram_rdptr = 0;
00091                 
00092                 // Write to frame.
00093                 memcpy((USHORT *)mediaPipe->WrFrame.Frame,
00094                         fsram_frameQ + fsram_rdptr,
00095                         ENCODER_MEDIA_PIPE_FRAMELEN );
00096 
00097                 fsram_rdptr += ENCODER_MEDIA_PIPE_FRAMELEN;             
00098                 fsram_frameNum++;
00099                 
00100                 // validate frame.
00101                 PIPE_writeNext(mediaPipe);
00102             }
00103             else
00104             {
00105                 Coder.flag |= F_CODER_ENCODER_IDLE;
00106                 Coder.flag &= ~F_CODER_ENCODER_DATAPENDING;
00107                 if(0==SEM_count(SEM_cache)) SEM_post(SEM_cache);    
00108                 break;
00109             }
00110             if(0==SEM_count(SEM_media)) SEM_post(SEM_media);    
00111         }       
00112         return TRUE;
00113     }
00114         
00115     if( PIPE_readFrameNum(pipe) ) 
00116     {      
00117         // See comment in UI_PSF_record.
00118         if(encode->nested == 0)
00119         {
00120             // Throw away the first 200ms audio.
00121             if(Encoder.garbage)
00122             {
00123                 Encoder.garbage--;
00124                 PIPE_readNext(&Encoder.pipe);
00125                 return TRUE;
00126             }
00127         
00128             wavrFrameIdx++;
00129             tmpUL = wavrFrameIdx*576/44100;
00130             if ( Audio.duration != tmpUL )
00131             {
00132                 Audio.duration = tmpUL;
00133                 mMSG_send(sysMsgQ, SYS_MSG_ID, SAUDIOTIME_UPDT, DONTCARE, 0);
00134             }   
00135         }
00136         else 
00137         {
00138             if(encode->nested == 1)
00139             {
00140                 encode->nested = 2;
00141                 Encoder.garbage = THROW_AWAY_SAMPLES;
00142                 // Now throw away buffered SRAM output.
00143                 fsram_frameNum += fsram_noiseFrameNum;
00144                 fsram_rdptr += fsram_noiseFrameNum*ENCODER_MEDIA_PIPE_FRAMELEN;
00145                 if(fsram_frameNum > MAX_FSRAM_QFRAME) 
00146                 {
00147                     fsram_frameNum = MAX_FSRAM_QFRAME;
00148                     fsram_rdptr    = fsram_wrptr;
00149                 }           
00150             }
00151         }
00152 
00153         // Setup sample rate conversion output buffer.
00154         SRC_setInput(&LeftSRC, (int *)pipe->RdFrame.Frame);             
00155         SRC_setInput(&RightSRC, (int *)pipe->RdFrame.Frame + ENCODER_PIPE_FRAMELEN/2 );       
00156         
00157         /* loop over sample rate converter until input buffers are empty */
00158         while (SRC_isInputBufferEmpty(&LeftSRC) == 0) 
00159         {   
00160             // run the left and right channels
00161             SRC_apply(&LeftSRC);                        
00162             SRC_apply(&RightSRC);
00163         
00164             if (SRC_isOutputBufferFull(&LeftSRC)) 
00165             {
00166                 SRC_setOutput(&LeftSRC, SRC_buf);
00167                 SRC_setOutput(&RightSRC, SRC_buf + WAV_SRC_BUFLEN/2);   
00168                 
00169                 /* Is queue writable? */
00170                 if( fsram_frameNum > wavrChNum )
00171                 {
00172                     int len;
00173                     
00174                     // Check to rewind.
00175                     if(fsram_wrptr == ENCODER_FSRAM_BUFLEN) fsram_wrptr = 0;
00176                     
00177                     len = (1==wavrChNum)? WAV_SRC_BUFLEN/2:WAV_SRC_BUFLEN;
00178                     ENCODER__wavEncode( SRC_buf, 
00179                                         fsram_frameQ + fsram_wrptr, 
00180                                         len, wavrChNum);
00181                     
00182                     fsram_wrptr += len;             
00183                     fsram_frameNum -= wavrChNum;        
00184                 }       
00185                 else            
00186                 {
00187                     // No frame left, simply return.
00188                     // Post media task to prevent dead lock. 
00189                     if(0==SEM_count(SEM_media)) SEM_post(SEM_media);
00190                 }               
00191             }
00192         }
00193         PIPE_readNext(&Encoder.pipe);
00194     }
00195 
00196         
00197     // Is there any free media frame?
00198     while( PIPE_writeFrameNum(mediaPipe) )
00199     {
00200         // Check queue to read.
00201         if(fsram_frameNum < MAX_FSRAM_QFRAME - RESERVED_SRAM_QFRAME)
00202         {
00203             // Check to rewind. 
00204             if(fsram_rdptr == ENCODER_FSRAM_BUFLEN) fsram_rdptr = 0;
00205                 
00206             // Write to frame.
00207             memcpy((USHORT *)mediaPipe->WrFrame.Frame,
00208                     fsram_frameQ + fsram_rdptr,                 
00209                     ENCODER_MEDIA_PIPE_FRAMELEN );
00210 
00211             fsram_rdptr += ENCODER_MEDIA_PIPE_FRAMELEN;             
00212             fsram_frameNum++;
00213                 
00214             // validate frame.
00215             PIPE_writeNext(mediaPipe);
00216             if(0==SEM_count(SEM_media)) SEM_post(SEM_media);
00217         }
00218         else 
00219         {
00220             Coder.flag &= ~F_CODER_ENCODER_DATAPENDING;
00221             return TRUE;
00222         }
00223     }       
00224     Coder.flag |= F_CODER_ENCODER_DATAPENDING;
00225     return TRUE;
00226 }

Here is the call graph for this function:

int ENCODER__wavEncode int *  in,
int *  out,
int  len,
int  chNum
 

Function serves as the WAV encoder task handle.

Convert big-endian audio data into little-endian.

Parameters:
in Input data buffer.
out Output data buffer.
len data length in words.
chNum number of channels.
Returns:
output data length in words.

Definition at line 375 of file ENCODER__wav.c.

Referenced by ENCODER__wav().

00376 {
00377     int *       in2 = in+len/2;
00378     int         dlen= len;
00379 
00380     if(1 == chNum) 
00381     {
00382         while(len--)
00383         {
00384             *out++ = ( (*in) << 8 ) | ( ((*in) >> 8) & 0x00ff);
00385             in++;                                                           
00386         }                       
00387     }
00388     else
00389     {
00390         len /= 2;
00391         while(len--)
00392         {
00393             *out++ = ( (*in) << 8 ) | ( ((*in) >> 8) & 0x00ff);
00394             *out++ = ( (*in2) << 8 ) | ( ((*in2) >> 8) & 0x00ff);
00395             in++;   
00396             in2++;                                      
00397         }                   
00398     }       
00399         
00400     return dlen;        
00401 }


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