Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.11.2014, 20:37   #1
Миша52
 
Регистрация: 19.09.2014
Сообщений: 6
Лампочка Обработка звука на C++

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

Последний раз редактировалось Миша52; 03.11.2014 в 20:42.
Миша52 вне форума Ответить с цитированием
Старый 03.11.2014, 20:58   #2
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Цитата:
Сообщение от Миша52 Посмотреть сообщение
Если я хочу в данной программе организовать считывание сигнала порциями по 4096 байт, то как это лучше реализовать, и какой временной промежуток мне использовать? Какая формула для его расчета мне необходима?
Каким образом организовать данное преобразование звука без потерь при его буферизации и лишних наложений? Как правильно рассчитать время, чтобы между двумя выборками БПП не оказывалось потерянной информации и чтобы одна выборка не накладывалась на другую?
Не факт, что 4096 байт это лучшее решение. Для того чтобы правильно определить размер "порции" необходимо отталкиваться от структуры аудиоданных. Вот описание для WAV.
Цитата:
Сообщение от Миша52 Посмотреть сообщение
Что в качестве аргументов принимает функция RecordingCallback?
В комплекте с библиотекой bass помимо примеров идёт и документация по ней. В ней всё подробно расписано.
Streletz вне форума Ответить с цитированием
Старый 03.11.2014, 21:20   #3
Миша52
 
Регистрация: 19.09.2014
Сообщений: 6
По умолчанию

Цитата:
Сообщение от Streletz Посмотреть сообщение
В комплекте с библиотекой bass помимо примеров идёт и документация по ней. В ней всё подробно расписано.
Например, length - это число байт в буфере. Как я понял, этот параметр принимает значение аргумента, объявленного внутри самой функции BASS_RecordStart(...)?
Из справки я не совсем это понял...
За статью большое спасибо. Буду изучать.

Последний раз редактировалось Миша52; 03.11.2014 в 21:22.
Миша52 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка звука в Delphi Vadymus Мультимедиа в Delphi 3 31.07.2014 11:26
Три задачи на Delphi (Паскаль): обработка строк, обработка множеств, работа с типизированным файлом Тедеев Помощь студентам 11 13.12.2013 13:38
Обработка звука алексей111 Мультимедиа в Delphi 2 11.05.2012 22:55
Захват звука, Обработка(пре-амп), и вывод f1re Мультимедиа в Delphi 5 23.08.2011 19:58
Обработка звука(С++) Скарам Помощь студентам 1 29.11.2009 17:02