Bongu! L-ewwel serje ta’ artikli tiegħi se tiffoka fuq l-istudju ta’ metodi ta’ kompressjoni u ħażna ta’ immaġni/awdjo bħal JPEG (immaġini) u WAVE (ħoss), u se tinkludi wkoll eżempji ta’ programmi li jużaw dawn il-formati (.jpg, .wav) fil-prattika. F'din il-parti se nħarsu lejn WAVE.
Story
WAVE (Waveform Audio File Format) huwa format tal-fajl tal-kontenitur għall-ħażna ta 'reġistrazzjoni ta' stream awdjo. Dan il-kontenitur huwa tipikament użat biex jaħżen awdjo modulat tal-kodiċi tal-polz mhux kompressat. (Meħuda mill-Wikipedija)
Ġie ivvintat u ppubblikat fl-1991 flimkien mar-RIFF minn Microsoft u IBM (Leading IT companies of that time).
Struttura tal-fajl
Il-fajl għandu parti header, id-data nnifisha, iżda l-ebda footer. L-header jiżen total ta '44 byte.
L-intestatura fiha settings għan-numru ta 'bits fil-kampjun, rata tal-kampjun, fond tal-ħoss, eċċ. informazzjoni meħtieġa għall-karta tal-ħoss. (Il-valuri numeriċi kollha tat-tabella jridu jinkitbu f'ordni Little-Endian)
Isem tal-blokk
Daqs tal-blokk (B)
Deskrizzjoni/Għan
Valur (għal xi wħud huwa fiss
chunkId
4
Id-definizzjoni ta' fajl bħala kontenitur tal-midja
0x52494646 fi Big-Endian (“RIFF”)
chunkSize
4
Daqs tal-fajl kollu mingħajr chunkId u chunkSize
FILE_SIZE - 8
format
4
Definizzjoni tat-tip minn RIFF
0x57415645 fi Big-Endian (“WAVE”)
subchunk1Id
4
Sabiex il-fajl jieħu aktar spazju bħala kontinwazzjoni tal-format
0x666d7420 fi Big-Endian (“fmt”)
subchunk1Size
4
Header li jifdal (f'bytes)
16 awtomatikament (għall-każ mingħajr kompressjoni tal-fluss tal-awdjo)
awdjoFormat
2
Format tal-awdjo (jiddependi fuq il-metodu tal-kompressjoni u l-istruttura tad-dejta tal-awdjo)
1 (għall-PCM, li huwa dak li qed nikkunsidraw)
numChannels
2
Numru ta 'kanali
1/2, se nieħdu kanal 1 (3/4/5/6/7... - track awdjo speċifiku, pereżempju 4 għal ħoss quad, eċċ.)
sampleRate
4
Rata ta' kampjunar tal-awdjo (f'Hertz)
Iktar ma jkun għoli, iktar ikun aħjar il-ħoss, iżda aktar tkun meħtieġa memorja biex tinħoloq track awdjo tal-istess tul, il-valur rakkomandat huwa 48000 (l-iktar kwalità aċċettabbli tal-ħoss)
byteRate
4
Numru ta' bytes kull sekonda
sampleRate numChannels bitsPerSample (aktar)
blockAlign
2
Numru ta' bytes għal kampjun 1
numChannels * bitsPerSample: 8
bitsPerSample
2
Numru ta' bits għal kull kampjun (fond)
Kwalunkwe numru li huwa multiplu ta’ 8. Aktar ma jkun għoli n-numru, iktar ikun aħjar u itqal l-awdjo, minn 32 bit m’hemm l-ebda differenza għall-bnedmin
subchunk2Id
4
Marka ta' referenza tad-dejta (peress li jista' jkun hemm elementi oħra tal-header skont l-audioFormat)
0x64617461 fi Big-Endian ("data")
subchunk2Size
4
Id-daqs taż-żona tad-dejta
daqs tad-data f'int
data
byteRate * tul ta' żmien tal-awdjo
Data awdjo
?
Eżempju WAVE
It-tabella ta 'qabel tista' faċilment tiġi tradotta fi struttura f'Ċ, iżda l-lingwa tagħna għal-lum hija Python. L-eħfef ħaġa li tista 'tagħmel hija tuża "mewġa" - ġeneratur tal-ħoss. Għal dan il-kompitu m'għandniex bżonn byteRate u kompressjoni għolja.
L-ewwel, ejja nimportaw il-moduli meħtieġa:
# WAV.py
from struct import pack # перевод py-объектов в базовые типы из C
from os import urandom # функция для чтения /dev/urandom, для windows:
# from random import randint
# urandom = lambda sz: bytes([randint(0, 255) for _ in range(sz)]) # лямбда под windows, т.к. urandom'а в винде нет
from sys import argv, exit # аргументы к проге и выход
if len(argv) != 3: # +1 имя скрипта (-1, если будете замораживать)
print('Usage: python3 WAV.py [num of samples] [output]')
exit(1)
Sussegwentement, għandna bżonn noħolqu l-varjabbli kollha meħtieġa mit-tabella skond id-daqsijiet tagħhom. Il-valuri varjabbli fiha jiddependu biss fuq numSamples (numru ta 'kampjuni). Iktar ma jkun hemm, l-istorbju tagħna se jibqa’ għaddej.
numSamples = int(argv[1])
output_path = argv[2]
chunkId = b'RIFF'
Format = b'WAVE'
subchunk1ID = b'fmt '
subchunk1Size = b'x10x00x00x00' # 0d16
audioFormat = b'x01x00'
numChannels = b'x02x00' # 2-х каналов будет достаточно (стерео)
sampleRate = pack('<L', 1000) # 1000 хватит, но если поставить больше, то шум будет слышен лучше. С 1000-ю он звучит, как ветер
bitsPerSample = b'x20x00' # 0d32
byteRate = pack('<L', 1000 * 2 * 4) # sampleRate * numChannels * bitsPerSample / 8 (32 bit sound)
blockAlign = b'x08x00' # numChannels * BPS / 8
subchunk2ID = b'data'
subchunk2Size = pack('<L', numSamples * 2 * 4) # * numChannels * BPS / 8
chunkSize = pack('<L', 36 + numSamples * 2 * 4) # 36 + subchunk2Size
data = urandom(1000 * 2 * 4 * numSamples) # сам шум
Jibqa' biss li tiktebhom fis-sekwenza meħtieġa (bħal fit-tabella):
with open(output_path, 'wb') as fh:
fh.write(chunkId + chunkSize + Format + subchunk1ID +
subchunk1Size + audioFormat + numChannels +
sampleRate + byteRate + blockAlign + bitsPerSample +
subchunk2ID + subchunk2Size + data) # записываем
U hekk, lest. Biex nużaw l-iskrittura, irridu nżidu l-argumenti meħtieġa tal-linja tal-kmand:
python3 WAV.py [num of samples] [output]
numru ta' kampjuni - għadd. kampjuni
output — mogħdija għall-fajl tal-output
Hawnhekk hawn link għal fajl awdjo tat-test bl-istorbju, iżda biex tiffranka l-memorja naqqas il-BPS għal 1b/s u naqqas in-numru ta 'kanali għal 1 (bi stream awdjo stereo mhux kompressat ta' 32 bit f'64kbs, irriżulta li kien 80M ta 'fajl .wav pur, u 10 biss):
Il-kodiċi kollu (WAV.py) (Il-kodiċi għandu ħafna valuri varjabbli duplikati, dan huwa biss skeċċ):
from struct import pack # перевод py-объектов в базовые типы из C
from os import urandom # функция для чтения /dev/urandom, для windows:
# from random import randint
# urandom = lambda sz: bytes([randint(0, 255) for _ in range(sz)]) # лямбда под windows, т.к. urandom'а в винде нет
from sys import argv, exit # аргументы к проге и выход
if len(argv) != 3: # +1 имя скрипта (-1, если будете замораживать)
print('Usage: python3 WAV.py [num of samples] [output]')
exit(1)
numSamples = int(argv[1])
output_path = argv[2]
chunkId = b'RIFF'
Format = b'WAVE'
subchunk1ID = b'fmt '
subchunk1Size = b'x10x00x00x00' # 0d16
audioFormat = b'x01x00'
numChannels = b'x02x00' # 2-х каналов будет достаточно (стерео)
sampleRate = pack('<L', 1000) # 1000 хватит, но можно и больше.
bitsPerSample = b'x20x00' # 0d32
byteRate = pack('<L', 1000 * 2 * 4) # sampleRate * numChannels * bitsPerSample / 8 (32 bit sound)
blockAlign = b'x08x00' # numChannels * BPS / 8
subchunk2ID = b'data'
subchunk2Size = pack('<L', numSamples * 2 * 4) # * numChannels * BPS / 8
chunkSize = pack('<L', 36 + numSamples * 2 * 4) # 36 + subchunk2Size
data = urandom(1000 * 2 * 4 * numSamples) # сам шум
with open(output_path, 'wb') as fh:
fh.write(chunkId + chunkSize + Format + subchunk1ID +
subchunk1Size + audioFormat + numChannels +
sampleRate + byteRate + blockAlign + bitsPerSample +
subchunk2ID + subchunk2Size + data) # записываем в файл результат
Total
Allura tgħallimt ftit aktar dwar il-ħoss diġitali u kif jinħażen. F'din il-post aħna ma użajnax kompressjoni (audioFormat), iżda biex tikkunsidra kull wieħed minn dawk popolari, se jkunu meħtieġa artikli 10. Nispera li tgħallimt xi ħaġa ġdida għalik innifsek u dan jgħinek fl-iżviluppi futuri.
Grazzi!
Sorsi
Sors: www.habr.com