Далее мой план таков:
- Считываю сигналы порциями определенной длины
- Для каждой "порции" провожу быстрое преобразование Фурье.
- В результате получаю массив частот. Из него удаляю лишнее.
- Выполняю обратное преобразование Фурье этого массива.
- Вывожу график без шумов на экран.
На первом этапе у меня возникли вопросы:
- Если я хочу в данной программе организовать считывание сигнала порциями по 4096 байт, то как это лучше реализовать, и какой временной промежуток мне использовать? Какая формула для его расчета мне необходима?
- Каким образом организовать данное преобразование звука без потерь при его буферизации и лишних наложений? Как правильно рассчитать время, чтобы между двумя выборками БПП не оказывалось потерянной информации и чтобы одна выборка не накладывалась на другую?
- Что в качестве аргументов принимает функция RecordingCallback?
Код: Выделить всё
#define FREQ 44100 // частота дискретизации
#define BUFSTEP 200000 // блок распределения памяти
#define CHANS 1 // количество каналов
char *recbuf=NULL; // буфер записи
int reclen; // длина записи
HRECORD rchan=0; // канал записи
HSTREAM chan=0; // канал воспроизведения
BOOL CALLBACK RecordingCallback(HRECORD handle, const void *buffer, DWORD length, void *user) //вызывается каждые 100 мс.
{
if ((reclen%BUFSTEP)+length>=BUFSTEP) // увеличить размер буфера при необходимости
{
recbuf = (char *)realloc(recbuf,((reclen+length)/BUFSTEP+1)*BUFSTEP);
if (!recbuf)
{
rchan=0;
return FALSE; // стоп
}
}
memcpy(recbuf+reclen,buffer,length); // буфер данных
reclen+=length;
return TRUE; // продолжить запись
}
void StartRecording()
{
WAVEFORMATEX *wf;
if(recbuf)
{
BASS_StreamFree(chan); // освободить старый канал
chan=0;
free(recbuf);
recbuf=NULL;
BASS_Free();
}
recbuf=(char *)malloc(BUFSTEP); // выделить персональный буфер и освободить место для заголовка
reclen=44;
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=CHANS; // количество каналов аудиоданных
wf->wBitsPerSample=16; // количество бит на сэмпл
wf->nSamplesPerSec=FREQ; // частота дискретизации
wf->nBlockAlign=wf->nChannels*wf->wBitsPerSample/8; // выравнивание блока в байтах
wf->nAvgBytesPerSec=wf->nSamplesPerSec*wf->nBlockAlign; // скорость передачи данных в байтах в секунду
rchan = BASS_RecordStart(FREQ,CHANS,0,RecordingCallback,0); // начать запись
}
Только не говорите что как всё плохо
