forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Библиотеки (http://forum.boolean.name/forumdisplay.php?f=28)
-   -   Получение свойств WAV-файла (http://forum.boolean.name/showthread.php?t=13372)

impersonalis 18.09.2010 16:19

Получение свойств WAV-файла
 
Код:

;code for B3D:        impersonalis (icq 11-999-51-51)
;info:                        https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

Function imp_MusProperty_GetByteStr$(bank%,start%,l%=4)
        Local s$=""
        Local i%
        Local endi%=start+(l-1)
        For i=start To endi
                s=s+Chr(PeekByte(bank,i))
        Next
        Return s
End Function

Function imp_MusProperty_Short2Int%(a%)
        Local M1%=%00000000000000001000000000000000
        Local M2%=%11111111111111110000000000000000
        Local D%=a And M1
        If D
                a = a Xor M2
        EndIf
        Return a
End Function

Type T_imp_MusProperty_Wav
        Field ChunkID$
        Field ChunkSize%
        Field Format$
        Field Subchunk1ID$
        Field Subchunk1Size%
        Field AudioFormat%
        Field NumChannels%
        Field SampleRate%
        Field ByteRate%
        Field BlockAlign%
        Field BitsPerSample%
        Field Subchunk2ID$
        Field Subchunk2Size%
End Type

Function imp_MusProperty_WavFileProc.T_imp_MusProperty_Wav(filename$)
        Local WP.T_imp_MusProperty_Wav=New T_imp_MusProperty_Wav
       
        Local i%
        Local file%=ReadFile(filename)
        If file=0
                RuntimeError "Cannot open "+filename
        EndIf
        Local RIFF_chunk%=CreateBank(12)
        Local fmt_subchunk%=CreateBank(24)
        Local data_subchunk%=CreateBank(8)
        ReadBytes(RIFF_chunk,file,0,BankSize(RIFF_chunk))
        ReadBytes(fmt_subchunk,file,0,BankSize(fmt_subchunk))
        ReadBytes(data_subchunk,file,0,BankSize(data_subchunk))
        CloseFile(file)
        WP\ChunkID=imp_MusProperty_GetByteStr(RIFF_chunk,0)
        WP\ChunkSize=PeekInt(RIFF_chunk,4)
        WP\Format=imp_MusProperty_GetByteStr(RIFF_chunk,8)
        WP\Subchunk1ID=imp_MusProperty_GetByteStr(fmt_subchunk,0)
        WP\Subchunk1Size=PeekInt(fmt_subchunk,4)
        WP\AudioFormat=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,8))
        WP\NumChannels=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,10))
        WP\SampleRate=PeekInt(fmt_subchunk,12)
        WP\ByteRate=PeekInt(fmt_subchunk,16)
        WP\BlockAlign=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,20))
        WP\BitsPerSample=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,22))
        WP\Subchunk2ID=imp_MusProperty_GetByteStr(data_subchunk,0)
        WP\Subchunk2Size=PeekInt(data_subchunk,4)
        FreeBank(RIFF_chunk)
        FreeBank(fmt_subchunk)
        FreeBank(data_subchunk)
       
        Return WP
End Function

Function imp_MusProperty_IsWav%(WP.T_imp_MusProperty_Wav)
        Return WP\Format="WAVE"
End Function

Для многих очевидный код, но кому-то пригодится. Основное применение: функции ChannelPitch channel_handle, hertz и SoundPitch sound_variable, hertz принимают в качестве hertz частоту дискретизации воспроизводимого звука - это логично но может порвать мозг в некторых случаях. Например, у вас есть wav-файл с записанной в него "чистой" синусойдой в 2КГц, какой hertz нужно передать в ChannelPitch, чтобы услышть звук частотой 10Кгц? 5? Фиг. Итоговая формула (опуская дефекты оконечной звуковой аппаратуры и психофизиологические особенности восприятия конкретного индивида и свойства среды распространения сигнала):
СлышимаяЧастота=ЧастотаЗаписанногоЗвука*ЧастотаДискретизацииЗвукаВФайле*hertz
Вот ЧастотаДискретизацииЗвукаВФайле нам и надо узнать. Причём сам гадский Блитц её знает, т.к. воспроизводит звук по умолчанию верно, но с нами делиться не хочет. Возможно, конечно, за воспроизведение отвечают кодеки, доставшиеся Марку в виде объектных файлов... пофиг :dontknow:
Что мы можем сделать:
взываем imp_MusProperty_WavFileProc с параметром filename$ равным пути до wav-файла и его имени с расширением. На выходе получаем объект типа T_imp_MusProperty_Wav, который можем чекнуть на валидность функцией imp_MusProperty_IsWav - проверим является ли файл WAV-ом. Удаляем объект обычным деструкторм структур - Delete.
ЧастотаДискретизацииЗвукаВФайле это поле ByteRate.
Вообще, вы можеет просто записывать все ваши файлы с одной и той же дисркетизацией, но вам надо это(?) когда данное свойство файла легко получить.

impersonalis 30.09.2010 23:57

Ответ: Получение свойств WAV-файла
 
Добавил функцию.
Код:

;code for B3D:        impersonalis (icq 11-999-51-51)
;info:                        https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
;                                http://www.gamedev.ru/code/forum/?id=38568

Function imp_MusProperty_GetByteStr$(bank%,start%,l%=4)
        Local s$=""
        Local i%
        Local endi%=start+(l-1)
        For i=start To endi
                s=s+Chr(PeekByte(bank,i))
        Next
        Return s
End Function

Function imp_MusProperty_Short2Int%(a%)
        Local M1%=%00000000000000001000000000000000
        Local M2%=%11111111111111110000000000000000
        Local D%=a And M1
        If D
                a = a Xor M2
        EndIf
        Return a
End Function

Type T_imp_MusProperty_Wav
        Field ChunkID$
        Field ChunkSize%
        Field Format$
        Field Subchunk1ID$
        Field Subchunk1Size%
        Field AudioFormat%
        Field NumChannels%
        Field SampleRate%
        Field ByteRate%
        Field BlockAlign%
        Field BitsPerSample%
        Field Subchunk2ID$
        Field Subchunk2Size%
End Type

Function imp_MusProperty_WavFileProc.T_imp_MusProperty_Wav(filename$)
        Local WP.T_imp_MusProperty_Wav=New T_imp_MusProperty_Wav
       
        Local i%
        Local file%=ReadFile(filename)
        If file=0
                RuntimeError "Cannot open "+filename
        EndIf
        Local RIFF_chunk%=CreateBank(12)
        Local fmt_subchunk%=CreateBank(24)
        Local data_subchunk%=CreateBank(8)
        ReadBytes(RIFF_chunk,file,0,BankSize(RIFF_chunk))
        ReadBytes(fmt_subchunk,file,0,BankSize(fmt_subchunk))
        ReadBytes(data_subchunk,file,0,BankSize(data_subchunk))
        CloseFile(file)
        WP\ChunkID=imp_MusProperty_GetByteStr(RIFF_chunk,0)
        WP\ChunkSize=PeekInt(RIFF_chunk,4)
        WP\Format=imp_MusProperty_GetByteStr(RIFF_chunk,8)
        WP\Subchunk1ID=imp_MusProperty_GetByteStr(fmt_subchunk,0)
        WP\Subchunk1Size=PeekInt(fmt_subchunk,4)
        WP\AudioFormat=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,8))
        WP\NumChannels=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,10))
        WP\SampleRate=PeekInt(fmt_subchunk,12)
        WP\ByteRate=PeekInt(fmt_subchunk,16)
        WP\BlockAlign=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,20))
        WP\BitsPerSample=imp_MusProperty_Short2Int(PeekShort(fmt_subchunk,22))
        WP\Subchunk2ID=imp_MusProperty_GetByteStr(data_subchunk,0)
        WP\Subchunk2Size=PeekInt(data_subchunk,4)
        FreeBank(RIFF_chunk)
        FreeBank(fmt_subchunk)
        FreeBank(data_subchunk)
       
        Return WP
End Function

Function imp_MusProperty_IsWav%(WP.T_imp_MusProperty_Wav)
        Return WP\Format="WAVE"
End Function

Function imp_MusProperty_GetWavTimeInSec#(WP.T_imp_MusProperty_Wav)
        Return WP\Subchunk2Size / Float( (WP\BitsPerSample / 8.0) * WP\NumChannels * WP\SampleRate)
End Function

imp_MusProperty_GetWavTimeInSec возвращает время воспроизведения звукового файла в секундах (float). Кстати, неплохо бы потестить (у меня пашет).


Часовой пояс GMT +4, время: 00:18.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot