Mga pamaagi sa pag-compress/pagtipig sa datos sa media sa WAVE ug JPEG nga mga format, bahin 1

Hello! Ang akong unang serye sa mga artikulo mag-focus sa pagtuon sa image/audio compression ug storage method sama sa JPEG (image) ug WAVE (sound), ug maglakip usab sa mga ehemplo sa mga programa nga naggamit niini nga mga format (.jpg, .wav) sa praktis. Niini nga bahin atong tan-awon ang WAVE.

История

Ang WAVE (Waveform Audio File Format) kay usa ka container file format para sa pagtipig og recording sa audio stream. Kini nga sudlanan kasagarang gigamit sa pagtipig sa wala ma-compress nga pulse code modulated audio. (Gikuha gikan sa Wikipedia)

Kini giimbento ug gipatik niadtong 1991 uban sa RIFF sa Microsoft ug IBM (Nanguna nga mga kompaniya sa IT niadtong panahona).

Istruktura sa file

Ang file adunay bahin sa header, ang data mismo, apan walay footer. Ang ulohan adunay gibug-aton nga 44 ka byte.
Ang header adunay mga setting alang sa gidaghanon sa mga bit sa sample, sample rate, sound depth, etc. impormasyon nga gikinahanglan alang sa sound card. (Ang tanang numeric table values ​​​​kinahanglan isulat sa Little-Endian order)

Block ngalan
Gidak-on sa block (B)
Deskripsyon/Katuyoan
Ang bili (alang sa pipila kini gitakda

chunkId
4
Paghubit sa usa ka file isip usa ka sudlanan sa media
0x52494646 sa Big-Endian (“RIFF”)

tipikSize
4
Gidak-on sa tibuok file nga walay chunkId ug chunkSize
FILE_SIZE - 8

format
4
Type definition gikan sa RIFF
0x57415645 sa Big-Endian (“WAVE”)

subchunk1Id
4
Aron ang file makakuha og dugang nga luna pinaagi sa pagpadayon sa format
0x666d7420 sa Big-Endian (“fmt”)

subchunk1Gidak-on
4
Nabilin nga header (sa bytes)
16 pinaagi sa default (alang sa kaso nga walay audio stream compression)

audioFormat
2
Audio format (depende sa compression method ug audio data structure)
1 (alang sa PCM, nga mao ang among gihunahuna)

numChannels
2
Gidaghan sa mga kanal
1/2, magkuha kami og 1 channel (3/4/5/6/7... - usa ka piho nga audio track, pananglitan 4 para sa quad sound, etc.)

sampleRate
4
Audio sampling rate (sa Hertz)
Ang mas taas, mas maayo ang tingog, apan mas daghang memorya ang gikinahanglan aron makahimo og audio track sa samang gitas-on, ang girekomendar nga bili mao ang 48000 (ang labing madawat nga kalidad sa tingog)

byteRate
4
Gidaghanon sa mga byte matag segundo
sampleRate numChannels bitsPerSample (dugang pa)

blockAlign
2
Gidaghanon sa byte para sa 1 sample
numChannels * bitsPerSample: 8

bitsPerSample
2
Gidaghanon sa mga bit kada 1 sample (gilalim)
Bisan unsa nga numero nga usa ka multiple sa 8. Kon mas taas ang numero, mas maayo ug mas bug-at ang audio, gikan sa 32 bits walay kalainan alang sa mga tawo

subchunk2Id
4
Data reference mark (tungod kay adunay uban nga mga elemento sa header depende sa audioFormat)
0x64617461 sa Big-Endian("data")

subchunk2Gidak-on
4
Gidak-on sa lugar sa datos
gidak-on sa datos sa int

nga data
byteRate * gidugayon sa audio
Audio data
?

Pananglitan sa WAVE

Ang miaging lamesa dali nga mahubad sa usa ka istruktura sa C, apan ang among sinultian karon mao ang Python. Ang labing sayon ​​nga butang nga imong mahimo mao ang paggamit sa usa ka "balud" - usa ka generator sa kasaba. Alang niini nga buluhaton wala kami magkinahanglan og taas nga byteRate ug compression.
Una, atong i-import ang gikinahanglan nga mga module:

# 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)

Sunod, kinahanglan naton nga buhaton ang tanan nga kinahanglan nga mga variable gikan sa lamesa sumala sa ilang mga gidak-on. Ang variable values ​​niini nagdepende lamang sa numSamples (gidaghanon sa mga sample). Kon daghan sila, mas dugay ang atong kasaba.

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)  # сам шум

Ang nahabilin mao ang pagsulat niini sa gikinahanglan nga han-ay (sama sa lamesa):

with open(output_path, 'wb') as fh:
    fh.write(chunkId + chunkSize + Format + subchunk1ID +
            subchunk1Size + audioFormat + numChannels + 
            sampleRate + byteRate + blockAlign + bitsPerSample +
            subchunk2ID + subchunk2Size + data)  # записываем

Ug busa, andam. Aron magamit ang script, kinahanglan natong idugang ang gikinahanglan nga mga argumento sa command line:
python3 WAV.py [num of samples] [output]
gidaghanon sa mga sample - ihap. mga sampol
output — dalan sa output file

Ania ang usa ka link sa usa ka pagsulay nga audio file nga adunay kasaba, apan aron makatipig sa memorya gipaubos nako ang BPS sa 1b / s ug gipaubos ang gidaghanon sa mga channel sa 1 (nga adunay 32-bit nga wala ma-compress nga stereo audio stream sa 64kbs, nahimo kini 80M nga puro .wav file, ug 10 lang): https://instaud.io/3Dcy

Ang tibuok code (WAV.py) (Ang code adunay daghang duplicate variable values, kini usa lang ka sketch):

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)  # записываем в файл результат

Ang resulta

Mao nga nakakat-on ka og gamay bahin sa digital nga tunog ug kung giunsa kini gitipig. Niini nga post wala kami naggamit sa compression (audioFormat), apan aron makonsiderar ang matag usa sa mga sikat, gikinahanglan ang mga artikulo sa 10. Nanghinaut ko nga nakakat-on ka og bag-o alang sa imong kaugalingon ug kini makatabang kanimo sa umaabot nga mga kalamboan.
Спасибо!

Mga tinubdan

WAV file nga istruktura
WAV - Wikipedia

Source: www.habr.com

Idugang sa usa ka comment