struct RIFF { char rID[4]; DWORD rLen; } riff; struct FORMAT { char fID[4]; DWORD fLen; WORD wTag; WORD wChannel; DWORD nSample; DWORD nByte; WORD align; WORD sample; }; struct DATA { char dID[4]; DWORD dLen; }; struct WAVE { char wID[4]; struct FORMAT fmt; struct DATA data; } wave; char error[80]; // description of error, if any int abortflag; // Watch the cancel button #pragma argsused BOOL CALLBACK StatusDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp) { if (msg==WM_INITDIALOG) { SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT)); CenterWindow(hdlg); } if (msg==WM_COMMAND && wp==IDCANCEL) abortflag=1; return 0; } // Write out a block of sound data, do some processing if necessary. // Return 0:failure, otherwise: bytes written. WORD wavwrite(signed int *sample,WORD len,FILE *f) { if (hz44) { if (stereo) { // 44khz stereo: no processing needed if (fwrite(sample,len,1,f)==1) return len; } else { // 44khz mono: calculate left/right channel average, then write WORD nsamples; signed int *src=sample,*dst=sample; nsamples=len>>2; while (nsamples--) { *dst=(WORD)(((DWORD)*src+*(src+1))>>1); src+=2; dst++; } if (fwrite(sample,len>>1,1,f)==1) return len>>1; } } else { if (stereo) { // 22khz stereo: condense samples (write only samples 0, 2, 4 etc) WORD nsamples; DWORD *src=(DWORD *)sample,*dst=(DWORD *)sample; nsamples=len>>3; while (nsamples--) { *dst=*src; dst++; src+=2; } if (fwrite(sample,len>>1,1,f)==1) return len>>1; } else { if (bit16) {// 22khz mono 16bits WORD nsamples; signed int *src=sample,*dst=sample; nsamples=len>>3; while (nsamples--) { *dst=(WORD)(((DWORD)*src+*(src+1))>>1); src+=4; dst++; } if (fwrite(sample,len>>2,1,f)==1) return len>>2; } else { // 22 khz mono 8 bits WORD nsamples; signed int *src=sample; signed char *dst=sample; nsamples=len>>3; while (nsamples--) { *dst=128+HIBYTE((WORD)(((DWORD)*src+*(src+1))>>1)); src+=4; dst++; } if (fwrite(sample,len>>3,1,f)==1) return len>>3; } } } return 0; } int record(char *image,DWORD startloc,DWORD size) { int first_time,i,bps; WORD offset,synch_size,written; DWORD end_pos,loc=startloc; FILE *f; HWND status; MSG msg; // Put up a modal dialog box (for status) abortflag=0; status=CreateDialog(hinst,"StatusDlg",0,StatusDlgProc); if (!status) { strcpy(error,"Cant create status window"); return 0; } strcpy(error,""); // Create WAV file f=fopen(image,"wb"); if (!f) { strcpy(error,"cant create file"); return 0; } // Prepare RIFF+WAV header bps=1; // bytes per sample - for a 8 bit mono sample if (bit16) bps<<=1; // two times as much for 16 bit samples if (stereo) bps<<=1; // another 2x as much for stereo strcpy(riff.rID, "RIFF"); riff.rLen = FRAME_SIZE * (DWORD)size + sizeof(struct WAVE); strcpy(wave.wID, "WAVE"); strcpy(wave.fmt.fID, "fmt "); wave.fmt.fLen = sizeof(struct FORMAT) - 8; wave.fmt.wTag = 1; wave.fmt.wChannel = stereo?2:1; // nr of channels wave.fmt.nSample = hz44?44100L:22050L; // sample rate wave.fmt.nByte = (hz44?44100L:22050L) * bps; // avg dataspeed bytes/sec wave.fmt.align = bps; // size of one sample, in bytes wave.fmt.sample = bit16?16:8; // bits per sample strcpy(wave.data.dID, "data"); wave.data.dLen = FRAME_SIZE * (DWORD)size; if (fwrite(&riff,sizeof(struct RIFF),1,f)!=1) { strcpy(error,"cant write to file (disk full?)"); goto Errorexit; } if (fwrite(&wave,sizeof(struct WAVE),1,f)!=1) { strcpy(error,"cant write to file (disk full?)"); goto Errorexit; } // Read the data in blocks, first in memory // loc: start position (sierra sector) // size: number of sectors to read // end_loc: sector number at where to end wave.data.dLen = 0L; first_time = 1; end_pos = loc+size; while (loc4096) { strcpy(error,"Synchronisation failed. Retry the operation. Close some other programs, if possible."); goto Errorexit; } offset=0; break; } } } if (offset==0) { strcpy(error,"Synchronisation failed, no matching block. Retry the operation. Close some other programs, if possible."); goto Errorexit; } } } else offset = 0; first_time=0; memcpy(pprev_end,pbuf[nbuf-1],(WORD)((DWORD)FRAME_SIZE*NBLOCK)); // Write all buffers to disk, except the last buffer for (i=0;i