Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Подземелье Магов
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  12:11[Войти] | [Зарегистрироваться]

Обсуждение материала
Еще раз о звуке
Полный текст материала


Цитата или краткий комментарий:

«... Как я выяснил, жители Королевства интересуются темой ввода/вывода звука, причем вопросов больше, чем ответов. Меня же некоторое время назад жизнь заставила разобраться с этой темой, не сказать чтобы досконально, но некоторые интересные моменты есть :). ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]1588.2%
 
  Ничего особенно нового и интересного
[2]211.8%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 17

Оценка стиля изложения

  Все понятно, материал читается легко
[1]1392.9%
 
  Есть неясности в изложении
[2]17.1%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 14




Смотрите также материалы по темам:
[WAV] [Чтение/запись и преобразование звука]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 23

09-07-2012 12:10
спасибо за прекрасную статью.. можно ли помочь с редактированием кода для вывода звукового сигнала  по двум аудиовыходам - по 4 каналам..?? заранее благодарен..


25-10-2010 11:26
Спасибо огромное за статью. Если есть возможность пожалуйста помогите с одним вопрос, необходимо вывести звук с формой сигнала пила, подскажите как это сделать.


16-11-2007 05:56
если сильно нагрузить CPU в момент её выполнения -
программа начинает дёргать звук
У меня тоже самое иногда происходит и в WinAMP и при проигрывании системных звуков, при чем только на встроенной карте, на второй всё нормально. Тут дело, видимо, в глючности драйверов и/или железа.
 Cep


15-11-2007 14:57
ОТВЕТ НА СВОЙ ЖЕ ВОПРОС:

чтобы избавиться от дёрганий после нагрузки на CPU
нужно выставить наивысший приоритет потоку

  ServiceThread := TServiceThread.Create(False);
ServiceThread.Priority:=tpTimeCritical;

но при этом кушать ресурсы не будет
т.к. есть функция    WaitForSingleObject(hEvent, infinite);


15-11-2007 14:35
очень полезный пример.

но есть одно большое НО:

если сильно нагрузить CPU в момент её выполнения -
программа начинает дёргать звук,
а когда CPU разгружается,
дерганье звука продолжается,
причём с какойто периодичностью.


и ещё мне непонятна структура
  while not Terminated do begin

    waveOutWrite(hwo, @wh[I], sizeof(WAVEHDR)); - отдаём буфер драйверу
    WaitForSingleObject(hEvent, infinite); я так понял что ждём пока драйвер отыграет буфер // ДЛЯ ЧЕГО эта функция и её физический смысл и почему используется именно она?


    I:= I xor 1; // почему если буферы не менять изменением I то появляется дёрганье?
ведь изменяем содержимое буферов только после того как звуковуха отыграет буфер

...

  end;


07-08-2007 12:09
Ссылка, конечно, битая. Новый адрес http://saanvi.ru/fac.php?filename=multimediadictionary.txt - теперь уж постоянный. ;)


25-06-2007 01:33
http://saanvi.narod.ru/mulvoc.html
не работает


17-06-2007 04:52
куда пропала страница
Не пропала, а просто поменяла адрес. Сейчас ссылка исправлена.


17-06-2007 01:39
куда пропала страница
http://www.delphikingdom.com/mastering/wave_api_1.htm

ссылка на которую есть в этом чудесном материале?

и еще неплохо бы расширить изложение по работе со всеми звууками


09-01-2007 10:40
Премного благодарен за эту статью. Мне, наконец, удалось обратиться к звуковой карте, давно я этого ждал :-)
Я попробовал всунуть в процедуру Generator процесс чтения сэмплов из стандартного файла, немножко изменив порядок загрузки. Не заполнять целиком один буфер, а потом целиком - другой, а заполнять оба сразу, через сэмпл. Получился проигрыватель.

И теперь такой вопрос. Чем может быть вызвана нечеткая стыковка соседних "порций" данных при переключениях буферов? Файл-то читается без пропусков - а в колонках прослушиваются легкие щелчки; периодичность которых прямо зависит от размера буфера. Нельзя ли как-то от них избавиться?

Буду признателен, если копия ответа будет послана мне почтой: mumrik05@hotmail.ru


02-05-2006 12:13
К сожалению ссылка на пример в статье битая. А очень хотелось бы посмотреть.


21-04-2005 04:49
Неоходимую информацию нашел, спасибо.

вопрос следующий:

1) заполняю структуру

  wfx: TWAVEFORMATEX;

  FillChar(wfx, Sizeof(TWAVEFORMATEX), #0);
  with wfx do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := 2;
    nSamplesPerSec := 44100;
    wBitsPerSample := 16;
    nBlockAlign := wBitsPerSample div 8 * nChannels;
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
    cbSize := 0;
  end;



2)Открываю устройство
  hEvent: THandle;

  hEvent := CreateEvent(nil, false, false, nil);
  if WaveOutOpen(@hwo, 0, @wfx, hEvent, 0, CALLBACK_EVENT)



3)Выделяю память под буфер (BlockSize=5*0.001*44100*4 это как раз 5 мс)
  si: TSYSTEMINFO;
  P: Pointer

  GetSystemInfo(si);
  P := VirtualAlloc(nil, (BlockSize + si.dwPageSize - 1) div
    si.dwPagesize * si.dwPageSize,
    MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE); //содрал с Гордеева



4)Подготавливаю буфер
  wh: TWAVEHDR;

  FillChar(wh, sizeof(TWAVEHDR), #0);
    wh.lpData := P; // указатель на буфер
    wh.dwBufferLength := BlockSize; // длина буфера
    waveOutPrepareHeader(hwo, @wh, sizeof(TWAVEHDR));



5)Заполняю буфер данными
  I: Integer;

  for I := 0 to BlockSize div 2 do
  begin
    P^ = 10000;
    Inc(PSmallInt(P));
  end



6)Воиспровожу данные буфера
  while 1=1 do
  begin
    WaveOutWrite(hwo, @wh, sizeof(WAVEHDR));
    WaitForSingleObject(hEvent, INFINITE);
  end



7)Подключаю осциллограф и вижу

******          ******
*    *          *    *
* 5мс*          * 5мс*
*    ************    ************

а по идее должен быть постоянный уровень с амплитудой 10000

*********************************

КАК ИЗБЕЖАТЬ ЭТИХ ПРОВАЛОВ
P.S. такое ощущение что я не до конца заполняю буфер и там остаются нули

СПАСИБО


14-02-2005 04:50

while not Terminated do begin
// передача очередного буфера
    waveOutWrite(hwo, @wh[I], sizeof(WAVEHDR));



если ждём как весь буфер "отыграется", то зачем ДВА буфера? Было бы понятно, если бы во время проигрывания одного другой заполнялся. Был похожий вопрос, автор ответил, что не знает почему если

WaitForSingleObject(hEvent, INFINITE);


перенести, то после заполнения буфера слышны щелчки, но зачем-то два буфера ведь использовались? Или это последствия того, что не получилось записывать буфер во время воспроизведения другого? Я пыталась без

WaitForSingleObject(hEvent, INFINITE);


сначала ставить два буфера в очередь, затем ждать пока один доиграет и заполнять его (так же как у автора, но вначале последовательно посылаются два буфера без ожидания). Слышны щелчки, непонятно почему...
    

WaitForSingleObject(hEvent, INFINITE);
    I:= I xor 1;
    // генерация буферов каналов
    Generator(CnlBuf[0],Typ[0], Freq[0], Lev[0], BlockSize div 2, tPred[0]);
    Generator(CnlBuf[1],Typ[1], Freq[1], Lev[1], BlockSize div 2, tPred[1]);
    Mix(buf[I],CnlBuf[0],CnlBuf[1], BlockSize div 2);
    // ожидание конца проигрывания и освобождения предыдущего буфера
  end;



непонятно, почему в последнем комментарии написано, что ждем конца проигрывания, т.е. после Mix. Или я не поняла как Mix работает? Ожидание вроде бы в другом месте.


15-12-2004 19:57
Спасибо за разъяснения.


15-12-2004 10:55
To Andrew

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


15-12-2004 09:23
Почему ступенька миандра выглядит прорезанной на осцилограмме? Как этого избежать?


24-08-2004 23:11
Я этим вопросом тоже долго задавался, когда писал статью,но так и не понял :)))
Если кто-то способен ответить, ответьте пожалуйста.


21-05-2004 11:11
Я кажется немного не  понял:
while not Terminated do begin
// передача очередного буфера
    waveOutWrite(hwo, @wh[I], sizeof(WAVEHDR));
//как я понял, ждём как весь буфер "отыграется"?
    WaitForSingleObject(hEvent, INFINITE);
    I:= I xor 1;
    // генерация буферов каналов
    Generator(CnlBuf[0],Typ[0], Freq[0], Lev[0], BlockSize div 2, tPred[0]);
    Generator(CnlBuf[1],Typ[1], Freq[1], Lev[1], BlockSize div 2, tPred[1]);
    Mix(buf[I],CnlBuf[0],CnlBuf[1], BlockSize div 2);
    // ожидание конца проигрывания и освобождения предыдущего буфера
  end;

А почему нельзя пока плейер "отыгрывает" генерировать буферы (или буфера :)? Но к сожалению, практика опровергает: если перенести WaitForSingleObject после Mix(...) наблюдаются всякие нехорошие щелчки :(
НО почему?


20-05-2004 14:49
Спасибо!


16-12-2002 13:21
Мне были вопросы по поводу примера и указания на ошибки,отвечаю:
1) При выделении памяти под буферы выделяю BlockSize*4, а не BlockSize*3?
VirtualAlloc(nil,(BlockSize*4+si.dwPageSize-1) div si.dwPagesize * si.dwPageSize,MEM_RESERVE or EM_COMMIT, PAGE_READWRITE);
Ведь нам памяти надо памяти BlockSize*2 на буферы для звука и BlockSize для буферов левого и правого канала, всего BlockSize*3.

Верно, я выделил памяти больше чем надо. Просчитался :)

2) Почему при заполнении данными буферов канала для "тишины" for I := 0 to Size-2. Почему -2?
Почему при заполнении данными буферов канала для "sin" for I := 0 to Size div 2. Почему div 2?!

Это связано вот с чем:
Size -- размер буфера канала в байтах, а считать нам все надо в выборках (SmallInt -- 16 бит)

в "тишине" ошибка, так как Size -- это размер буфера в байтах, а в цикле работа идет с типом SmallInt -- т.е. выборкой 16 бит или 2 байта и Inc(PSmallInt(buf)); увеличивает buf на 2.  Поэтому размер буфера в выборках будет Size div 2. Аналогично, sin генерится в размере SmallInt т.е. 2 байта, а Size дан в байтах, поэтому там тоже  div 2 -- т.е. количество в выборках. Кажется, здесь может быть еще ошибка -- надо еще 2 вычесть ,т.е. Size div 2 -2 чтоб сошлось. А может и не надо???? Если будете проверять -- сообщите результат.
К ошибке в звучании не приводит вот почему:))) Сначала заполняется cnlbuf0, потом cnlbuf1, а т.к. они друг за другом, то при тишине сначала оба буфера обнуляются, потом только второй буфер настраивается -- потери данных нет :))) Но ошибка, конечно, есть. Стоит только поменять в потоке вызовы процедуры Generator местами, все рухнет.



28-09-2002 20:06
Спасибо! Статья экономит массу времени.


18-03-2002 10:38
Попробовал - все понятно, пример работает. Спасибо.
Хотелось бы продолжения - о возможности использования звуковой карты для ввода сигнала.


07-03-2002 20:42
Очень помогло. Спасибо.


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Раз дощечка, два дощечка будет лесенка. Раз словечко, два словечко, будет ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования