Natthaphon Sudadech
/
PJ04_MASTER
+mp3
Fork of VS1053 by
player.cpp@0:58524d569dfd, 2016-12-02 (annotated)
- Committer:
- cha45689
- Date:
- Fri Dec 02 19:37:00 2016 +0000
- Revision:
- 0:58524d569dfd
- Child:
- 1:17913cff05a2
ss
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cha45689 | 0:58524d569dfd | 1 | #include "player.h" |
cha45689 | 0:58524d569dfd | 2 | #include"SDFileSystem.h" |
cha45689 | 0:58524d569dfd | 3 | |
cha45689 | 0:58524d569dfd | 4 | SDFileSystem sd(D11, D12, D13, D9, "sd"); // the pinout on the mbed Cool |
cha45689 | 0:58524d569dfd | 5 | vs10xx vs1053(D11, D12, D13, D6, D7, D2, D8);//mosi,miso,sclk,xcs,xdcs,dreq,xreset |
cha45689 | 0:58524d569dfd | 6 | Serial pc(USBTX, USBRX); |
cha45689 | 0:58524d569dfd | 7 | playerStatetype playerState; |
cha45689 | 0:58524d569dfd | 8 | ctrlStatetype ctrlState; |
cha45689 | 0:58524d569dfd | 9 | static unsigned char fileBuf[1024]; |
cha45689 | 0:58524d569dfd | 10 | unsigned char *bufptr; |
cha45689 | 0:58524d569dfd | 11 | |
cha45689 | 0:58524d569dfd | 12 | char list[20][14]; //song list |
cha45689 | 0:58524d569dfd | 13 | char index = 0; //song play index |
cha45689 | 0:58524d569dfd | 14 | char index_MAX; //how many song in all |
cha45689 | 0:58524d569dfd | 15 | unsigned char vlume = 0x40; //vlume |
cha45689 | 0:58524d569dfd | 16 | unsigned char vlumeflag = 0; //set vlume flag |
cha45689 | 0:58524d569dfd | 17 | |
cha45689 | 0:58524d569dfd | 18 | void Player::begin(void) |
cha45689 | 0:58524d569dfd | 19 | { |
cha45689 | 0:58524d569dfd | 20 | DirHandle *dir; |
cha45689 | 0:58524d569dfd | 21 | struct dirent *ptr; |
cha45689 | 0:58524d569dfd | 22 | FileHandle *fp; |
cha45689 | 0:58524d569dfd | 23 | |
cha45689 | 0:58524d569dfd | 24 | vs1053.reset(); |
cha45689 | 0:58524d569dfd | 25 | dir = opendir("/sd"); |
cha45689 | 0:58524d569dfd | 26 | printf("\r\n**********playing list**********\r\n"); |
cha45689 | 0:58524d569dfd | 27 | unsigned char i = 0,j=0; |
cha45689 | 0:58524d569dfd | 28 | while(((ptr = dir->readdir()) != NULL)&&(i <20)) |
cha45689 | 0:58524d569dfd | 29 | { |
cha45689 | 0:58524d569dfd | 30 | if(strstr(ptr->d_name,".mp3")||strstr(ptr->d_name,".MP3")||strstr(ptr->d_name,".WAV")||strstr(ptr->d_name,".wav") |
cha45689 | 0:58524d569dfd | 31 | ||strstr(ptr->d_name,".WMA")||strstr(ptr->d_name,".wma")||strstr(ptr->d_name,".OGG")||strstr(ptr->d_name,".ogg") |
cha45689 | 0:58524d569dfd | 32 | ||strstr(ptr->d_name,".AAC")||strstr(ptr->d_name,".aac")||strstr(ptr->d_name,".FLAC")||strstr(ptr->d_name,".flac")) |
cha45689 | 0:58524d569dfd | 33 | { |
cha45689 | 0:58524d569dfd | 34 | fp =sd.open(ptr->d_name, O_RDONLY); |
cha45689 | 0:58524d569dfd | 35 | if(fp != NULL) |
cha45689 | 0:58524d569dfd | 36 | { |
cha45689 | 0:58524d569dfd | 37 | char *byte = ptr->d_name; |
cha45689 | 0:58524d569dfd | 38 | j=0; |
cha45689 | 0:58524d569dfd | 39 | while(*byte) |
cha45689 | 0:58524d569dfd | 40 | { |
cha45689 | 0:58524d569dfd | 41 | list[i][j++] = *byte++; |
cha45689 | 0:58524d569dfd | 42 | } |
cha45689 | 0:58524d569dfd | 43 | pc.printf("%2d . %s\r\n", i,list[i++]); |
cha45689 | 0:58524d569dfd | 44 | //fp->close(); |
cha45689 | 0:58524d569dfd | 45 | } |
cha45689 | 0:58524d569dfd | 46 | } |
cha45689 | 0:58524d569dfd | 47 | } |
cha45689 | 0:58524d569dfd | 48 | index_MAX = i-1; |
cha45689 | 0:58524d569dfd | 49 | dir->closedir(); |
cha45689 | 0:58524d569dfd | 50 | printf("\r\n"); |
cha45689 | 0:58524d569dfd | 51 | } |
cha45689 | 0:58524d569dfd | 52 | |
cha45689 | 0:58524d569dfd | 53 | /* This function plays back an audio file. */ |
cha45689 | 0:58524d569dfd | 54 | void Player::playFile(char *file) { |
cha45689 | 0:58524d569dfd | 55 | int bytes; // How many bytes in buffer left |
cha45689 | 0:58524d569dfd | 56 | char n; |
cha45689 | 0:58524d569dfd | 57 | |
cha45689 | 0:58524d569dfd | 58 | |
cha45689 | 0:58524d569dfd | 59 | playerState = PS_PLAY; |
cha45689 | 0:58524d569dfd | 60 | |
cha45689 | 0:58524d569dfd | 61 | if (strstr(file, ".flac")) |
cha45689 | 0:58524d569dfd | 62 | { |
cha45689 | 0:58524d569dfd | 63 | printf("Loading FLAC Plugin...\r\n"); |
cha45689 | 0:58524d569dfd | 64 | vs1053.loadPlugin(flacPlugin,sizeof(flacPlugin)/sizeof(flacPlugin[0])); |
cha45689 | 0:58524d569dfd | 65 | } |
cha45689 | 0:58524d569dfd | 66 | |
cha45689 | 0:58524d569dfd | 67 | vs1053.setFreq(24000000); //hight speed |
cha45689 | 0:58524d569dfd | 68 | |
cha45689 | 0:58524d569dfd | 69 | FileHandle *fp =sd.open(file, O_RDONLY); |
cha45689 | 0:58524d569dfd | 70 | |
cha45689 | 0:58524d569dfd | 71 | if(fp == NULL) { |
cha45689 | 0:58524d569dfd | 72 | printf("Could not open %s\r\n",file); |
cha45689 | 0:58524d569dfd | 73 | |
cha45689 | 0:58524d569dfd | 74 | } |
cha45689 | 0:58524d569dfd | 75 | else |
cha45689 | 0:58524d569dfd | 76 | { |
cha45689 | 0:58524d569dfd | 77 | printf("Playing %s ...\r\n",file); |
cha45689 | 0:58524d569dfd | 78 | |
cha45689 | 0:58524d569dfd | 79 | /* Main playback loop */ |
cha45689 | 0:58524d569dfd | 80 | while((bytes = fp->read(fileBuf,512)) > 0) |
cha45689 | 0:58524d569dfd | 81 | { |
cha45689 | 0:58524d569dfd | 82 | bufptr = fileBuf; |
cha45689 | 0:58524d569dfd | 83 | |
cha45689 | 0:58524d569dfd | 84 | // actual audio data gets sent to VS10xx. |
cha45689 | 0:58524d569dfd | 85 | while(bytes > 0) |
cha45689 | 0:58524d569dfd | 86 | { |
cha45689 | 0:58524d569dfd | 87 | n = (bytes < 32)?bytes:32; |
cha45689 | 0:58524d569dfd | 88 | vs1053.writeData(bufptr,n); |
cha45689 | 0:58524d569dfd | 89 | bytes -= n; |
cha45689 | 0:58524d569dfd | 90 | bufptr += n; |
cha45689 | 0:58524d569dfd | 91 | } |
cha45689 | 0:58524d569dfd | 92 | while(playerState == PS_PAUSE); //Pause |
cha45689 | 0:58524d569dfd | 93 | |
cha45689 | 0:58524d569dfd | 94 | if(vlumeflag) //set vlume |
cha45689 | 0:58524d569dfd | 95 | { |
cha45689 | 0:58524d569dfd | 96 | vs1053.setFreq(12000000); //low speed |
cha45689 | 0:58524d569dfd | 97 | vs1053.writeRegister(SPI_VOL, vlume*0x101); //Set volume level |
cha45689 | 0:58524d569dfd | 98 | vs1053.setFreq(24000000); //higth speed |
cha45689 | 0:58524d569dfd | 99 | vlumeflag = 0; //clear flag; |
cha45689 | 0:58524d569dfd | 100 | } |
cha45689 | 0:58524d569dfd | 101 | |
cha45689 | 0:58524d569dfd | 102 | if(playerState != PS_PLAY) //stop |
cha45689 | 0:58524d569dfd | 103 | { |
cha45689 | 0:58524d569dfd | 104 | fp->close(); |
cha45689 | 0:58524d569dfd | 105 | vs1053.softReset(); |
cha45689 | 0:58524d569dfd | 106 | return; |
cha45689 | 0:58524d569dfd | 107 | } |
cha45689 | 0:58524d569dfd | 108 | } |
cha45689 | 0:58524d569dfd | 109 | fp->close(); |
cha45689 | 0:58524d569dfd | 110 | vs1053.softReset(); |
cha45689 | 0:58524d569dfd | 111 | printf("[done!]\r\n"); |
cha45689 | 0:58524d569dfd | 112 | } |
cha45689 | 0:58524d569dfd | 113 | if(index != index_MAX)index++; |
cha45689 | 0:58524d569dfd | 114 | else index = 0; |
cha45689 | 0:58524d569dfd | 115 | } |
cha45689 | 0:58524d569dfd | 116 | |
cha45689 | 0:58524d569dfd | 117 | |
cha45689 | 0:58524d569dfd | 118 | /* PCM file Header */ |
cha45689 | 0:58524d569dfd | 119 | unsigned char pcmHeader[44] = { |
cha45689 | 0:58524d569dfd | 120 | 'R', 'I', 'F', 'F', |
cha45689 | 0:58524d569dfd | 121 | 0xFF, 0xFF, 0xFF, 0xFF, |
cha45689 | 0:58524d569dfd | 122 | 'W', 'A', 'V', 'E', |
cha45689 | 0:58524d569dfd | 123 | 'f', 'm', 't', ' ', |
cha45689 | 0:58524d569dfd | 124 | 0x10, 0, 0, 0, /* 16 */ |
cha45689 | 0:58524d569dfd | 125 | 0x1, 0, /* PCM */ |
cha45689 | 0:58524d569dfd | 126 | 0x1, 0, /* chan */ |
cha45689 | 0:58524d569dfd | 127 | 0x40, 0x1F, 0x0, 0x0, /* sampleRate */ |
cha45689 | 0:58524d569dfd | 128 | 0x80, 0x3E, 0x0, 0x0, /* byteRate */ |
cha45689 | 0:58524d569dfd | 129 | 2, 0, /* blockAlign */ |
cha45689 | 0:58524d569dfd | 130 | 0x10, 0, /* bitsPerSample */ |
cha45689 | 0:58524d569dfd | 131 | 'd', 'a', 't', 'a', |
cha45689 | 0:58524d569dfd | 132 | 0xFF, 0xFF, 0xFF, 0xFF |
cha45689 | 0:58524d569dfd | 133 | }; |
cha45689 | 0:58524d569dfd | 134 | |
cha45689 | 0:58524d569dfd | 135 | void Set32(unsigned char *d, unsigned int n) { |
cha45689 | 0:58524d569dfd | 136 | int i; |
cha45689 | 0:58524d569dfd | 137 | for (i=0; i<4; i++) { |
cha45689 | 0:58524d569dfd | 138 | *d++ = (unsigned char)n; |
cha45689 | 0:58524d569dfd | 139 | n >>= 8; |
cha45689 | 0:58524d569dfd | 140 | } |
cha45689 | 0:58524d569dfd | 141 | } |
cha45689 | 0:58524d569dfd | 142 | |
cha45689 | 0:58524d569dfd | 143 | /* This function records an audio file in WAV formats.Use LINK1,left channel */ |
cha45689 | 0:58524d569dfd | 144 | void Player::recordFile(char *file) { |
cha45689 | 0:58524d569dfd | 145 | unsigned int fileSize = 0; |
cha45689 | 0:58524d569dfd | 146 | unsigned int n; |
cha45689 | 0:58524d569dfd | 147 | |
cha45689 | 0:58524d569dfd | 148 | vs1053.writeRegister(SPI_BASS, 0x0055); //set accent |
cha45689 | 0:58524d569dfd | 149 | vs1053.writeRegister(SPI_AICTRL0,8000); //samplerate 8k |
cha45689 | 0:58524d569dfd | 150 | vs1053.writeRegister(SPI_AICTRL1,0); //record gain |
cha45689 | 0:58524d569dfd | 151 | vs1053.writeRegister(SPI_AICTRL2,0); //Set the gain maximum,65536=64X |
cha45689 | 0:58524d569dfd | 152 | vs1053.writeRegister(SPI_AICTRL3,7); //PCM Mode ,left channel,earphone mic |
cha45689 | 0:58524d569dfd | 153 | //vs1053.writeRegister(SPI_AICTRL3,6); //PCM Mode ,right channel,board mic |
cha45689 | 0:58524d569dfd | 154 | vs1053.writeRegister(SPI_CLOCKF,0x2000); //set clock |
cha45689 | 0:58524d569dfd | 155 | |
cha45689 | 0:58524d569dfd | 156 | printf("loading recording plugin......\r\n"); |
cha45689 | 0:58524d569dfd | 157 | vs1053.writeRegister(SPI_MODE,0x1804); //Initialize recording |
cha45689 | 0:58524d569dfd | 158 | |
cha45689 | 0:58524d569dfd | 159 | vs1053.loadPlugin(recPlugin,sizeof(recPlugin)/sizeof(recPlugin[0])); |
cha45689 | 0:58524d569dfd | 160 | sd.remove(file); |
cha45689 | 0:58524d569dfd | 161 | FileHandle *fp =sd.open(file, O_WRONLY|O_CREAT); |
cha45689 | 0:58524d569dfd | 162 | if(fp == NULL) { |
cha45689 | 0:58524d569dfd | 163 | printf("Could not open file for write\r\n"); |
cha45689 | 0:58524d569dfd | 164 | } |
cha45689 | 0:58524d569dfd | 165 | else |
cha45689 | 0:58524d569dfd | 166 | { |
cha45689 | 0:58524d569dfd | 167 | printf("recording......\r\n"); |
cha45689 | 0:58524d569dfd | 168 | while(playerState == PS_RECORDING) |
cha45689 | 0:58524d569dfd | 169 | { |
cha45689 | 0:58524d569dfd | 170 | unsigned int i; |
cha45689 | 0:58524d569dfd | 171 | unsigned char *rbp = fileBuf; |
cha45689 | 0:58524d569dfd | 172 | /* See if there is some data available */ |
cha45689 | 0:58524d569dfd | 173 | if ((n = vs1053.readRegister(SPI_HDAT1)) > 0) { |
cha45689 | 0:58524d569dfd | 174 | /* Make little-endian conversion for 16-bit PCM .WAV files */ |
cha45689 | 0:58524d569dfd | 175 | if(n>511)n=511; |
cha45689 | 0:58524d569dfd | 176 | for (i=0; i<n;i++) { |
cha45689 | 0:58524d569dfd | 177 | unsigned int w = vs1053.readRegister(SPI_HDAT0); |
cha45689 | 0:58524d569dfd | 178 | *rbp++ = (unsigned char)(w & 0xFF); |
cha45689 | 0:58524d569dfd | 179 | *rbp++ = (unsigned char)(w >> 8); |
cha45689 | 0:58524d569dfd | 180 | } |
cha45689 | 0:58524d569dfd | 181 | fp->write(fileBuf,2*n); |
cha45689 | 0:58524d569dfd | 182 | fileSize += 2*n; |
cha45689 | 0:58524d569dfd | 183 | } |
cha45689 | 0:58524d569dfd | 184 | |
cha45689 | 0:58524d569dfd | 185 | } |
cha45689 | 0:58524d569dfd | 186 | |
cha45689 | 0:58524d569dfd | 187 | /* Update file sizes for an RIFF PCM .WAV file */ |
cha45689 | 0:58524d569dfd | 188 | fp->lseek(0, SEEK_SET); |
cha45689 | 0:58524d569dfd | 189 | Set32(pcmHeader+4, fileSize-8); |
cha45689 | 0:58524d569dfd | 190 | Set32(pcmHeader+40, fileSize-36); |
cha45689 | 0:58524d569dfd | 191 | fp->write(pcmHeader, sizeof(pcmHeader)); |
cha45689 | 0:58524d569dfd | 192 | fp->close(); |
cha45689 | 0:58524d569dfd | 193 | |
cha45689 | 0:58524d569dfd | 194 | printf("recording end\r\n"); |
cha45689 | 0:58524d569dfd | 195 | } |
cha45689 | 0:58524d569dfd | 196 | /* Finally, reset the VS10xx software, including realoading the |
cha45689 | 0:58524d569dfd | 197 | patches package, to make sure everything is set up properly. */ |
cha45689 | 0:58524d569dfd | 198 | vs1053.softReset(); |
cha45689 | 0:58524d569dfd | 199 | |
cha45689 | 0:58524d569dfd | 200 | } |
cha45689 | 0:58524d569dfd | 201 |