На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела "Программирование звука"
0) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с записью, обработкой, воспроизведением звука. Перед созданием темы подумайте, не будет ли она уместнее в разделах Разработка и тестирование программ, Наши исходники, а особенно Разовые заказы и подработки
1) На Раздел распространяются все Правила форума.Огромная просьба с ними внимательно ознакомиться.
2) Запрещается давать бессмысленные ответы вроде: "Снеси Мастдай", "ХП рулит", "Поставь Линукс" и т.д.
3) Запрещается создавать темы, в которых Вы намереваетесь получить ссылку на кряки, серийники и т.п. Также запрещено любое обсуждение p2p (peer-to-peer) сетей (BitTorrent, eDonkey и т.д.).
4) Реклама всякого рода пресекается беспощадно.
5) Используйте тэг [CODE] для выделения кода программы (непременно с указанием языка программирования - выбрать из списка. В противном случае бессмысленно!). Уважайте тех, кто будет читать ваш код!
6) Если решение вашей проблемы найдено, то не забываем помечать тему специальной функцией "Вопрос решён". Вам всего лишь требуется при написании последнего ответа поставить одну единственную галочку прямо над формой ответа.
7) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе

8) Если не прикрепляются/не скачиваются файлы, читаем Не прикрепляется / не скачивается файл. Любые обсуждения в данном разделе проблем с приложением файлов считаются оффтопиком! Со всеми вытекающими.

9) NEW! Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно. Попытки накрутки количества тематических сообщений за счёт поднятия древних неактуальных тем ("некрофилия") будут наказываться по велению левой пятки модераторского состава (см. пп.12, 13 Правил)



Нарушение Правил может повлечь наказание со стороны модераторов.



user posted imageFAQ Раздела user posted imageПоиск в Разделе user posted imageMSDN Library Online | Ваше мнение о модераторах: user posted imageBarazuk user posted imageRikkie
Страницы: (3) 1 2 [3]  все  ( Перейти к последнему сообщению )  
> Работа со звуком с помощью MMSystem
    Вывод: в буфере ничего не "затирается".
    Сообщение отредактировано: Prince -
      Переделал свою прг как вы советуете (добавил 2й буфер). Теперь стыков гораздо меньше, но они все равно проскакивают. Пока эту проблему решу анализом массива. Если стык есть - просто выюрасываем этот буфер и ждем следующего.
      Спасибо!
        Цитата
        Теперь стыков гораздо меньше, но они все равно проскакивают.

        Запишите сигнал в звуковом редакторе. Если в нём присуствуют "стыки", значит, на входе звуковой карты такой сигнал.
        Вставьте в OnwaveIn запись буферов в файл, и таким способом запишите звук из своей программы. Проанализируйте запись в том же редакторе, сравните.
        Лучше найти причину глюка, и если она програмная, переписать программу по-человечески, чем костыли для игнорирования глюка изобретать. Имхо.
          Длительность буфера какая?
            Ок. Сигнал был записан с помощью стандартной программы виндов "звукозапись", воспроизводилась через Винамп. Чтоб исключить возможную порчу звука Винампом сделано как вы советуете.
            Из OnWaveIn выброшено все, добавлена только запись в файл. Используем 2 буфера, звук подаем на вход микрофона, я в него дышал, чтоб низкую частоту получить)
            После быстренько накалякал программу чтения из ВАВа.
            Читаем то, что записали в файл - Оппа, стыки идут!
            Прикреплённый файлПрикреплённый файлtest.jpg (26 Кбайт, скачиваний: 691)
              Длительность (длина буфера) - 1024точки. Пробовал 2048 и т.д. до 16000 - не меняется ничего. Стык то есть, то нет. И если есть - то он обычно в начале буфера, со смещением 50-200 точек.
              Частоту дискретизации ставил от 4000 до 44100.
                Из опыта, длительность буфера должна быть не менее 100 - 200 мс, иначе будут потери в данных.
                Прикреплённый файлПрикреплённый файлwavein.rar (12,04 Кбайт, скачиваний: 323)
                Сообщение отредактировано: Prince -
                  Цитата IvanB @
                  Переделал под себя - не работает как надо. Видимо мой обработчик довольно долгий (выполняется преобразование Фурье, поиск в каждом канале сигнала "пиков", расчет фаз и вывод на экран) и буфер все равно успевает переполняться.

                  А не нужно все это делать в обработчике. Тем более, что сами пишете - непрерывный поток не нужен.
                  Обработчик должен схватить буфер и либо скопировать его, скажем, в закольцованную очередь, либо выяснить, готов ли его кто обрабатывать, и если не готов - игнорировать.

                  А программа обработки, соответственно, должна либо искать последний готовый буфер в очереди, освобождая все прочие в первом варианте, либо по завершении обработки выставлять флаг готовности и ждать, пока обработчик выплюнет очередной буфер.
                    Цитата
                    Обработчик должен схватить буфер и либо скопировать его, скажем, в закольцованную очередь, либо выяснить, готов ли его кто обрабатывать, и если не готов - игнорировать.

                    Зачем ещё одна очередь, если она уже есть.
                      andriano, так буфер в обработчике изначально находится в непотребном состоянии, с искажениями.
                      Только что проверил свою программу дома, на стационарном компе. Все работает как надо! Нет никаких наложений даже с одним буфером, при любой его длине (выставлял даже 256точек, 44100 дискретность).
                      Но не работает нормально на ноутбуке на работе и на ноутбуке в гараже (в гараже старенький Тошиба, на работе свежий Асер). Такие вот пироги :blink:
                        IvanB, вопрос, вероятно, не в том, стационарный комп или ноутбук, а в том, какой стоит звуковой чип и, соответственно, его возможности - что он делает аппаратно, а что перекладывает на процессор для программной обработки.

                        Любая правильно написанная программа надежно работает на любом железе. Если с Вашей программой этого не происходит, значит, она написана неправильно, а то, что она работает, говорит о том, что "железо" стационарного компа исправляет Ваши ошибки.
                        Следовательно, Вы что-то изначально неверно организуете, и Вам нужно не удивляться, почему программа, которая кое-где работает, работает не везде, а исправлять ее так, чтобы она работала на наиболее неблагоприятной для нее конфигурации.

                        "буфер в обработчике изначально находится в непотребном состоянии, с искажениями" - это неверная посылка. Если буфер у Вас оказывается в таком состоянии, значит, где-то Вы сами его портите. Либо что-то неправильное делаете с системой, что заставляет ее портить Ваш буфер.

                        Добавлено
                        Цитата Prince @
                        Зачем ещё одна очередь, если она уже есть.

                        Затем, что вторая очередь не будет совпадать с первой.
                        Они будут по-разному обрабатываться и их элементы будут по-разному освобождаться.
                          Цитата
                          Затем, что вторая очередь не будет совпадать с первой.
                          Они будут по-разному обрабатываться и их элементы будут по-разному освобождаться.

                          Так зачем это нужно? Чем не устривает та очередь, что уже есть?
                            Цитата
                            выставлял даже 256точек, 44100 дискретность

                            Выставьте 256 точек(6 мс), 1024(23 мс), 2048(46 мс) и 4096(92 мс) и сравните загрузку процессора. Допустите, что ваша программа выполняется на старенькой машине, параллельно с другими задачами, тоже требующими процессорного времени.
                              Prince, исправил в своей программе "инициализацию" буферов, что-то связанное с выделением памяти. Сделал как у вас в WaveIn.
                              До этого было так
                              ExpandedWrap disabled
                                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);


                              Переделал в такое
                              ExpandedWrap disabled
                                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);


                              Стало работать без ошибок! :good: Вечером еще на старом буке надо проверить.
                              Выделение буферов сейчас сделано как у вас в программе, здесь просто приведен пример того, что исправлено.

                              Спасибо!
                              зы: пока писал ответ, помоему понял ошибку. В первом случае я 1 раз выделил память (строки 21-22) и дальше писал по одному и тому же адресу 2 буфера.
                                Доброго!
                                Писать звук с 2х каналов научили :good: . Теперь хотелки выросли и нужно записать 4 канала на том же железе.
                                Имеем встроенную звуковую систему АС97 на чипе Alc201, т.е. 2х канальное стерео. АЦП имеет частоту дискретизации 48кГц и 4 пары каналов записи. Задача - получить 4х канальный сигнал с полезной частотой не превышающей 3кГц, синхронизированный во времени.
                                Идея следующая. Запрограммировать длину буфера весьма короткой (1, 2 или 4 отсчета). Получить от АЦП выборку 1й пары каналов, скинуть ее в буфер1. Потом переключить запись на другую пару каналов и получить выборку с нее, сбросить ее в буфер2. Получится ли таким образом записать "одновременно" 4 канала? Или потрачу много времени на переключение каналов?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 2 [3]  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0706 ]   [ 20 queries used ]   [ Generated: 28.03.24, 09:58 GMT ]