My Billy Bass program, see my notebook for details
Dependencies: EthernetNetIf mbed
main.cpp@0:7613b886e052, 2010-08-14 (annotated)
- Committer:
- tombracer
- Date:
- Sat Aug 14 19:00:53 2010 +0000
- Revision:
- 0:7613b886e052
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tombracer | 0:7613b886e052 | 1 | |
tombracer | 0:7613b886e052 | 2 | |
tombracer | 0:7613b886e052 | 3 | #include "mbed.h" |
tombracer | 0:7613b886e052 | 4 | #include "SDHCFileSystem.h" |
tombracer | 0:7613b886e052 | 5 | #include "HTTPClient.h" |
tombracer | 0:7613b886e052 | 6 | #include "EthernetNetIf.h" |
tombracer | 0:7613b886e052 | 7 | |
tombracer | 0:7613b886e052 | 8 | #define SAMPLE_FREQ 40000 |
tombracer | 0:7613b886e052 | 9 | #define BUF_SIZE (SAMPLE_FREQ/10) |
tombracer | 0:7613b886e052 | 10 | #define SLICE_BUF_SIZE 1 |
tombracer | 0:7613b886e052 | 11 | |
tombracer | 0:7613b886e052 | 12 | typedef struct uFMT_STRUCT { |
tombracer | 0:7613b886e052 | 13 | short comp_code; |
tombracer | 0:7613b886e052 | 14 | short num_channels; |
tombracer | 0:7613b886e052 | 15 | unsigned sample_rate; |
tombracer | 0:7613b886e052 | 16 | unsigned avg_Bps; |
tombracer | 0:7613b886e052 | 17 | short block_align; |
tombracer | 0:7613b886e052 | 18 | short sig_bps; |
tombracer | 0:7613b886e052 | 19 | } FMT_STRUCT; |
tombracer | 0:7613b886e052 | 20 | |
tombracer | 0:7613b886e052 | 21 | short DAC_fifo[256]; |
tombracer | 0:7613b886e052 | 22 | short DAC_wptr; |
tombracer | 0:7613b886e052 | 23 | short DAC_rptr; |
tombracer | 0:7613b886e052 | 24 | short DAC_on; |
tombracer | 0:7613b886e052 | 25 | |
tombracer | 0:7613b886e052 | 26 | DigitalOut led1(LED1); |
tombracer | 0:7613b886e052 | 27 | DigitalOut led2(LED2); |
tombracer | 0:7613b886e052 | 28 | DigitalOut led3(LED3); |
tombracer | 0:7613b886e052 | 29 | DigitalOut led4(LED4); |
tombracer | 0:7613b886e052 | 30 | |
tombracer | 0:7613b886e052 | 31 | SDFileSystem sd(p5, p6, p7, p13, "sd"); |
tombracer | 0:7613b886e052 | 32 | |
tombracer | 0:7613b886e052 | 33 | EthernetNetIf eth; |
tombracer | 0:7613b886e052 | 34 | HTTPClient http; |
tombracer | 0:7613b886e052 | 35 | |
tombracer | 0:7613b886e052 | 36 | void download_bmf(void); |
tombracer | 0:7613b886e052 | 37 | void load_lipsync(char[]); |
tombracer | 0:7613b886e052 | 38 | void mouth(void); |
tombracer | 0:7613b886e052 | 39 | |
tombracer | 0:7613b886e052 | 40 | void dac_out(void); |
tombracer | 0:7613b886e052 | 41 | void dingdong(void); |
tombracer | 0:7613b886e052 | 42 | |
tombracer | 0:7613b886e052 | 43 | void body_move(int); |
tombracer | 0:7613b886e052 | 44 | void tail_flap(int); |
tombracer | 0:7613b886e052 | 45 | |
tombracer | 0:7613b886e052 | 46 | int dl(char[], char[]); |
tombracer | 0:7613b886e052 | 47 | void surf(char[]); |
tombracer | 0:7613b886e052 | 48 | void pollserver(void); |
tombracer | 0:7613b886e052 | 49 | |
tombracer | 0:7613b886e052 | 50 | DigitalOut ruu1(p21); //tail |
tombracer | 0:7613b886e052 | 51 | DigitalOut ruu2(p22); //body |
tombracer | 0:7613b886e052 | 52 | DigitalOut suu1(p23); |
tombracer | 0:7613b886e052 | 53 | DigitalOut suu2(p24); |
tombracer | 0:7613b886e052 | 54 | DigitalOut ena(p25); //enable |
tombracer | 0:7613b886e052 | 55 | |
tombracer | 0:7613b886e052 | 56 | Ticker tick; |
tombracer | 0:7613b886e052 | 57 | Ticker polltick; |
tombracer | 0:7613b886e052 | 58 | #define POLLINTERVAL 10 //server polling interval in seconds |
tombracer | 0:7613b886e052 | 59 | bool pollfound = false; //flag goes up if there is something to play |
tombracer | 0:7613b886e052 | 60 | |
tombracer | 0:7613b886e052 | 61 | AnalogOut DACout(p18); |
tombracer | 0:7613b886e052 | 62 | DigitalOut relay1(p29); |
tombracer | 0:7613b886e052 | 63 | |
tombracer | 0:7613b886e052 | 64 | InterruptIn doorbell(p30); |
tombracer | 0:7613b886e052 | 65 | void dummy(void); |
tombracer | 0:7613b886e052 | 66 | |
tombracer | 0:7613b886e052 | 67 | void play_wave(char *, bool); |
tombracer | 0:7613b886e052 | 68 | |
tombracer | 0:7613b886e052 | 69 | Ticker movetick; //runs the lipsync function |
tombracer | 0:7613b886e052 | 70 | #define SAYSPEED 0.085 //speed of lipsync in seconds |
tombracer | 0:7613b886e052 | 71 | char lipmoves[300]; //array for lipmove bits |
tombracer | 0:7613b886e052 | 72 | int lippos; |
tombracer | 0:7613b886e052 | 73 | |
tombracer | 0:7613b886e052 | 74 | bool doorint = false; //doorbell interrupt flag |
tombracer | 0:7613b886e052 | 75 | |
tombracer | 0:7613b886e052 | 76 | |
tombracer | 0:7613b886e052 | 77 | int main() { |
tombracer | 0:7613b886e052 | 78 | |
tombracer | 0:7613b886e052 | 79 | //setup ethernet connection |
tombracer | 0:7613b886e052 | 80 | printf("Setting up ethernet...\n"); |
tombracer | 0:7613b886e052 | 81 | EthernetErr ethErr = eth.setup(); |
tombracer | 0:7613b886e052 | 82 | if(ethErr) { |
tombracer | 0:7613b886e052 | 83 | printf("Error %d in ethernet setup.\n", ethErr); |
tombracer | 0:7613b886e052 | 84 | }//if |
tombracer | 0:7613b886e052 | 85 | |
tombracer | 0:7613b886e052 | 86 | printf("Ethernet setup OK\n"); |
tombracer | 0:7613b886e052 | 87 | |
tombracer | 0:7613b886e052 | 88 | //putting doorbell pin(p30) in pullup mode so it pulls up the voltage |
tombracer | 0:7613b886e052 | 89 | //between interrupts that pull it down |
tombracer | 0:7613b886e052 | 90 | doorbell.mode(PullUp); |
tombracer | 0:7613b886e052 | 91 | |
tombracer | 0:7613b886e052 | 92 | //run interrupt function when detecting a falling edge on p30 |
tombracer | 0:7613b886e052 | 93 | doorbell.fall(&dummy); |
tombracer | 0:7613b886e052 | 94 | doorbell.fall(&dingdong); |
tombracer | 0:7613b886e052 | 95 | |
tombracer | 0:7613b886e052 | 96 | lippos = 0; |
tombracer | 0:7613b886e052 | 97 | suu1 = suu2 = ruu1 = ruu2 = 0; |
tombracer | 0:7613b886e052 | 98 | ena = 1; //enable L293 chip |
tombracer | 0:7613b886e052 | 99 | |
tombracer | 0:7613b886e052 | 100 | //starting http server polling ticker (10 second intervals) |
tombracer | 0:7613b886e052 | 101 | polltick.attach(&pollserver, POLLINTERVAL); |
tombracer | 0:7613b886e052 | 102 | |
tombracer | 0:7613b886e052 | 103 | while(1) { |
tombracer | 0:7613b886e052 | 104 | //check if polling flag is up |
tombracer | 0:7613b886e052 | 105 | if(pollfound==true) { |
tombracer | 0:7613b886e052 | 106 | polltick.detach(); |
tombracer | 0:7613b886e052 | 107 | doorbell.fall(&dummy); |
tombracer | 0:7613b886e052 | 108 | |
tombracer | 0:7613b886e052 | 109 | //TODO: dl an effect description file or an sfx sound file |
tombracer | 0:7613b886e052 | 110 | |
tombracer | 0:7613b886e052 | 111 | //download lipsync file and load it into the array |
tombracer | 0:7613b886e052 | 112 | if(dl("http://192.168.1.2/talk/snd.bmf", "/sd/snd.bmf")==0) { |
tombracer | 0:7613b886e052 | 113 | load_lipsync("/sd/snd.bmf"); |
tombracer | 0:7613b886e052 | 114 | }//inner if |
tombracer | 0:7613b886e052 | 115 | |
tombracer | 0:7613b886e052 | 116 | //flap the tail before playing |
tombracer | 0:7613b886e052 | 117 | tail_flap(2); |
tombracer | 0:7613b886e052 | 118 | |
tombracer | 0:7613b886e052 | 119 | //play downloaded file (new waveplayer code) |
tombracer | 0:7613b886e052 | 120 | play_wave("/sd/snd.wav", true); |
tombracer | 0:7613b886e052 | 121 | |
tombracer | 0:7613b886e052 | 122 | //add event to eventlog (info=type:sender:description) |
tombracer | 0:7613b886e052 | 123 | surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Played%20wavefile%20snd.wav"); |
tombracer | 0:7613b886e052 | 124 | |
tombracer | 0:7613b886e052 | 125 | //delete played sound file |
tombracer | 0:7613b886e052 | 126 | surf("http://192.168.1.2/talk/dlok.php?delete=yes"); |
tombracer | 0:7613b886e052 | 127 | |
tombracer | 0:7613b886e052 | 128 | //add event to eventlog (info=type:sender:description) |
tombracer | 0:7613b886e052 | 129 | surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Deleted%20wavefile%20snd.wav%20from%20server."); |
tombracer | 0:7613b886e052 | 130 | |
tombracer | 0:7613b886e052 | 131 | //reset pollfound flag |
tombracer | 0:7613b886e052 | 132 | pollfound = false; |
tombracer | 0:7613b886e052 | 133 | polltick.attach(&pollserver, POLLINTERVAL); |
tombracer | 0:7613b886e052 | 134 | doorbell.fall(&dingdong); |
tombracer | 0:7613b886e052 | 135 | }//if pollfound |
tombracer | 0:7613b886e052 | 136 | |
tombracer | 0:7613b886e052 | 137 | //check if doorbell flag is raised for doorbell press |
tombracer | 0:7613b886e052 | 138 | if(doorint==true) { |
tombracer | 0:7613b886e052 | 139 | printf("Doorbell press detected..\n"); |
tombracer | 0:7613b886e052 | 140 | |
tombracer | 0:7613b886e052 | 141 | polltick.detach(); |
tombracer | 0:7613b886e052 | 142 | |
tombracer | 0:7613b886e052 | 143 | play_wave("/sd/ns.wav", false); //doorbell sound, no lipmoves |
tombracer | 0:7613b886e052 | 144 | |
tombracer | 0:7613b886e052 | 145 | load_lipsync("/sd/tulossa.bmf"); |
tombracer | 0:7613b886e052 | 146 | |
tombracer | 0:7613b886e052 | 147 | ruu2 = 1;//raise body |
tombracer | 0:7613b886e052 | 148 | play_wave("/sd/tulossa.wav", true); |
tombracer | 0:7613b886e052 | 149 | ruu2 = 0;//lower body |
tombracer | 0:7613b886e052 | 150 | |
tombracer | 0:7613b886e052 | 151 | //add event to eventlog (info=type:sender:description) |
tombracer | 0:7613b886e052 | 152 | surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Doorbell%20pressed"); |
tombracer | 0:7613b886e052 | 153 | |
tombracer | 0:7613b886e052 | 154 | //reattach polling ticker |
tombracer | 0:7613b886e052 | 155 | polltick.attach(&pollserver, POLLINTERVAL); |
tombracer | 0:7613b886e052 | 156 | |
tombracer | 0:7613b886e052 | 157 | //reset doorbell interrupt flag |
tombracer | 0:7613b886e052 | 158 | doorint = false; |
tombracer | 0:7613b886e052 | 159 | }//if doorint |
tombracer | 0:7613b886e052 | 160 | }//while 1 |
tombracer | 0:7613b886e052 | 161 | |
tombracer | 0:7613b886e052 | 162 | }///////////// main ends ////////////////// |
tombracer | 0:7613b886e052 | 163 | |
tombracer | 0:7613b886e052 | 164 | //dummy function for the interruptin 'fix' |
tombracer | 0:7613b886e052 | 165 | void dummy() {} |
tombracer | 0:7613b886e052 | 166 | |
tombracer | 0:7613b886e052 | 167 | |
tombracer | 0:7613b886e052 | 168 | //this function is attached to polltick, and it polls the server |
tombracer | 0:7613b886e052 | 169 | //every 10 seconds looking for something to download and play |
tombracer | 0:7613b886e052 | 170 | void pollserver() { |
tombracer | 0:7613b886e052 | 171 | printf("Attempting download..\n"); |
tombracer | 0:7613b886e052 | 172 | led1 = 1; |
tombracer | 0:7613b886e052 | 173 | |
tombracer | 0:7613b886e052 | 174 | //if download is successful, raise flag |
tombracer | 0:7613b886e052 | 175 | if (dl("http://192.168.1.2/talk/snd.wav", "/sd/snd.wav")==0) { |
tombracer | 0:7613b886e052 | 176 | pollfound = true; |
tombracer | 0:7613b886e052 | 177 | polltick.detach(); |
tombracer | 0:7613b886e052 | 178 | }//if dl.. |
tombracer | 0:7613b886e052 | 179 | |
tombracer | 0:7613b886e052 | 180 | led1 = 0; |
tombracer | 0:7613b886e052 | 181 | }//pollserver |
tombracer | 0:7613b886e052 | 182 | |
tombracer | 0:7613b886e052 | 183 | |
tombracer | 0:7613b886e052 | 184 | //http download function, takes url (http://mbed.org/example.wav) |
tombracer | 0:7613b886e052 | 185 | //and target file (/sd/example.wav) as parameters |
tombracer | 0:7613b886e052 | 186 | //returns 0 on success and 1 on failure |
tombracer | 0:7613b886e052 | 187 | int dl(char url[], char target[]) { |
tombracer | 0:7613b886e052 | 188 | int result; |
tombracer | 0:7613b886e052 | 189 | HTTPFile f(target); |
tombracer | 0:7613b886e052 | 190 | HTTPResult r = http.get(url, &f); |
tombracer | 0:7613b886e052 | 191 | |
tombracer | 0:7613b886e052 | 192 | if(r==HTTP_OK) { |
tombracer | 0:7613b886e052 | 193 | printf(" HTTP Result OK\n"); |
tombracer | 0:7613b886e052 | 194 | result=0; |
tombracer | 0:7613b886e052 | 195 | } |
tombracer | 0:7613b886e052 | 196 | else { |
tombracer | 0:7613b886e052 | 197 | printf("HTTP Error %d\n", r); |
tombracer | 0:7613b886e052 | 198 | result=1; |
tombracer | 0:7613b886e052 | 199 | }//else |
tombracer | 0:7613b886e052 | 200 | |
tombracer | 0:7613b886e052 | 201 | return result; |
tombracer | 0:7613b886e052 | 202 | }//dl |
tombracer | 0:7613b886e052 | 203 | |
tombracer | 0:7613b886e052 | 204 | |
tombracer | 0:7613b886e052 | 205 | //http get function "surfing the web" |
tombracer | 0:7613b886e052 | 206 | void surf(char url[]) { |
tombracer | 0:7613b886e052 | 207 | HTTPText txt; |
tombracer | 0:7613b886e052 | 208 | |
tombracer | 0:7613b886e052 | 209 | HTTPResult r = http.get(url, &txt); |
tombracer | 0:7613b886e052 | 210 | if(r==HTTP_OK) { |
tombracer | 0:7613b886e052 | 211 | printf("Surfing result :\"%s\"\n", txt.gets()); |
tombracer | 0:7613b886e052 | 212 | }//if |
tombracer | 0:7613b886e052 | 213 | else { |
tombracer | 0:7613b886e052 | 214 | printf("Surfing error %d\n", r); |
tombracer | 0:7613b886e052 | 215 | }//else |
tombracer | 0:7613b886e052 | 216 | }//surf |
tombracer | 0:7613b886e052 | 217 | |
tombracer | 0:7613b886e052 | 218 | |
tombracer | 0:7613b886e052 | 219 | //doorbell interrupt code here |
tombracer | 0:7613b886e052 | 220 | //remember not to put any large operations in the interrupt handler |
tombracer | 0:7613b886e052 | 221 | void dingdong() { |
tombracer | 0:7613b886e052 | 222 | doorint = true; |
tombracer | 0:7613b886e052 | 223 | }//dingdong |
tombracer | 0:7613b886e052 | 224 | |
tombracer | 0:7613b886e052 | 225 | |
tombracer | 0:7613b886e052 | 226 | //load lipsync data from bmf file to array in RAM |
tombracer | 0:7613b886e052 | 227 | void load_lipsync(char syncfile[]) { |
tombracer | 0:7613b886e052 | 228 | printf("Reading lipsync from sd file\n"); |
tombracer | 0:7613b886e052 | 229 | FILE * pFile = fopen (syncfile , "r"); |
tombracer | 0:7613b886e052 | 230 | if (pFile != NULL) { |
tombracer | 0:7613b886e052 | 231 | fgets (lipmoves , 300 , pFile); |
tombracer | 0:7613b886e052 | 232 | printf("Lipmoves file is: %s\n", lipmoves); |
tombracer | 0:7613b886e052 | 233 | fclose (pFile); |
tombracer | 0:7613b886e052 | 234 | }//if |
tombracer | 0:7613b886e052 | 235 | }//lipsync |
tombracer | 0:7613b886e052 | 236 | |
tombracer | 0:7613b886e052 | 237 | |
tombracer | 0:7613b886e052 | 238 | //mouth function is attached to movetick ticker |
tombracer | 0:7613b886e052 | 239 | //and it moves billys mouth when activated |
tombracer | 0:7613b886e052 | 240 | void mouth() { |
tombracer | 0:7613b886e052 | 241 | if(lippos < 300) { |
tombracer | 0:7613b886e052 | 242 | suu1 = 0; |
tombracer | 0:7613b886e052 | 243 | |
tombracer | 0:7613b886e052 | 244 | char tmpmrk; |
tombracer | 0:7613b886e052 | 245 | tmpmrk = lipmoves[lippos]; |
tombracer | 0:7613b886e052 | 246 | int num = atoi(&tmpmrk); |
tombracer | 0:7613b886e052 | 247 | //printf("suu on %d ", num); |
tombracer | 0:7613b886e052 | 248 | suu2 = num; |
tombracer | 0:7613b886e052 | 249 | lippos++; |
tombracer | 0:7613b886e052 | 250 | }//if |
tombracer | 0:7613b886e052 | 251 | }//mouth |
tombracer | 0:7613b886e052 | 252 | |
tombracer | 0:7613b886e052 | 253 | |
tombracer | 0:7613b886e052 | 254 | void body_move(int secs) { |
tombracer | 0:7613b886e052 | 255 | printf("making body move %d",secs); |
tombracer | 0:7613b886e052 | 256 | ruu2 = 1; |
tombracer | 0:7613b886e052 | 257 | wait(secs); |
tombracer | 0:7613b886e052 | 258 | ruu2 = 0; |
tombracer | 0:7613b886e052 | 259 | } |
tombracer | 0:7613b886e052 | 260 | |
tombracer | 0:7613b886e052 | 261 | |
tombracer | 0:7613b886e052 | 262 | //tail flapping function |
tombracer | 0:7613b886e052 | 263 | void tail_flap(int howmany) { |
tombracer | 0:7613b886e052 | 264 | for(int i=0;i<howmany;i++) { |
tombracer | 0:7613b886e052 | 265 | ruu1=1; |
tombracer | 0:7613b886e052 | 266 | wait(0.2); |
tombracer | 0:7613b886e052 | 267 | ruu1=ruu2=0; |
tombracer | 0:7613b886e052 | 268 | wait(0.2); |
tombracer | 0:7613b886e052 | 269 | }//for |
tombracer | 0:7613b886e052 | 270 | wait(0.3); |
tombracer | 0:7613b886e052 | 271 | }//tailflap |
tombracer | 0:7613b886e052 | 272 | |
tombracer | 0:7613b886e052 | 273 | |
tombracer | 0:7613b886e052 | 274 | void play_wave(char *wavname, bool lipmoves) { |
tombracer | 0:7613b886e052 | 275 | |
tombracer | 0:7613b886e052 | 276 | //enable audio amps via relay 1 |
tombracer | 0:7613b886e052 | 277 | relay1=1; |
tombracer | 0:7613b886e052 | 278 | |
tombracer | 0:7613b886e052 | 279 | unsigned chunk_id,chunk_size,channel; |
tombracer | 0:7613b886e052 | 280 | unsigned data,samp_int,i; |
tombracer | 0:7613b886e052 | 281 | short dac_data; |
tombracer | 0:7613b886e052 | 282 | char *slice_buf; |
tombracer | 0:7613b886e052 | 283 | short *data_sptr; |
tombracer | 0:7613b886e052 | 284 | FMT_STRUCT wav_format; |
tombracer | 0:7613b886e052 | 285 | FILE *wavfile; |
tombracer | 0:7613b886e052 | 286 | long slice,num_slices; |
tombracer | 0:7613b886e052 | 287 | DAC_wptr=0; |
tombracer | 0:7613b886e052 | 288 | DAC_rptr=0; |
tombracer | 0:7613b886e052 | 289 | |
tombracer | 0:7613b886e052 | 290 | size_t result; |
tombracer | 0:7613b886e052 | 291 | |
tombracer | 0:7613b886e052 | 292 | for (i=0;i<256;i+=2) { |
tombracer | 0:7613b886e052 | 293 | DAC_fifo[i]=0; |
tombracer | 0:7613b886e052 | 294 | DAC_fifo[i+1]=3000; |
tombracer | 0:7613b886e052 | 295 | } |
tombracer | 0:7613b886e052 | 296 | DAC_wptr=4; |
tombracer | 0:7613b886e052 | 297 | DAC_on=0; |
tombracer | 0:7613b886e052 | 298 | |
tombracer | 0:7613b886e052 | 299 | printf("Playing wave file '%s'\r\n",wavname); |
tombracer | 0:7613b886e052 | 300 | |
tombracer | 0:7613b886e052 | 301 | wavfile=fopen(wavname,"rb"); |
tombracer | 0:7613b886e052 | 302 | if (!wavfile) { |
tombracer | 0:7613b886e052 | 303 | printf("Unable to open wav file '%s'\r\n",wavname); |
tombracer | 0:7613b886e052 | 304 | exit(1); |
tombracer | 0:7613b886e052 | 305 | } |
tombracer | 0:7613b886e052 | 306 | |
tombracer | 0:7613b886e052 | 307 | fread(&chunk_id,4,1,wavfile); |
tombracer | 0:7613b886e052 | 308 | fread(&chunk_size,4,1,wavfile); |
tombracer | 0:7613b886e052 | 309 | while (!feof(wavfile)) { |
tombracer | 0:7613b886e052 | 310 | printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size); |
tombracer | 0:7613b886e052 | 311 | switch (chunk_id) { |
tombracer | 0:7613b886e052 | 312 | case 0x46464952: |
tombracer | 0:7613b886e052 | 313 | fread(&data,4,1,wavfile); |
tombracer | 0:7613b886e052 | 314 | printf("RIFF chunk\r\n"); |
tombracer | 0:7613b886e052 | 315 | printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); |
tombracer | 0:7613b886e052 | 316 | printf(" RIFF type 0x%x\r\n",data); |
tombracer | 0:7613b886e052 | 317 | break; |
tombracer | 0:7613b886e052 | 318 | case 0x20746d66: |
tombracer | 0:7613b886e052 | 319 | fread(&wav_format,sizeof(wav_format),1,wavfile); |
tombracer | 0:7613b886e052 | 320 | printf("FORMAT chunk\r\n"); |
tombracer | 0:7613b886e052 | 321 | printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); |
tombracer | 0:7613b886e052 | 322 | printf(" compression code %d\r\n",wav_format.comp_code); |
tombracer | 0:7613b886e052 | 323 | printf(" %d channels\r\n",wav_format.num_channels); |
tombracer | 0:7613b886e052 | 324 | printf(" %d samples/sec\r\n",wav_format.sample_rate); |
tombracer | 0:7613b886e052 | 325 | printf(" %d bytes/sec\r\n",wav_format.avg_Bps); |
tombracer | 0:7613b886e052 | 326 | printf(" block align %d\r\n",wav_format.block_align); |
tombracer | 0:7613b886e052 | 327 | printf(" %d bits per sample\r\n",wav_format.sig_bps); |
tombracer | 0:7613b886e052 | 328 | if (chunk_size > sizeof(wav_format)) |
tombracer | 0:7613b886e052 | 329 | fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR); |
tombracer | 0:7613b886e052 | 330 | // create a slice buffer large enough to hold multiple slices |
tombracer | 0:7613b886e052 | 331 | slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); |
tombracer | 0:7613b886e052 | 332 | if (!slice_buf) { |
tombracer | 0:7613b886e052 | 333 | printf("Unable to malloc slice buffer"); |
tombracer | 0:7613b886e052 | 334 | exit(1); |
tombracer | 0:7613b886e052 | 335 | } |
tombracer | 0:7613b886e052 | 336 | break; |
tombracer | 0:7613b886e052 | 337 | case 0x61746164: |
tombracer | 0:7613b886e052 | 338 | slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); |
tombracer | 0:7613b886e052 | 339 | if (!slice_buf) { |
tombracer | 0:7613b886e052 | 340 | printf("Unable to malloc slice buffer"); |
tombracer | 0:7613b886e052 | 341 | exit(1); |
tombracer | 0:7613b886e052 | 342 | } |
tombracer | 0:7613b886e052 | 343 | num_slices=chunk_size/wav_format.block_align; |
tombracer | 0:7613b886e052 | 344 | printf("DATA chunk\r\n"); |
tombracer | 0:7613b886e052 | 345 | printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); |
tombracer | 0:7613b886e052 | 346 | printf(" %d slices\r\n",num_slices); |
tombracer | 0:7613b886e052 | 347 | printf(" Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate)); |
tombracer | 0:7613b886e052 | 348 | samp_int=1000000/(wav_format.sample_rate); |
tombracer | 0:7613b886e052 | 349 | printf(" programmed interrupt tick interval=%d\r\n",samp_int); |
tombracer | 0:7613b886e052 | 350 | |
tombracer | 0:7613b886e052 | 351 | // starting up ticker to write samples out -- no printfs until tick.detach is called |
tombracer | 0:7613b886e052 | 352 | if(lipmoves==true) { |
tombracer | 0:7613b886e052 | 353 | lippos = 0; //reset lipmoves position counter |
tombracer | 0:7613b886e052 | 354 | movetick.attach(&mouth, SAYSPEED); |
tombracer | 0:7613b886e052 | 355 | } |
tombracer | 0:7613b886e052 | 356 | tick.attach_us(&dac_out, samp_int); |
tombracer | 0:7613b886e052 | 357 | |
tombracer | 0:7613b886e052 | 358 | DAC_on=1; |
tombracer | 0:7613b886e052 | 359 | for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) { |
tombracer | 0:7613b886e052 | 360 | |
tombracer | 0:7613b886e052 | 361 | result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile); |
tombracer | 0:7613b886e052 | 362 | if (feof(wavfile)) { |
tombracer | 0:7613b886e052 | 363 | printf("Oops -- not enough slices in the wave file\r\n"); |
tombracer | 0:7613b886e052 | 364 | |
tombracer | 0:7613b886e052 | 365 | break; |
tombracer | 0:7613b886e052 | 366 | } |
tombracer | 0:7613b886e052 | 367 | |
tombracer | 0:7613b886e052 | 368 | data_sptr=(short *)slice_buf; |
tombracer | 0:7613b886e052 | 369 | for (i=0;i<SLICE_BUF_SIZE;i++) { |
tombracer | 0:7613b886e052 | 370 | dac_data=0; |
tombracer | 0:7613b886e052 | 371 | |
tombracer | 0:7613b886e052 | 372 | // for a stereo wave file average the two channels. |
tombracer | 0:7613b886e052 | 373 | for (channel=0;channel<wav_format.num_channels;channel++) { |
tombracer | 0:7613b886e052 | 374 | switch (wav_format.sig_bps) { |
tombracer | 0:7613b886e052 | 375 | case 16: |
tombracer | 0:7613b886e052 | 376 | dac_data+=( ((int)(*data_sptr++)) +32768 ); |
tombracer | 0:7613b886e052 | 377 | break; |
tombracer | 0:7613b886e052 | 378 | case 8: |
tombracer | 0:7613b886e052 | 379 | dac_data+=( ((int)(*data_sptr++)) +32768 <<8); |
tombracer | 0:7613b886e052 | 380 | break; |
tombracer | 0:7613b886e052 | 381 | } |
tombracer | 0:7613b886e052 | 382 | } |
tombracer | 0:7613b886e052 | 383 | DAC_fifo[DAC_wptr]=dac_data; |
tombracer | 0:7613b886e052 | 384 | DAC_wptr=(DAC_wptr+1) & 0xff; |
tombracer | 0:7613b886e052 | 385 | while (DAC_wptr==DAC_rptr) { |
tombracer | 0:7613b886e052 | 386 | wait_us(10); |
tombracer | 0:7613b886e052 | 387 | } |
tombracer | 0:7613b886e052 | 388 | } |
tombracer | 0:7613b886e052 | 389 | } |
tombracer | 0:7613b886e052 | 390 | DAC_on=0; |
tombracer | 0:7613b886e052 | 391 | suu1 = suu2 = 0; |
tombracer | 0:7613b886e052 | 392 | tick.detach(); |
tombracer | 0:7613b886e052 | 393 | if(lipmoves==true) { |
tombracer | 0:7613b886e052 | 394 | movetick.detach(); |
tombracer | 0:7613b886e052 | 395 | } |
tombracer | 0:7613b886e052 | 396 | printf("Tickers detached\r\n"); |
tombracer | 0:7613b886e052 | 397 | free(slice_buf); |
tombracer | 0:7613b886e052 | 398 | break; |
tombracer | 0:7613b886e052 | 399 | case 0x5453494c: |
tombracer | 0:7613b886e052 | 400 | printf("INFO chunk, size %d\r\n",chunk_size); |
tombracer | 0:7613b886e052 | 401 | fseek(wavfile,chunk_size,SEEK_CUR); |
tombracer | 0:7613b886e052 | 402 | break; |
tombracer | 0:7613b886e052 | 403 | default: |
tombracer | 0:7613b886e052 | 404 | printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size); |
tombracer | 0:7613b886e052 | 405 | data=fseek(wavfile,chunk_size,SEEK_CUR); |
tombracer | 0:7613b886e052 | 406 | break; |
tombracer | 0:7613b886e052 | 407 | } |
tombracer | 0:7613b886e052 | 408 | fread(&chunk_id,4,1,wavfile); |
tombracer | 0:7613b886e052 | 409 | fread(&chunk_size,4,1,wavfile); |
tombracer | 0:7613b886e052 | 410 | } |
tombracer | 0:7613b886e052 | 411 | printf("++++++++++++ Done with wave file ++++++++++\r\n"); |
tombracer | 0:7613b886e052 | 412 | fclose(wavfile); |
tombracer | 0:7613b886e052 | 413 | |
tombracer | 0:7613b886e052 | 414 | //disable audio amps via relay 1 |
tombracer | 0:7613b886e052 | 415 | relay1=0; |
tombracer | 0:7613b886e052 | 416 | }//play-wave |
tombracer | 0:7613b886e052 | 417 | |
tombracer | 0:7613b886e052 | 418 | |
tombracer | 0:7613b886e052 | 419 | void dac_out() { |
tombracer | 0:7613b886e052 | 420 | if (DAC_on) { |
tombracer | 0:7613b886e052 | 421 | DACout.write_u16(DAC_fifo[DAC_rptr]); |
tombracer | 0:7613b886e052 | 422 | DAC_rptr=(DAC_rptr+1) & 0xff; |
tombracer | 0:7613b886e052 | 423 | }//if |
tombracer | 0:7613b886e052 | 424 | }//dac-out |