Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "SDHCFileSystem.h" 00003 #include "MSCFileSystem.h" 00004 #include "TLV320.h" 00005 00006 TLV320 audio(p9, p10, 52, p5, p6, p7, p8, p29); //TLV320 object 00007 SDFileSystem sd(p11, p12, p13, p14, "sd"); //SD Card object 00008 MSCFileSystem msc("usb"); //USB object 00009 InterruptIn finish(p16); //button to stop recording 00010 FILE *outfp; //file pointer object 00011 00012 /* Buffers, pointers and states */ 00013 int circularBuffer[4096]; 00014 volatile int writePointer = 0; 00015 volatile int theta = 0; 00016 volatile bool recording = false; 00017 volatile long size = 36; 00018 00019 /* Record settings */ 00020 unsigned int frequency = 8000; //sample rate 00021 unsigned short wordWidth = 16; //bits per sample per channel 00022 unsigned short channels = 2; //number of channels 00023 00024 /* Function to read content of I2SRXFIFO into circular buffer */ 00025 void record(void){ 00026 audio.read(); 00027 circularBuffer[writePointer] = audio.rxBuffer[0]; 00028 circularBuffer[++writePointer] = audio.rxBuffer[1]; 00029 circularBuffer[++writePointer] = audio.rxBuffer[2]; 00030 circularBuffer[++writePointer] = audio.rxBuffer[3]; 00031 ++writePointer; 00032 theta += 4; 00033 if(writePointer > 4094) writePointer = 0; 00034 } 00035 00036 /*Function to write data from circular buffer to usb storage */ 00037 void streamToFile(void){ 00038 static volatile int readPointer = 0; 00039 while(recording){ 00040 if(theta > 512){ // only start writing when there is enough data! 00041 fwrite(&circularBuffer[readPointer], 4, 128, outfp); //write data in 512 byte chunks, this is 00042 theta -= 128; //the natural usb memory chunk size 00043 readPointer += 128; 00044 if(readPointer > 4094) readPointer = 0; 00045 size += 512; 00046 } 00047 } 00048 //Complete file and header details 00049 fseek(outfp, 0, SEEK_END); 00050 for(int k = 0; k < theta; ++k){ 00051 fwrite(&circularBuffer[readPointer], 4, 1, outfp); //this writes the last of the data 00052 ++readPointer; //held in the circular buffer to memory 00053 if(readPointer > 4094) readPointer = 0; 00054 size += 4; 00055 } 00056 return; 00057 } 00058 00059 /* Function to stop recording, namely to stop audio interrupts */ 00060 void stopRecording(void){ 00061 audio.stop(); 00062 recording = false; 00063 return; 00064 } 00065 00066 /* Function to write .wav header */ 00067 void startHeader(void){ 00068 /* RIFF WAV header 00069 * --------------- 00070 * This is composed of several sub chunks. All strings 00071 * are in big endian form. All numeric data is in little endian form. 00072 * All data to be completed after recording (i.e. data chunk size) is default blank. 00073 */ 00074 char blockAlign = (char)channels * (wordWidth/8); 00075 int bps = (int)frequency * blockAlign; 00076 char header[44] = { 0x52, 0x49, 0x46, 0x46, //'RIFF' 00077 0x00, 0x00, 0x00, 0x00, //file size 00078 0x57, 0x41, 0x56, 0x45, //'WAVE' 00079 /*sub chunk 1*/ 0x66, 0x6d, 0x74, 0x20, //'fmt ' 00080 0x10, 0x00, 0x00, 0x00, //subchunk size = 16 00081 0x01, 0x00, ((char)(channels & 0xff)), 0x00, //PCM compression code | number of channels - I assume no more than 2 channels 00082 ((char)((frequency & 0xff)>>0)), ((char)((frequency & 0xff00)>>8)), ((char)((frequency & 0xff0000)>>16)), ((char)((frequency & 0xff000000)>>24)), //sample rate 00083 ((char)((bps & 0xff)>>0)), ((char)((bps & 0xff00)>>8)), ((char)((bps & 0xff0000)>>16)), ((char)((bps & 0xff000000)>>24)), //bit rate 00084 blockAlign, 0x00, ((char)((wordWidth & 0xff)>>0)), ((char)((wordWidth & 0xff00)>>8)), //bloack align | wordwidth 00085 /*sub chunk 2*/ 0x64, 0x61, 0x74, 0x61, //'data' 00086 0x00, 0x00, 0x00, 0x00}; //size of data chunk in bytes 00087 fwrite(header, 1, 44, outfp); 00088 } 00089 00090 /* Function to complete header, once recording finishes */ 00091 void completeHeader(void){ 00092 fseek(outfp, 4, SEEK_SET); 00093 fputc((int) (0xff & size), outfp); //All these lines are needed to switch the endianess of the data 00094 fputc((int) ((0xff00 & size) >> 8), outfp); 00095 fputc((int) ((0xff0000 & size) >> 16), outfp); 00096 fputc((int) ((0xff000000 & size) >> 24), outfp); 00097 fseek(outfp, 40, SEEK_SET); 00098 size -= 36; 00099 fputc((int) (0xff & size), outfp); 00100 fputc((int) ((0xff00 & size) >> 8), outfp); 00101 fputc((int) ((0xff0000 & size) >> 16), outfp); 00102 fputc((int) ((0xff000000 & size) >> 24), outfp); 00103 } 00104 00105 /* Main */ 00106 int main(){ 00107 /* Create a file to write to */ 00108 outfp = fopen("/usb/rec.wav", "w"); 00109 if(outfp == NULL){ 00110 perror("Error opening file!"); 00111 exit(1); 00112 } 00113 startHeader(); //write first half of header 00114 audio.power(0x02); //power up all TLV320, just not microphone 00115 audio.inputVolume(0.999, 0.999); //Set input volume to max - I don't like to use 1.0 due to rounding errors 00116 audio.frequency(frequency); 00117 audio.format(wordWidth, (2-channels)); //note int mode = 2 - channels 00118 audio.attach(&record); //attach record function to audio interrupt 00119 finish.rise(&stopRecording); //attach stop button 00120 for(int j = 0; j < 4096; ++j){ 00121 circularBuffer[j] = 0; //clear circular buffer 00122 } 00123 recording = true; 00124 audio.start(RECEIVE); //start recording 00125 streamToFile(); 00126 completeHeader(); //once finished recording complete the header 00127 fclose(outfp); //and close the file 00128 }
Generated on Fri Jul 15 2022 11:08:43 by
1.7.2