Hello! Artikel seri pisananku bakal fokus ing sinau kompresi gambar / audio lan cara panyimpenan kayata JPEG (gambar) lan WAVE (swara), lan uga bakal kalebu conto program sing nggunakake format kasebut (.jpg, .wav) ing praktik. Ing bagean iki kita bakal katon ing WAVE.
История
WAVE (Waveform Audio File Format) minangka format file wadhah kanggo nyimpen rekaman stream audio. Wadah iki biasane digunakake kanggo nyimpen audio modulasi kode pulsa sing ora dikompres. (Dijupuk saka Wikipedia)
Iki diciptakake lan diterbitake ing taun 1991 bebarengan karo RIFF dening Microsoft lan IBM (Perusahaan IT terkemuka ing wektu iku).
Struktur berkas
File kasebut duwe bagean header, data dhewe, nanging ora ana footer. Header bobote total 44 bita.
Header ngemot setelan kanggo jumlah bit ing sampel, tingkat sampel, ambane swara, lsp. informasi sing dibutuhake kanggo kertu swara. (Kabeh nilai tabel numerik kudu ditulis kanthi urutan Little-Endian)
Jeneng blok
Ukuran Blok (B)
Katrangan / Tujuan
Nilai (kanggo sawetara wis tetep
chunkId
4
Nemtokake file minangka wadah media
0x52494646 ing Big-Endian ("RIFF")
ukuran bongkahan
4
Ukuran kabeh file tanpa chunkId lan chunkSize
UKURAN_FILE - 8
format
4
Tipe definisi saka RIFF
0x57415645 ing Big-Endian ("GELOMBANG")
subchunk1 id
4
Supaya file njupuk luwih akeh spasi minangka kelanjutan saka format
0x666d7420 ing Big-Endian ("fmt")
subchunk1 Ukuran
4
Sisa header (ing bita)
16 minangka standar (kanggo kasus tanpa kompresi stream audio)
format audio
2
Format audio (gumantung metode kompresi lan struktur data audio)
1 (kanggo PCM, sing lagi dipikirake)
numChannels
2
Jumlah saluran
1/2, kita bakal njupuk 1 saluran (3/4/5/6/7... - trek audio tartamtu, contone 4 kanggo audio kotak, etc.)
sampleRate
4
Tingkat sampling audio (ing Hertz)
Sing luwih dhuwur, swara sing luwih apik, nanging luwih akeh memori sing dibutuhake kanggo nggawe trek audio kanthi dawa sing padha, nilai sing disaranake yaiku 48000 (kualitas swara sing paling bisa ditampa)
byteRate
4
Jumlah bita per detik
sampleRate numChannels bitsPerSample (luwih)
blockAlign
2
Jumlah bita kanggo 1 sampel
numChannels * bitPerSample: 8
bitPerSample
2
Jumlah bit per 1 sampel (jero)
Sembarang angka sing kelipatan 8. Sing luwih dhuwur nomer kasebut, audio sing luwih apik lan luwih abot saka 32 bit ora ana bedane kanggo manungsa
subchunk2 id
4
Tandha referensi data (amarga ana unsur header liyane gumantung saka format audio)
0x64617461 ing Big-Endian("data")
subchunk2 Ukuran
4
Ukuran area data
ukuran data ing int
data
byteRate * durasi audio
Data audio
?
Tuladha WAVE
Tabel sadurunge bisa gampang diterjemahake menyang struktur ing C, nanging basa kita saiki yaiku Python. Sing paling gampang sampeyan bisa nindakake yaiku nggunakake "gelombang" - generator gangguan. Kanggo tugas iki kita ora perlu dhuwur byteRate lan komprèsi.
Pisanan, ayo ngimpor modul sing dibutuhake:
# 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)Sabanjure, kita kudu nggawe kabeh variabel sing dibutuhake saka tabel miturut ukurane. Nilai variabel kasebut mung gumantung ing numSamples (jumlah sampel). Sing luwih akeh, saya suwe swara kita bakal terus.
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) # сам шумKabeh sing isih ana yaiku nulis ing urutan sing dibutuhake (kaya ing tabel):
with open(output_path, 'wb') as fh:
fh.write(chunkId + chunkSize + Format + subchunk1ID +
subchunk1Size + audioFormat + numChannels +
sampleRate + byteRate + blockAlign + bitsPerSample +
subchunk2ID + subchunk2Size + data) # записываемDadi, siap. Kanggo nggunakake skrip, kita kudu nambah argumen baris perintah sing dibutuhake:
python3 WAV.py [num of samples] [output]
jumlah sampel - count. sampel
output - path menyang file output
Punika link menyang file audio test karo gangguan, nanging kanggo nyimpen memori aku sudo BPS kanggo 1b / s lan sudo nomer saluran kanggo 1 (karo 32-bit uncompressed stream audio stereo ing 64kbs, iku ternyata dadi. 80M file .wav murni, lan mung 10):
Kabeh kode (WAV.py) (Kode kasebut nduweni akeh duplikasi nilai variabel, iki mung sketsa):
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) # записываем в файл результатAsile
Dadi sampeyan wis sinau luwih akeh babagan swara digital lan cara disimpen. Ing postingan iki, kita ora nggunakake kompresi (AudioFormat), nanging kanggo nimbang saben sing populer, 10 artikel bakal dibutuhake, muga-muga sampeyan sinau babagan sing anyar lan iki bakal mbantu sampeyan ing mangsa ngarep.
Matur suwun!
Sumber informasi
Source: www.habr.com
