Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.129.247.196] |
|
Страницы: (3) 1 2 [3] все ( Перейти к последнему сообщению ) |
Сообщ.
#31
,
|
|
|
Вывод: в буфере ничего не "затирается".
|
Сообщ.
#32
,
|
|
|
Переделал свою прг как вы советуете (добавил 2й буфер). Теперь стыков гораздо меньше, но они все равно проскакивают. Пока эту проблему решу анализом массива. Если стык есть - просто выюрасываем этот буфер и ждем следующего.
Спасибо! |
Сообщ.
#33
,
|
|
|
Цитата Теперь стыков гораздо меньше, но они все равно проскакивают. Запишите сигнал в звуковом редакторе. Если в нём присуствуют "стыки", значит, на входе звуковой карты такой сигнал. Вставьте в OnwaveIn запись буферов в файл, и таким способом запишите звук из своей программы. Проанализируйте запись в том же редакторе, сравните. Лучше найти причину глюка, и если она програмная, переписать программу по-человечески, чем костыли для игнорирования глюка изобретать. Имхо. |
Сообщ.
#34
,
|
|
|
Длительность буфера какая?
|
Сообщ.
#35
,
|
|
|
Ок. Сигнал был записан с помощью стандартной программы виндов "звукозапись", воспроизводилась через Винамп. Чтоб исключить возможную порчу звука Винампом сделано как вы советуете.
Из OnWaveIn выброшено все, добавлена только запись в файл. Используем 2 буфера, звук подаем на вход микрофона, я в него дышал, чтоб низкую частоту получить) После быстренько накалякал программу чтения из ВАВа. Читаем то, что записали в файл - Оппа, стыки идут! Прикреплённый файлtest.jpg (26 Кбайт, скачиваний: 693) |
Сообщ.
#36
,
|
|
|
Длительность (длина буфера) - 1024точки. Пробовал 2048 и т.д. до 16000 - не меняется ничего. Стык то есть, то нет. И если есть - то он обычно в начале буфера, со смещением 50-200 точек.
Частоту дискретизации ставил от 4000 до 44100. |
Сообщ.
#37
,
|
|
|
Из опыта, длительность буфера должна быть не менее 100 - 200 мс, иначе будут потери в данных.
Прикреплённый файлwavein.rar (12,04 Кбайт, скачиваний: 326) |
Сообщ.
#38
,
|
|
|
Цитата IvanB @ Переделал под себя - не работает как надо. Видимо мой обработчик довольно долгий (выполняется преобразование Фурье, поиск в каждом канале сигнала "пиков", расчет фаз и вывод на экран) и буфер все равно успевает переполняться. А не нужно все это делать в обработчике. Тем более, что сами пишете - непрерывный поток не нужен. Обработчик должен схватить буфер и либо скопировать его, скажем, в закольцованную очередь, либо выяснить, готов ли его кто обрабатывать, и если не готов - игнорировать. А программа обработки, соответственно, должна либо искать последний готовый буфер в очереди, освобождая все прочие в первом варианте, либо по завершении обработки выставлять флаг готовности и ждать, пока обработчик выплюнет очередной буфер. |
Сообщ.
#39
,
|
|
|
Цитата Обработчик должен схватить буфер и либо скопировать его, скажем, в закольцованную очередь, либо выяснить, готов ли его кто обрабатывать, и если не готов - игнорировать. Зачем ещё одна очередь, если она уже есть. |
Сообщ.
#40
,
|
|
|
andriano, так буфер в обработчике изначально находится в непотребном состоянии, с искажениями.
Только что проверил свою программу дома, на стационарном компе. Все работает как надо! Нет никаких наложений даже с одним буфером, при любой его длине (выставлял даже 256точек, 44100 дискретность). Но не работает нормально на ноутбуке на работе и на ноутбуке в гараже (в гараже старенький Тошиба, на работе свежий Асер). Такие вот пироги |
Сообщ.
#41
,
|
|
|
IvanB, вопрос, вероятно, не в том, стационарный комп или ноутбук, а в том, какой стоит звуковой чип и, соответственно, его возможности - что он делает аппаратно, а что перекладывает на процессор для программной обработки.
Любая правильно написанная программа надежно работает на любом железе. Если с Вашей программой этого не происходит, значит, она написана неправильно, а то, что она работает, говорит о том, что "железо" стационарного компа исправляет Ваши ошибки. Следовательно, Вы что-то изначально неверно организуете, и Вам нужно не удивляться, почему программа, которая кое-где работает, работает не везде, а исправлять ее так, чтобы она работала на наиболее неблагоприятной для нее конфигурации. "буфер в обработчике изначально находится в непотребном состоянии, с искажениями" - это неверная посылка. Если буфер у Вас оказывается в таком состоянии, значит, где-то Вы сами его портите. Либо что-то неправильное делаете с системой, что заставляет ее портить Ваш буфер. Добавлено Цитата Prince @ Зачем ещё одна очередь, если она уже есть. Затем, что вторая очередь не будет совпадать с первой. Они будут по-разному обрабатываться и их элементы будут по-разному освобождаться. |
Сообщ.
#42
,
|
|
|
Цитата Затем, что вторая очередь не будет совпадать с первой. Они будут по-разному обрабатываться и их элементы будут по-разному освобождаться. Так зачем это нужно? Чем не устривает та очередь, что уже есть? |
Сообщ.
#43
,
|
|
|
Цитата выставлял даже 256точек, 44100 дискретность Выставьте 256 точек(6 мс), 1024(23 мс), 2048(46 мс) и 4096(92 мс) и сравните загрузку процессора. Допустите, что ваша программа выполняется на старенькой машине, параллельно с другими задачами, тоже требующими процессорного времени. |
Сообщ.
#44
,
|
|
|
Prince, исправил в своей программе "инициализацию" буферов, что-то связанное с выделением памяти. Сделал как у вас в WaveIn.
До этого было так type BufHead1,BufHead2: TWaveHdr; adress:PWaveHdr; header: TWaveFormatEx; buf: pointer; СтартБаттонКлик begin with header do begin wFormatTag := WAVE_FORMAT_PCM; nChannels := 2; { количество каналов } nSamplesPerSec := SpS; { частота } wBitsPerSample := 16; { 8 / 16 бит } nBlockAlign := nChannels * (wBitsPerSample div 8); nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; cbSize := 0; end; WaveInOpen(Addr(WaveIn), WAVE_MAPPER, addr(header),Form1.Handle, 0, CALLBACK_WINDOW); BufLen := header.nBlockAlign * BufSize; hBuf := GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE, BufLen); Buf := GlobalLock(hBuf); with BufHead1 do begin lpData := Buf; dwBufferLength := BufLen; dwFlags := 0;//WHDR_DONE;//BEGINLOOP; dwLoops:=0; end; adress:=@BufHead1; with BufHead2 do begin lpData := Buf; dwBufferLength := BufLen; dwFlags := 0;//WHDR_DONE;//BEGINLOOP; dwLoops:=0; end; WaveInPrepareHeader(WaveIn, Addr(BufHead1), sizeof(TWaveHdr)); WaveInPrepareHeader(WaveIn, Addr(BufHead2), sizeof(TWaveHdr)); WaveInAddBuffer(WaveIn, adress, sizeof(BufHead1)); WaveInStart(WaveIn); Переделал в такое with header do begin wFormatTag := WAVE_FORMAT_PCM; nChannels := 2; nSamplesPerSec := SpS; wBitsPerSample := 16; nBlockAlign := nChannels * (wBitsPerSample div 8); nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; cbSize := 0; end; WaveInOpen(Addr(WaveIn), WAVE_MAPPER, addr(header),Form1.Handle, 0, CALLBACK_WINDOW); BufLen := header.nBlockAlign * BufSize; adress:=allocmem(sizeof(TWAVEHDR)); adress.lpData := allocmem(BufLen); adress.dwBufferLength := BufLen; WaveInPrepareHeader(WaveIn, adress, sizeof(TWaveHdr)); WaveInAddBuffer(WaveIn, adress, sizeof(TWaveHdr)); adress:=allocmem(sizeof(TWAVEHDR)); adress.lpData := allocmem(BufLen); adress.dwBufferLength := BufLen; WaveInPrepareHeader(WaveIn, adress, sizeof(TWaveHdr)); WaveInAddBuffer(WaveIn, adress, sizeof(TWaveHdr)); WaveInStart(WaveIn); Стало работать без ошибок! Вечером еще на старом буке надо проверить. Выделение буферов сейчас сделано как у вас в программе, здесь просто приведен пример того, что исправлено. Спасибо! зы: пока писал ответ, помоему понял ошибку. В первом случае я 1 раз выделил память (строки 21-22) и дальше писал по одному и тому же адресу 2 буфера. |
Сообщ.
#45
,
|
|
|
Доброго!
Писать звук с 2х каналов научили . Теперь хотелки выросли и нужно записать 4 канала на том же железе. Имеем встроенную звуковую систему АС97 на чипе Alc201, т.е. 2х канальное стерео. АЦП имеет частоту дискретизации 48кГц и 4 пары каналов записи. Задача - получить 4х канальный сигнал с полезной частотой не превышающей 3кГц, синхронизированный во времени. Идея следующая. Запрограммировать длину буфера весьма короткой (1, 2 или 4 отсчета). Получить от АЦП выборку 1й пары каналов, скинуть ее в буфер1. Потом переключить запись на другую пару каналов и получить выборку с нее, сбросить ее в буфер2. Получится ли таким образом записать "одновременно" 4 канала? Или потрачу много времени на переключение каналов? |