- DSР (15)
- Нейронні мережі (1)
- Цифрова обробка аудіо (14)
Хмара рубрик
Знайшли помилку на сторінці?
Виділіть помилку та натисніть
Як відтворити безперервні звукові дані?
Початківцю не одразу стане ясно, що саме тут відбувається. Тож я поясню. Насамперед потрібно ініціалізувати бібліотеку, викликавши функціюPa_Initialize().
Далі необхідно отримати звуковий пристрій, викликавши функціюPa_GetDefaultOutputDevice().
Якщо пристрій отримано без помилки, тоді можна розпочати його налаштування. Для цього необхідно заповнити структуруoutputParameters.
Коли все це зроблено, можна переходити до найцікавішого, а саме до відкриття (Pa_OpenStream(…) ) та запуску (Pa_StartStream(…) ) потоку відтворення.
Напевно, на цьому етапі не зовсім зрозуміло, куди і де ми передаватимемо наші звукові вибірки. Тут все просто… Відкриваючи потік викликом функціїPa_OpenStream(...) ми передаємо в цю функцію покажчик на функціюpatestCallback(...), яку смикатиме драйвер аудіопристрою (нехай це звучить так) коли йому потрібні нові дані. Так ось, у цій функції ми й генеруватимемо і передаватимемо драйверу наші аудіовибірки. Як генерувати та записувати вибірки в лівий та правий канали, можна подивитися тут:
Тут ми генеруємо вибірку функцією синуса із стандартної математичної бібліотеки. ЗначенняtimeTmp постійно збільшується до тих пір, поки не переступить максимальне собі значення і знову стане нулем.Канали в буфері чергуються один за одним для кожного семпла. В даному випадку ми маємо лише 2 канали, тому і зрушуємо покажчикout на буфер лише 2 рази.
Для завершення роботи з бібліотекою ми повинні закрити потік відтворення викликавши функціюPa_CloseStream(…) після чого можна зупинити роботу і самої бібліотеки викликавшиPa_Terminate().
Ось, власне, і все, що необхідно знати під час роботи з бібліотекою«Portaudio» на початковому етапі!
На завершення, я хотів би сказати, що це всього-на-всього приклад і деякі речі робити так як в цьому проекті небажано, наприклад виділяти або видаляти пам'ять всередині функціїpatestCallback(…). Крім цього робити громіздкі обчислення тут теж небажано. Конкретно в нашому випадку, у випадку цього прикладу я знаю, що за час між сусідніми викликами функціїpatestCallback(...) ми однозначно встигаємо розрахувати значення для нової вибірки. Якщо потрібно робити більш громіздкі обчислення, тоді можна скористатися логікою багатопоточних додатків і, наприклад, буфером FIFO. Але це вже зовсім інша історія.
Мені залишається найголовніше – викласти вихідний код проекту:). Ось він, дорогі друзі: