Конференция "Media" » Bass.dll Функция Bass_ChannelGetData [D7, WinXP]
 
  • ВладОшин © (26.12.18 14:46) [0]
    Идея - не слушать тишину звукового файла
    Для этого хочу получить уровни звука, а потом участки близкие к 0 перепрыгивать при воспроизведении


    type
     TFFT8192 = array[0..4093] of single;
    var
     data2: TFFT8192;  
    .....
    BASS_Init(-1, 44100, 0, Application.Handle, nil) ;
    filename := 'C:\Users\oshin\Desktop\PlayVisualWanMp3\1.wav';
    StreamWav := BASS_StreamCreateFile(FALSE, pchar(filename), 0, 0, BASS_STREAM_DECODE or BASS_STREAM_PRESCAN);



    если пишу

    Bass_ChannelGetData(StreamWav, @data2, BASS_DATA_FFT8192);
    for i := 0 to 4093 do
     fastLineSeries1.Add(100*data2[i]);
    <.CODE>
    не понятно что рисует, даже в начале не похоже

    понятно если  так (этот же файл загружаю в любую программу-редактор, там волны совпадают с моими "всплесками", и хотя не похоже, но это ладно, 0 совпадает)
    но это относительно долго работает

    StreamLen := BASS_ChannelGetLength(StreamWav, BASS_POS_BYTE);
    StreamLenSec := BASS_ChannelBytes2Seconds(StreamWav, StreamLen);
    CurPos := 0;
    while (CurPos <= StreamLenSec) do
    begin
      CurPosByte := BASS_ChannelSeconds2Bytes(StreamWav, CurPos);
      BASS_ChannelSetPosition(StreamWav, CurPosByte, BASS_POS_BYTE);
      Level := BASS_ChannelGetLevel(StreamWav);
      //L := LOWORD(Level);
      L := MulDiv(100, LOWORD(Level), 32768);
      fastLineSeries1.Add(L);
      CurPos := CurPos + 0.1;
    end;



    Как правильно и быстро выцепить уровни в массив?

    (вот эти волны, картинка)
    https://cloud.mail.ru/public/DVJ2/nUy9YXokZ
  • RWolf © (26.12.18 16:41) [1]
    Я бы отпрофилировал для начала, а то вдруг окажется, что все тормоза только лишь из-за добавления миллионов точек в TChart.
  • ВладОшин © (26.12.18 18:27) [2]
    Не, чарт быстр достаточно,
    но да, если через 10 точек - летает. Да и похоже сообразил как массив брать

    теперь сделал так


    type
     TSingleArray = array of Single;
    var
     ci  : BASS_CHANNELINFO;
     Buf  : TSingleArray;

    ...
    StreamLen := BASS_ChannelGetLength(StreamWav, BASS_POS_BYTE); // Длинна в байтах
    StreamLenSingle :=  StreamLen div SizeOf(Single);
    //print(StreamLenSingle, 'StreamLenSingle=');
    BASS_ChannelGetInfo(StreamWav, ci);
    //Print(ci.chans, 'Chanels=');
    SetLength(Buf, StreamLenSingle*ci.chans);
    BASS_ChannelGetData(StreamWav, buf, StreamLenSingle*SizeOf(Single)*ci.chans or BASS_DATA_FLOAT);
    //print(Length(buf), 'Length(buf)=');
      for i := 0 to Length(buf) - 1 do
      begin
        if i mod 10 = 0 then
          fstLnSeries1.Add(buf[i]);
      end;




    выглядит почти )
    https://cloud.mail.ru/public/GuNk/n7G5CpTrP

    остается загвоздка - где остальные данные.
    Похоже, ошибся с размером buf. Если тупо спросить больше - дает больше.
    Single - 4 байта
    Канал - 1
    Не пойму где просчитался. Ладно, утро вечера мудренее, походу затупил просто, завтра подумаю. Или подскажите )
  • ВладОшин © (31.12.18 14:54) [3]
    только руки дошли

    если умножить на 2 размер буфера, то 1:1 картинка

    SetLength(Buf, StreamLenSingle*ci.chans *2);
    BASS_ChannelGetData(StreamWav, buf, StreamLenSingle*SizeOf(Single)*ci.chans *2 or BASS_DATA_FLOAT);


    не пойму, почему на 2 умножить надо

    может, потому что моно. А там левый и правый(пустой) канал.. Но, как пишут, дам должно идти чередованием - данные левого, данные правого,данные левого, данные правого..данные левого, данные правого
    в общем, не понятно.
  • ВладОшин © (31.12.18 15:51) [4]
    а вот первый попавшийся mp3 разложил - там уже ровно половина =0
    пришлось множитель x2 убрать и тогда правильно показывает

    https://cloud.mail.ru/public/3mfF/e1p3Gc8nk

    не понятно, когда надо SetLength(Buf, StreamLenSingle*ci.chans *2);
    а когда нет..
  • ВладОшин © (31.12.18 15:57) [5]
    а.. кажется понял..
    Всегда х2
    Только когда моно - ci.chans = 1 и x2 = x2
    А когда стерео - ci.chans = 2 и x2 уже не надо
  • ВладОшин © (07.02.19 14:30) [6]
    Все, сделал.

    + массив, куда пишем каждый K сигнал.
    Он проверяется на eps ~=0, если меньше eps, то = -1, иначе = 1.
    Если подряд N раз идет -1, то пишем не -1, а 0.

    Потом пробегаем вспомогательтный массив задом наперед, и вместо -1 ставим то, что было перед ним.
    т.о. короткие участки с -1 заменяются на 1, а длинные - на 0.

    При воспроизведении смотрим постоянно на него, если попали в 0, то перебираем то первой 1.
    Умножаем индекс на K  и ставим это смещение в реальном потоке звука
 
Конференция "Media" » Bass.dll Функция Bass_ChannelGetData [D7, WinXP]
Есть новые Нет новых   [134427   +29][b:0][p:0.002]