VLSI Solution Oy VLSI Solution Oy Evaluation MP3 Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

record.c

Go to the documentation of this file.
00001 00003 #include "record.h" 00004 #include "filesys.h" 00005 #include "storage.h" 00006 #include "vs10xx.h" 00007 #include "console.h" 00008 #include "ui.h" 00009 #include "display.h" 00010 00011 00012 extern xdata unsigned char SPMax; 00013 00015 code const unsigned char RIFFHeader0[] = { 00016 'R' , 'I' , 'F' , 'F' , // Chunk ID (RIFF) 00017 0x70, 0x70, 0x70, 0x70, // Chunk payload size (calculate after rec!) 00018 'W' , 'A' , 'V' , 'E' , // RIFF resource format type 00019 00020 'f' , 'm' , 't' , ' ' , // Chunk ID (fmt ) 00021 0x14, 0x00, 0x00, 0x00, // Chunk payload size (0x14 = 20 bytes) 00022 0x11, 0x00, // Format Tag (IMA ADPCM) 00023 0x01, 0x00, // Channels (1) 00024 0x80, 0x3e, 0x00, 0x00, // Sample Rate, 0x3e80 = 16.0kHz 00025 0xd7, 0x0f, 0x00, 0x00, // Average Bytes Per Second 00026 0x00, 0x01, // Data Block Size (256 bytes) 00027 0x04, 0x00, // ADPCM encoded bits per sample (4 bits) 00028 0x02, 0x00, // Extra data (2 bytes) 00029 0xf9, 0x01, // Samples per Block (505 samples) 00030 00031 'f' , 'a' , 'c' , 't' , // Chunk ID (fact) 00032 0xc8, 0x01, 0x00, 0x00, // Chunk payload size (456 bytes (zeropad!)) 00033 0xff, 0xff, 0xff, 0xff // Number of Samples (calculate after rec!) 00034 // Insert 448 zeroes here! 00035 }; 00036 00038 code const unsigned char RIFFHeader504[] = { 00039 'd' , 'a' , 't' , 'a' , // Chunk ID (data) 00040 0x70, 0x70, 0x70, 0x70 // Chunk payload size (calculate after rec!) 00041 }; 00042 00043 00101 unsigned char Record(){ 00102 00103 xdata unsigned char blockNumber; 00104 xdata unsigned long sectorCount; 00105 xdata unsigned long lastSector; 00106 bit stopRecording = 0; 00107 bit continueRecording = 0; 00108 00109 char oldlevel=0; 00110 blockNumber = 0; 00111 sectorCount = 1; 00112 00113 playingState = PS_RECORDING; //Inform the world that rec mode is on. 00114 00115 // Kick vs10xx into action! 00116 00117 /* Set clock register, doubler etc. */ 00118 #ifdef VS1003 00119 // Set base xtal 14.7456MHZ (0x0696) | multiplier:fixed 2.5 (0x600) 00120 Mp3WriteRegister(SPI_CLOCKF,0x66,0x96); 00121 #else 00122 Mp3WriteRegister(SPI_CLOCKF,156,204); //for 14.576MHz XTAL 00123 #endif 00124 00125 //Set sample rate 16khz for VS1003 (6.4kHz for VS1002 :( ) 00126 Mp3WriteRegister(SPI_AICTRL0,0x00,0x09); //Set sample rate divider=9 00127 Mp3WriteRegister(SPI_AICTRL1,0x10,0x00); //AutoGain OFF, reclevel 0x1000 00128 Mp3WriteRegister(SPI_MODE,0x18,0x04); //RECORD,NEWMODE,RESET 00129 Delay(10); 00130 00131 /* Set clock register, doubler etc. */ 00132 #ifdef VS1003 00133 // Set base xtal 14.7456MHZ (0x0696) | multiplier:fixed 2.5 (0x600) 00134 Mp3WriteRegister(SPI_CLOCKF,0x66,0x96); 00135 #else 00136 Mp3WriteRegister(SPI_CLOCKF,156,204); //for 14.576MHz XTAL 00137 #endif 00138 00139 00140 // Locate free space 00151 freeSector = 0; 00152 ScanForFreeSector(); 00153 sectorAddress.l = freeSector; 00154 fragment[0].start = freeSector; 00155 00156 00164 for (temp.c=0; temp.c<56; temp.c++){ //temp is unsafe global temp variable. 00165 diskSect.raw.buf[temp.c] = RIFFHeader0[temp.c]; 00166 } 00167 for (temp.i=52; temp.i<504; temp.i++){ 00168 diskSect.raw.buf[temp.i] = 0; 00169 } 00170 for (temp.i=504; temp.i<512; temp.i++){ 00171 diskSect.raw.buf[temp.i] = RIFFHeader504[temp.i-504]; 00172 } 00173 00180 lastSector = freeSector; 00181 WriteDiskSector(freeSector); 00182 00183 /* Get a new free sector */ 00184 ScanForFreeSector(); 00185 sectorAddress.l = freeSector; 00186 dataBufPtr = diskSect.raw.buf; 00187 00188 Delay(10); 00189 //Sync to incoming audio frame... 00190 while (Mp3ReadRegister(SPI_HDAT1)>>8) //lots of data in buffer 00191 ; //Wait until buffer level restarts from 0 00192 00193 dataBufPtr = diskSect.raw.buf; //reset dataBufPtr to start of filebuffer 00194 blockNumber = 0; 00195 00196 ConsoleWrite("\rRecording, push button to stop..."); 00197 while((!KEY_BUTTON 00198 || (blockNumber!=0) 00199 || ((sectorCount)%(fatSectorsPerCluster)!=0)) 00200 && (!stopRecording)){ 00201 00202 GREEN_LED = LED_ON; 00203 00204 //Check for data 00205 if (Mp3ReadRegister(SPI_HDAT1) >= 128){ 00206 //there is a data block to be read... 00207 GREEN_LED = LED_OFF; 00208 blockNumber++; 00209 00210 //dataBufPtr should point inside disk buffer, this should never fail: 00211 if (dataBufPtr>(diskSect.raw.buf+511)){ 00212 ConsoleWrite("\rBuffer indexing error. Stop.\r"); 00213 while(1); //stop 00214 } 00215 00216 //Get the data 00217 for (temp.c=0;temp.c<128;temp.c++){ 00218 data unsigned int i; 00219 i = Mp3ReadRegister(SPI_HDAT0); 00220 *dataBufPtr++ = (i>>8); 00221 *dataBufPtr++ = (i&0xff); 00222 } 00223 00224 00225 { //Do basic SOUND LEVEL BAR calculation based on the 1 linear 00226 //sample in block[0] and [1] 00227 signed int soundlevel; 00228 // the user interface (level bar) calculation 00229 if (uiMode == UI_TITLE){ 00230 soundlevel = (signed char)diskSect.raw.buf[1]<<7; 00231 soundlevel |= diskSect.raw.buf[0]>>1; 00232 if (soundlevel<0) soundlevel = -soundlevel; 00233 displayValue=0; 00234 while (soundlevel>31){ 00235 displayValue++; 00236 soundlevel>>=1; 00237 } 00238 if (soundlevel>19) displayValue++; 00239 if (soundlevel>12) displayValue++; 00240 if (soundlevel>6) displayValue++; 00241 displayValue-=3; 00242 displayValue*=13; 00243 if (oldlevel>displayValue){ 00244 displayValue=oldlevel-3; 00245 } 00246 oldlevel=displayValue; 00247 } 00248 AvailableProcessorTime(); 00249 00250 }//SOUND LEVEL BAR calculation 00251 00252 }//if there was data to read 00253 00254 00255 //Release SCI chip select, we might want to use MMC card 00256 Mp3DeselectControl(); 00257 00258 if (blockNumber==2){ //2 blocks (512 bytes) received, write to disk... 00259 00260 //If we update the SPI_DECODE_TIME, it will show on player screen :) 00261 //we can do it, no problem. Here is the calculation for 16khz; 00262 //for 16kHz sample rate, 505 samples/block, 8 disk sectors are 00263 //exactly 505 milliseconds. 00264 temp.l = (sectorCount/8) * 505; 00265 temp.l /= 1000; 00266 Mp3WriteRegister(SPI_DECODE_TIME,temp.b.b1,temp.b.b0); 00267 Mp3DeselectControl(); 00268 00269 blockNumber = 0; 00270 sectorCount++; 00271 WriteDiskSector(sectorAddress.l); 00272 lastSector = freeSector; 00273 ScanForFreeSector(); //this would be the proper way to go... 00274 sectorAddress.l = freeSector; //keep all variables in proper values 00275 dataBufPtr = diskSect.raw.buf; //reset data buffer pointer 00276 if (freeSector!=(lastSector+1)){ //end of continuous space, must break! 00277 stopRecording = 1; 00278 ConsoleWrite("\nFragment end - can't continue recording!\n"); 00279 InitDisplay(DS_STATIC,"FRAGMENT"," LIMIT!!",0); 00280 continueRecording = 1; 00281 } 00282 } 00283 00284 displayValue = 0; 00285 00286 }//while not button - stop recording when BUTTON is pressed 00287 fragment[0].length = sectorCount; 00288 00289 00290 //Enter size information to RIFF header.. 00291 { 00292 xdata addressType size; 00293 00294 ReadDiskSector(fragment[0].start); 00295 00296 //Patch in number of samples 00297 size.l = (sectorCount-1)*1010; 00298 diskSect.raw.buf[48] = size.b.b0; 00299 diskSect.raw.buf[49] = size.b.b1; 00300 diskSect.raw.buf[50] = size.b.b2; 00301 diskSect.raw.buf[51] = size.b.b3; 00302 00303 //Patch in size of RIFF chunk... 00304 size.l = (sectorCount*512)-8; 00305 diskSect.raw.buf[4] = size.b.b0; 00306 diskSect.raw.buf[5] = size.b.b1; 00307 diskSect.raw.buf[6] = size.b.b2; 00308 diskSect.raw.buf[7] = size.b.b3; 00309 00310 //Patch in size of DATA chunk... 00311 size.l = (sectorCount*512)-512; 00312 diskSect.raw.buf[508] = size.b.b0; 00313 diskSect.raw.buf[509] = size.b.b1; 00314 diskSect.raw.buf[510] = size.b.b2; 00315 diskSect.raw.buf[511] = size.b.b3; 00316 00317 WriteDiskSector(sectorAddress.l); 00318 } 00319 00320 ConsoleWrite("Registering... FStart:"); 00321 ConsolePutUInt(fragment[0].start); 00322 ConsoleWrite("Registering... Size:"); 00323 ConsolePutUInt(fragment[0].length); 00324 00325 //Create FAT records. 00326 fragment[1].start = 0x0fffffff; //fragment 0 is the only fragment 00327 WriteClusterChain(); //register newly created file in FAT FS 00328 00331 sectorAddress.l = 0; //force sector reload for next access 00332 00333 Mp3Reset(); 00334 if (continueRecording) return PS_RECORDING; 00335 return PS_NEXT_SONG; 00336 00337 } 00338

All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules are limited to promotional use only and only with the VS1011 / VS1002 / VS1003 MP3-Evakit evaluation boards. Free or commercial use of these software modules in MP3 players is ok if the product includes MP3 decoder chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi