Metodi għall-kompressjoni/ħażna tad-dejta tal-midja fil-formati WAVE u JPEG, parti 1

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): https://instaud.io/3Dcy

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

Struttura tal-fajl WAV
WAV - Wikipedija

Sors: www.habr.com

Żid kumment