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.
Dependencies: EthernetNetIf mbed
main.cpp
00001 00002 00003 #include "mbed.h" 00004 #include "SDHCFileSystem.h" 00005 #include "HTTPClient.h" 00006 #include "EthernetNetIf.h" 00007 00008 #define SAMPLE_FREQ 40000 00009 #define BUF_SIZE (SAMPLE_FREQ/10) 00010 #define SLICE_BUF_SIZE 1 00011 00012 typedef struct uFMT_STRUCT { 00013 short comp_code; 00014 short num_channels; 00015 unsigned sample_rate; 00016 unsigned avg_Bps; 00017 short block_align; 00018 short sig_bps; 00019 } FMT_STRUCT; 00020 00021 short DAC_fifo[256]; 00022 short DAC_wptr; 00023 short DAC_rptr; 00024 short DAC_on; 00025 00026 DigitalOut led1(LED1); 00027 DigitalOut led2(LED2); 00028 DigitalOut led3(LED3); 00029 DigitalOut led4(LED4); 00030 00031 SDFileSystem sd(p5, p6, p7, p13, "sd"); 00032 00033 EthernetNetIf eth; 00034 HTTPClient http; 00035 00036 void download_bmf(void); 00037 void load_lipsync(char[]); 00038 void mouth(void); 00039 00040 void dac_out(void); 00041 void dingdong(void); 00042 00043 void body_move(int); 00044 void tail_flap(int); 00045 00046 int dl(char[], char[]); 00047 void surf(char[]); 00048 void pollserver(void); 00049 00050 DigitalOut ruu1(p21); //tail 00051 DigitalOut ruu2(p22); //body 00052 DigitalOut suu1(p23); 00053 DigitalOut suu2(p24); 00054 DigitalOut ena(p25); //enable 00055 00056 Ticker tick; 00057 Ticker polltick; 00058 #define POLLINTERVAL 10 //server polling interval in seconds 00059 bool pollfound = false; //flag goes up if there is something to play 00060 00061 AnalogOut DACout(p18); 00062 DigitalOut relay1(p29); 00063 00064 InterruptIn doorbell(p30); 00065 void dummy(void); 00066 00067 void play_wave(char *, bool); 00068 00069 Ticker movetick; //runs the lipsync function 00070 #define SAYSPEED 0.085 //speed of lipsync in seconds 00071 char lipmoves[300]; //array for lipmove bits 00072 int lippos; 00073 00074 bool doorint = false; //doorbell interrupt flag 00075 00076 00077 int main() { 00078 00079 //setup ethernet connection 00080 printf("Setting up ethernet...\n"); 00081 EthernetErr ethErr = eth.setup(); 00082 if(ethErr) { 00083 printf("Error %d in ethernet setup.\n", ethErr); 00084 }//if 00085 00086 printf("Ethernet setup OK\n"); 00087 00088 //putting doorbell pin(p30) in pullup mode so it pulls up the voltage 00089 //between interrupts that pull it down 00090 doorbell.mode(PullUp); 00091 00092 //run interrupt function when detecting a falling edge on p30 00093 doorbell.fall(&dummy); 00094 doorbell.fall(&dingdong); 00095 00096 lippos = 0; 00097 suu1 = suu2 = ruu1 = ruu2 = 0; 00098 ena = 1; //enable L293 chip 00099 00100 //starting http server polling ticker (10 second intervals) 00101 polltick.attach(&pollserver, POLLINTERVAL); 00102 00103 while(1) { 00104 //check if polling flag is up 00105 if(pollfound==true) { 00106 polltick.detach(); 00107 doorbell.fall(&dummy); 00108 00109 //TODO: dl an effect description file or an sfx sound file 00110 00111 //download lipsync file and load it into the array 00112 if(dl("http://192.168.1.2/talk/snd.bmf", "/sd/snd.bmf")==0) { 00113 load_lipsync("/sd/snd.bmf"); 00114 }//inner if 00115 00116 //flap the tail before playing 00117 tail_flap(2); 00118 00119 //play downloaded file (new waveplayer code) 00120 play_wave("/sd/snd.wav", true); 00121 00122 //add event to eventlog (info=type:sender:description) 00123 surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Played%20wavefile%20snd.wav"); 00124 00125 //delete played sound file 00126 surf("http://192.168.1.2/talk/dlok.php?delete=yes"); 00127 00128 //add event to eventlog (info=type:sender:description) 00129 surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Deleted%20wavefile%20snd.wav%20from%20server."); 00130 00131 //reset pollfound flag 00132 pollfound = false; 00133 polltick.attach(&pollserver, POLLINTERVAL); 00134 doorbell.fall(&dingdong); 00135 }//if pollfound 00136 00137 //check if doorbell flag is raised for doorbell press 00138 if(doorint==true) { 00139 printf("Doorbell press detected..\n"); 00140 00141 polltick.detach(); 00142 00143 play_wave("/sd/ns.wav", false); //doorbell sound, no lipmoves 00144 00145 load_lipsync("/sd/tulossa.bmf"); 00146 00147 ruu2 = 1;//raise body 00148 play_wave("/sd/tulossa.wav", true); 00149 ruu2 = 0;//lower body 00150 00151 //add event to eventlog (info=type:sender:description) 00152 surf("http://192.168.1.2/talk/addevent.php?info=info:Billy:Doorbell%20pressed"); 00153 00154 //reattach polling ticker 00155 polltick.attach(&pollserver, POLLINTERVAL); 00156 00157 //reset doorbell interrupt flag 00158 doorint = false; 00159 }//if doorint 00160 }//while 1 00161 00162 }///////////// main ends ////////////////// 00163 00164 //dummy function for the interruptin 'fix' 00165 void dummy() {} 00166 00167 00168 //this function is attached to polltick, and it polls the server 00169 //every 10 seconds looking for something to download and play 00170 void pollserver() { 00171 printf("Attempting download..\n"); 00172 led1 = 1; 00173 00174 //if download is successful, raise flag 00175 if (dl("http://192.168.1.2/talk/snd.wav", "/sd/snd.wav")==0) { 00176 pollfound = true; 00177 polltick.detach(); 00178 }//if dl.. 00179 00180 led1 = 0; 00181 }//pollserver 00182 00183 00184 //http download function, takes url (http://mbed.org/example.wav) 00185 //and target file (/sd/example.wav) as parameters 00186 //returns 0 on success and 1 on failure 00187 int dl(char url[], char target[]) { 00188 int result; 00189 HTTPFile f(target); 00190 HTTPResult r = http.get(url, &f); 00191 00192 if(r==HTTP_OK) { 00193 printf(" HTTP Result OK\n"); 00194 result=0; 00195 } 00196 else { 00197 printf("HTTP Error %d\n", r); 00198 result=1; 00199 }//else 00200 00201 return result; 00202 }//dl 00203 00204 00205 //http get function "surfing the web" 00206 void surf(char url[]) { 00207 HTTPText txt; 00208 00209 HTTPResult r = http.get(url, &txt); 00210 if(r==HTTP_OK) { 00211 printf("Surfing result :\"%s\"\n", txt.gets()); 00212 }//if 00213 else { 00214 printf("Surfing error %d\n", r); 00215 }//else 00216 }//surf 00217 00218 00219 //doorbell interrupt code here 00220 //remember not to put any large operations in the interrupt handler 00221 void dingdong() { 00222 doorint = true; 00223 }//dingdong 00224 00225 00226 //load lipsync data from bmf file to array in RAM 00227 void load_lipsync(char syncfile[]) { 00228 printf("Reading lipsync from sd file\n"); 00229 FILE * pFile = fopen (syncfile , "r"); 00230 if (pFile != NULL) { 00231 fgets (lipmoves , 300 , pFile); 00232 printf("Lipmoves file is: %s\n", lipmoves); 00233 fclose (pFile); 00234 }//if 00235 }//lipsync 00236 00237 00238 //mouth function is attached to movetick ticker 00239 //and it moves billys mouth when activated 00240 void mouth() { 00241 if(lippos < 300) { 00242 suu1 = 0; 00243 00244 char tmpmrk; 00245 tmpmrk = lipmoves[lippos]; 00246 int num = atoi(&tmpmrk); 00247 //printf("suu on %d ", num); 00248 suu2 = num; 00249 lippos++; 00250 }//if 00251 }//mouth 00252 00253 00254 void body_move(int secs) { 00255 printf("making body move %d",secs); 00256 ruu2 = 1; 00257 wait(secs); 00258 ruu2 = 0; 00259 } 00260 00261 00262 //tail flapping function 00263 void tail_flap(int howmany) { 00264 for(int i=0;i<howmany;i++) { 00265 ruu1=1; 00266 wait(0.2); 00267 ruu1=ruu2=0; 00268 wait(0.2); 00269 }//for 00270 wait(0.3); 00271 }//tailflap 00272 00273 00274 void play_wave(char *wavname, bool lipmoves) { 00275 00276 //enable audio amps via relay 1 00277 relay1=1; 00278 00279 unsigned chunk_id,chunk_size,channel; 00280 unsigned data,samp_int,i; 00281 short dac_data; 00282 char *slice_buf; 00283 short *data_sptr; 00284 FMT_STRUCT wav_format; 00285 FILE *wavfile; 00286 long slice,num_slices; 00287 DAC_wptr=0; 00288 DAC_rptr=0; 00289 00290 size_t result; 00291 00292 for (i=0;i<256;i+=2) { 00293 DAC_fifo[i]=0; 00294 DAC_fifo[i+1]=3000; 00295 } 00296 DAC_wptr=4; 00297 DAC_on=0; 00298 00299 printf("Playing wave file '%s'\r\n",wavname); 00300 00301 wavfile=fopen(wavname,"rb"); 00302 if (!wavfile) { 00303 printf("Unable to open wav file '%s'\r\n",wavname); 00304 exit(1); 00305 } 00306 00307 fread(&chunk_id,4,1,wavfile); 00308 fread(&chunk_size,4,1,wavfile); 00309 while (!feof(wavfile)) { 00310 printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size); 00311 switch (chunk_id) { 00312 case 0x46464952: 00313 fread(&data,4,1,wavfile); 00314 printf("RIFF chunk\r\n"); 00315 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); 00316 printf(" RIFF type 0x%x\r\n",data); 00317 break; 00318 case 0x20746d66: 00319 fread(&wav_format,sizeof(wav_format),1,wavfile); 00320 printf("FORMAT chunk\r\n"); 00321 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); 00322 printf(" compression code %d\r\n",wav_format.comp_code); 00323 printf(" %d channels\r\n",wav_format.num_channels); 00324 printf(" %d samples/sec\r\n",wav_format.sample_rate); 00325 printf(" %d bytes/sec\r\n",wav_format.avg_Bps); 00326 printf(" block align %d\r\n",wav_format.block_align); 00327 printf(" %d bits per sample\r\n",wav_format.sig_bps); 00328 if (chunk_size > sizeof(wav_format)) 00329 fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR); 00330 // create a slice buffer large enough to hold multiple slices 00331 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); 00332 if (!slice_buf) { 00333 printf("Unable to malloc slice buffer"); 00334 exit(1); 00335 } 00336 break; 00337 case 0x61746164: 00338 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); 00339 if (!slice_buf) { 00340 printf("Unable to malloc slice buffer"); 00341 exit(1); 00342 } 00343 num_slices=chunk_size/wav_format.block_align; 00344 printf("DATA chunk\r\n"); 00345 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); 00346 printf(" %d slices\r\n",num_slices); 00347 printf(" Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate)); 00348 samp_int=1000000/(wav_format.sample_rate); 00349 printf(" programmed interrupt tick interval=%d\r\n",samp_int); 00350 00351 // starting up ticker to write samples out -- no printfs until tick.detach is called 00352 if(lipmoves==true) { 00353 lippos = 0; //reset lipmoves position counter 00354 movetick.attach(&mouth, SAYSPEED); 00355 } 00356 tick.attach_us(&dac_out, samp_int); 00357 00358 DAC_on=1; 00359 for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) { 00360 00361 result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile); 00362 if (feof(wavfile)) { 00363 printf("Oops -- not enough slices in the wave file\r\n"); 00364 00365 break; 00366 } 00367 00368 data_sptr=(short *)slice_buf; 00369 for (i=0;i<SLICE_BUF_SIZE;i++) { 00370 dac_data=0; 00371 00372 // for a stereo wave file average the two channels. 00373 for (channel=0;channel<wav_format.num_channels;channel++) { 00374 switch (wav_format.sig_bps) { 00375 case 16: 00376 dac_data+=( ((int)(*data_sptr++)) +32768 ); 00377 break; 00378 case 8: 00379 dac_data+=( ((int)(*data_sptr++)) +32768 <<8); 00380 break; 00381 } 00382 } 00383 DAC_fifo[DAC_wptr]=dac_data; 00384 DAC_wptr=(DAC_wptr+1) & 0xff; 00385 while (DAC_wptr==DAC_rptr) { 00386 wait_us(10); 00387 } 00388 } 00389 } 00390 DAC_on=0; 00391 suu1 = suu2 = 0; 00392 tick.detach(); 00393 if(lipmoves==true) { 00394 movetick.detach(); 00395 } 00396 printf("Tickers detached\r\n"); 00397 free(slice_buf); 00398 break; 00399 case 0x5453494c: 00400 printf("INFO chunk, size %d\r\n",chunk_size); 00401 fseek(wavfile,chunk_size,SEEK_CUR); 00402 break; 00403 default: 00404 printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size); 00405 data=fseek(wavfile,chunk_size,SEEK_CUR); 00406 break; 00407 } 00408 fread(&chunk_id,4,1,wavfile); 00409 fread(&chunk_size,4,1,wavfile); 00410 } 00411 printf("++++++++++++ Done with wave file ++++++++++\r\n"); 00412 fclose(wavfile); 00413 00414 //disable audio amps via relay 1 00415 relay1=0; 00416 }//play-wave 00417 00418 00419 void dac_out() { 00420 if (DAC_on) { 00421 DACout.write_u16(DAC_fifo[DAC_rptr]); 00422 DAC_rptr=(DAC_rptr+1) & 0xff; 00423 }//if 00424 }//dac-out
Generated on Fri Jul 15 2022 01:34:56 by
1.7.2