Фильтрация звука

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Миша1
Сообщения: 3
Зарегистрирован: 19 сен 2014, 21:16

Здравствуйте. Очень нужен ваш совет. В университете задали написать программу фильтрации звука. (удаления шума и лишних гармоник). За основу взял, перевёл и немного изменил готовый пример из bass.dll.

Далее мой план таков:
  1. Считываю сигналы порциями определенной длины
  2. Для каждой "порции" провожу быстрое преобразование Фурье.
  3. В результате получаю массив частот. Из него удаляю лишнее.
  4. Выполняю обратное преобразование Фурье этого массива.
  5. Вывожу график без шумов на экран.
В общем: В режиме реального времени с минимальной задержкой должно строиться 2 графика. Первый - звук с шумами. Второй - звук без шумов. (потом ещё должен быть добавлен график функции автокорреляции... но это потом).

На первом этапе у меня возникли вопросы:
  1. Если я хочу в данной программе организовать считывание сигнала порциями по 4096 байт, то как это лучше реализовать, и какой временной промежуток мне использовать? Какая формула для его расчета мне необходима?
  2. Каким образом организовать данное преобразование звука без потерь при его буферизации и лишних наложений? Как правильно рассчитать время, чтобы между двумя выборками БПП не оказывалось потерянной информации и чтобы одна выборка не накладывалась на другую?
  3. Что в качестве аргументов принимает функция 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);  // начать запись
  }
Пересмотрел кучу тем, но для данного случая ничего не нашел... Да, я тупой, но очень хочу в этом разобраться... а время поджимает.
Только не говорите что как всё плохо :)
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Тема работы со звуком уже когда-то обсуждалась на этом форуме.
Вот посмотри эту ветку http://forum.developing.ru/showthread.p ... ного-гудка


Там как раз используется формула для расчёта размера буфера исходя из времени звучания, частоты дискретизации, числа каналов и т.д.
Ответить