Здравствуйте. Очень нужен ваш совет. В университете задали написать программу фильтрации звука. (удаления шума и лишних гармоник). За основу взял, перевёл и немного изменил готовый пример из bass.dll.
Далее мой план таков:
- Считываю сигналы порциями определенной длины
- Для каждой "порции" провожу быстрое преобразование Фурье.
- В результате получаю массив частот. Из него удаляю лишнее.
- Выполняю обратное преобразование Фурье этого массива.
- Вывожу график без шумов на экран.
В общем: В режиме реального времени с минимальной задержкой должно строиться 2 графика. Первый - звук с шумами. Второй - звук без шумов. (потом ещё должен быть добавлен график функции автокорреляции... но это потом)
На первом этапе у меня возникли следующие вопросы:
- Если я хочу в данной программе организовать считывание сигнала порциями по 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); // начать запись
}
Пересмотрел кучу тем, но для данного случая ничего не нашел... Да, я тупой, но очень хочу в этом разобраться...
Только не говорите что как всё плохо :)