Щелчки при воспроизведении звука waveOutWrite

Тема в разделе "WASM.WIN32", создана пользователем Exp10der, 6 июн 2008.

  1. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Вот простейший код, хочу разобраться со звуком.. но при переключении буферов возникают щелчки длит. 0.1 сек... тема заезженая, но в сети ничего толкового не нашёл :dntknw:

    Код (Text):
    1. procedure PlaySound();
    2. var i: dword; event_: dword; t: bool;
    3. si: TSystemInfo;
    4. mem: pointer;
    5. Format: TWaveFormatEx;
    6. WaveOut: hWaveOut;
    7. WaveHdr: array [0..1] of TWaveHdr;
    8. begin
    9.  Format.wFormatTag:=WAVE_FORMAT_PCM;
    10.  Format.nChannels:=1;
    11.  Format.nSamplesPerSec:=11025;
    12.  Format.cbSize:=0;
    13.  Format.wBitsPerSample:=8;
    14.  Format.nBlockAlign:=Format.nChannels*(Format.wBitsPerSample div 8);
    15.  Format.nAvgBytesPerSec:=Format.nSamplesPerSec*Format.nBlockAlign;
    16.  event_:=CreateEvent(nil, false, false, nil);
    17.  GetSystemInfo(si);
    18.  mem:=VirtualAlloc(nil, (16384*4+si.dwPageSize-1) div si.dwPagesize*si.dwPageSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
    19.  ZeroMemory(@WaveHdr, SizeOf(WaveHdr));
    20.  WaveHdr[0].lpData:=mem;
    21.  WaveHdr[0].dwBufferLength:=16384;
    22.  WaveHdr[1].dwBufferLength:=16384;
    23.  WaveHdr[1].lpData:=pointer(dword(mem)+WaveHdr[0].dwBufferLength);
    24.  waveOutOpen(@WaveOut, WAVE_MAPPER, @Format, event_, 0, CALLBACK_EVENT);
    25.  waveoutprepareheader(WaveOut, @WaveHdr[0], SizeOf(TWaveHdr));
    26.  waveoutprepareheader(WaveOut, @WaveHdr[1], SizeOf(TWaveHdr));
    27.  for i:=0 to 16384*2-1 do
    28.  begin
    29.   if t then byte(pointer(dword(mem)+i)^):=0 else byte(pointer(dword(mem)+i)^):=255;
    30.   t:=not t;
    31.  end;
    32.  i:=0;
    33.  ResetEvent(Event_);
    34.  repeat
    35.   WaveOutWrite(WaveOut, @WaveHdr[i], SizeOf(TWaveHdr));
    36.   i:=i xor 1;
    37.   WaitForSingleObject(Event_, INFINITE);
    38.   until (false);
     
  2. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Такая весчь равносильна мерцанию картинки при перерисовке без заднего буфера кадра. ИМХО, решение проблемы - свести эти 2 буфера в один, размером 32кб (если я правильно понял код) и отправлять на воспроизведение единым куском.

    ЗЫЖ а как можно в белом шуме различить щелчки? :)

    [+]: также, можно поставить зацикленное воспроизведение. Только вот блин, забыл как он ставится. Вроде как парамами в waveOutOpen. Снимается с waveOutBreakLoop, это-то я вроде помню... Отыщу свои "творения" - отпишусь.
     
  3. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Прикол в том что "щёлкает" даже если буфер пустой... я уже писал подобную прогу.. практичеки такую же и без этих "артефактов".. эх.. найти бы её ещё..

    [+]: сделал так:
    Код (Text):
    1.  WaveHdr[0].lpData:=mem;
    2.  WaveHdr[0].dwBufferLength:=32768;
    3.  WaveHdr[1].dwBufferLength:=32768;
    4.  WaveHdr[1].lpData:=mem; //pointer(dword(mem)+WaveHdr[0].dwBufferLength);
    ...та же хрень
     
  4. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Вроде и буферы выровнены всё как в туторе, ничего не могу понять... может у кого работающий примерчик найдётся?
     
  5. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Для Win нет, но я писал в свое время WAV-плеер под DOS real-mode через DMA. У меня была похожая проблема.
    Создавались 2 буфера, и свуковой карте давался один буфер. Пока она его играла, подгружались данные во второй. Срабатывало прерывание об окончании буфера - я переключал карточку на второй буфер. Тут и возникали щелчки.

    Решение было простое: создавать один буфер из двух частей (каждая размером W) и грузить сразу обе части. И инициализировать звуковую на размер воспроизведение по размеру W. А DMA настроил на закольцованную отдачу карточке и подгружал по W байт в неактивную половину буфере при получении прерывания.

    Может чем поможет. Но это чистый DOS.
     
  6. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    А сразу два буфера на проигрывание поставить, и заполнять первый, пока второй играется, никак?
     
  7. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    iZzz32
    Собственно, я нечто подобное и предлагаю, просто с WaveOut не работал...
     
  8. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Данке всем, проблема решена - пихаю сразу два буфера - дальше жду и заново и никаких щелчков.
     
  9. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Exp10der
    А в момент окончания второго буфер происходит подгрузка в оба сразу? И не "щелкает"? Странно...
     
  10. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Xerx
    Не совсем: ставишь играть первый буфер пишешь во второй - соотв. играет второй - пишешь в первый и т. д.
     
  11. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Возможной причиной щелчков может быть слишком разный уровень сигнала в конце первого сэмпла и начале второго (или если в первом сэмпле шло нарастание, а во втором - убывание - тогда получается короткий по времени и большой по амплитуде разовый импульс, т.е. щелчок). Даже при простом склеивании в звуковом редакторе за гладкостью сигнала на склейке приходилось следить.
     
  12. microprogs

    microprogs New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2006
    Сообщения:
    54
    Если ты разобрался, выложи пожалуйста исходник.
    Я полдня пытаюсь понять похожие грабли, причем щелкает как начало воспроизведения, так и окончание воспроизведения :dntknw:
    Внутри - все отлично... Края массива щелкают....
    причем если весь массив забит 0-лями, то щелчки абсолютно такие-же.... Ядреные и громкие....