Приветствую всех форумчан! Сейчас работаю над одной программой. Программа для записи, обработки звука. Использую звуковую библиотеку Bass вместе с Bass fx. Сейчас делаю возможность записывать голос под музыку. Столкнулся с проблемой при сохранении голосового потока в wav файл. Проблема возникает если в программу загружена музыка. Музыку загружаю так:
| Код | BASS_StreamFree(chan); // free the old stream chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_STREAM_DECODE); //chan типа HSTREAM if (!chan) chan=BASS_MusicLoad(FALSE, file, 0, 0, BASS_MUSIC_RAMP|BASS_MUSIC_PRESCAN|BASS_STREAM_DECODE,0);
// get the current sample rate BASS_ChannelGetAttribute(chan, BASS_ATTRIB_FREQ, &freq); oldfreq = freq;
// create a new stream - decoded & resampled :) if (!(chan=BASS_FX_TempoCreate(chan, BASS_SAMPLE_LOOP|BASS_FX_FREESOURCE))) { Error("Couldn't create a resampled stream!"); BASS_StreamFree(chan); BASS_MusicFree(chan); }
|
Звук записываю так:
| Код | #define BUFSTEP 1500000 // memory allocation unit
int input; // current input source char *recbuf=NULL; // recording buffer DWORD reclen; // recording length
HRECORD rvoice=0; // recording channel HSTREAM voice=0; // playback channel float level=100;
//...........................................................................................
// display error messages void Error(const char *es) { char mes[200]; sprintf(mes,"%s\n(error code: %d)",es,BASS_ErrorGetCode()); MessageBox(win,mes,0,0); }
//...........................................................................................
// buffer the recorded data BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user) { // increase buffer size if needed if ((reclen%BUFSTEP)+length>=BUFSTEP) { recbuf=realloc(recbuf,((reclen+length)/BUFSTEP+1)*BUFSTEP); if (!recbuf) { rvoice=0; Error("Out of memory!"); MESS(IDB_RECORD_VOICE,WM_SETTEXT,0,"Record voice"); return FALSE; // stop recording } } // buffer the data memcpy(recbuf+reclen,buffer,length); reclen+=length; return TRUE; // continue recording }
void StartRecording() { WAVEFORMATEX *wf; if (recbuf) { // free old recording BASS_StreamFree(voice); BASS_MusicFree(voice); voice=0; free(recbuf); recbuf=NULL; EnableWindow(DLGITEM(IDC_PLAY_VOICE),FALSE); // close output device before recording incase of half-duplex device //BASS_Free(); } // allocate initial buffer and make space for WAVE header recbuf=malloc(BUFSTEP); reclen=44; // fill the WAVE header memcpy(recbuf,"RIFF\0\0\0\0WAVEfmt \20\0\0\0",20); memcpy(recbuf+36,"data\0\0\0\0",8); wf=(WAVEFORMATEX*)(recbuf+20); wf->wFormatTag=1; wf->nChannels=2; wf->wBitsPerSample=16; wf->nSamplesPerSec=44100; wf->nBlockAlign=wf->nChannels*wf->wBitsPerSample/8; wf->nAvgBytesPerSec=wf->nSamplesPerSec*wf->nBlockAlign; // start recording @ 44100hz 16-bit stereo if (!(rvoice=BASS_RecordStart(44100,2,0,&RecordingCallback,0))) { Error("Couldn't start recording"); free(recbuf); recbuf=0; return; } MESS(IDB_RECORD_VOICE,WM_SETTEXT,0,"Stop recording"); }
void StopRecording() { BASS_ChannelStop(rvoice); BASS_StreamFree(voice); // free the old stream rvoice=0; MESS(IDB_RECORD_VOICE,WM_SETTEXT,0,"Record voice"); // complete the WAVE header *(DWORD*)(recbuf+4)=reclen-8; *(DWORD*)(recbuf+40)=reclen-44; ofnv.lStructSize=sizeof(ofnv); ofnv.hwndOwner=win; ofnv.nMaxFile=MAX_PATH; ofnv.lpstrFile=v_file; ofnv.Flags=OFN_HIDEREADONLY|OFN_EXPLORER; ofnv.lpstrFilter="WAV files\0*.wav\0All files\0*.*\0\0"; ofnv.lpstrDefExt="wav"; fpv=fopen(v_file,"wb"); fwrite(recbuf,reclen,1,fpv); //вот эта строчка сносит программу. fclose(fpv);
// create a stream from the recording if(voice=BASS_StreamCreateFile(FALSE,"media/voice.wav",0,0,BASS_STREAM_DECODE)) { if(!voice) voice=BASS_MusicLoad(FALSE, "media/voice.wav", 0, 0, BASS_MUSIC_RAMP|BASS_MUSIC_PRESCAN|BASS_STREAM_DECODE,0); EnableWindow(DLGITEM(IDC_PLAY_VOICE),TRUE); // enable "play" button } else EnableWindow(DLGITEM(IDC_PLAY_VOICE),TRUE); // enable "play" button
// get the current sample rate BASS_ChannelGetAttribute(voice, BASS_ATTRIB_FREQ, &v_freq); v_oldfreq = v_freq;
// create a new stream - decoded & resampled :) if (!(voice=BASS_FX_TempoCreate(voice, BASS_SAMPLE_LOOP|BASS_FX_FREESOURCE))) { //MESS(ID_OPEN,WM_SETTEXT,0,"click here to open a file && play it..."); Error("Couldn't create a resampled stream!"); BASS_StreamFree(voice); BASS_MusicFree(voice); }
//BASS_Free(); }
|
Инициализация и девайса записи и самого bass проходит под одним ид, иначе программа ругается на невозможность инициализации девайса записи.
| Код | // initialize default output device if (!BASS_Init(-1,44100,0,win,NULL)) { Error("Can't initialize device"); DestroyWindow(win); }
//.......................................................................
if (!BASS_RecordInit(-1)) { Error("Can't initialize recording device"); DestroyWindow(win); }
BASS_RecordSetInput(BASS_INPUT_TYPE_MIC,0,level); // get info on the input
|
Вылет программы происходит на указанной коментарием строчке во втором листинге. Не могу понять почему программа рушится и вылетает с предложением отправить отчёт. В чём проблема? ЗЫ: звук записывается через микрофон. Программа рушится при вызове функции StopRecording(). |