áááºá¹ááá¬áá«! áá»áœááºá¯ááºáááááá¯á¶ážáá±á¬ááºážáá«ážá á®ážáá®ážáá»á¬ážááẠJPEG (áá¯ááºáá¯á¶) ááŸáá·áº WAVE (á¡áá¶) áá²á·ááá¯á·áá±á¬ áá¯ááºáá¯á¶/á¡áá¶áá»á¯á¶á·ááŒááºážááŸáá·áº ááá¯ááŸá±á¬ááºááŸá¯áááºážáááºážáá»á¬ážááᯠáá±á·áá¬ááŒááºážá¡áá±á«áº á¡á¬áá¯á¶á áá¯ááºáááºááŒá áºááŒá®áž áááºááœá±á·ááœáẠá¡ááá¯áá«áá±á¬áºáááºáá»á¬áž (.jpg, .wav) á¡áá¯á¶ážááŒá¯áá¬ážáá±á¬ áááá¯ááááºáá»á¬ážá ááá°áá¬áá»á¬ážáááºáž áá«áááºáááºááŒá áºáááºá áá®á¡ááá¯ááºážááŸá¬áá±á¬á· WAVE ááᯠááŒáá·áºáá«áááºá
áá¯á¶ááŒááº
WAVE (Waveform Audio File Format) ááẠá¡á±á¬áºáá®ááá¯á á®ážááŒá±á¬ááºážáá áºáá¯á á¡áá¶ááœááºážááŒááºážááᯠááááºážáááºážáááºá¡ááœáẠááœááºááááºáá¬ááá¯ááºáá±á¬áºáááºáá áºáá¯ááŒá áºáááºá áá¯á¶ááŸááºá¡á¬ážááŒáá·áº á€ááœááºááááºáá¬ááᯠáá»á¯á¶á·ááá¬ážáá±á¬ ááœá±ážáá¯ááºááŸá¯ááºážáá¯ááºááŒáá·áº ááŒá¯ááŒááºáá¬ážáá±á¬ á¡áá¶ááᯠááááºážáááºážááẠá¡áá¯á¶ážááŒá¯áááºá (áá®áá®áá®ážáá®ážáá¬ážááŸáá°ážáá°áááº)
áááºážááᯠMicrosoft ááŸáá·áº IBM (ááá¯áá±ááºá ááááºáááºáž á¡áá¯ááºáá®áá¯áá¹ááá®áá»á¬áž) á០RIFF ááŸáá·áºá¡áá° 1991 áá¯ááŸá áºááœáẠáá®ááœááºáá¯ááºáá±áá²á·áááºá
ááá¯ááºááœá²á·á ááºážáá¯á¶
ááá¯ááºááœáẠáá±á«ááºážá
á®ážá¡ááá¯ááºážá áá±áá¬ááá¯ááºááá¯ááºáá«ááŸááá±á¬áºáááºáž á¡á±á¬ááºááŒá±ááŸááºá
á¯áááŸááá«á áá±á«ááºážá
á®ážááẠá
á¯á
á¯áá±á«ááºáž 44 bytes á¡áá±ážáá»áááºááŸááááºá
áá±á«ááºážá
á®ážááœáẠááá°áá¬ááŸá áá
áºá¡áá±á¡ááœááºá ááá°áá¬ááŸá¯ááºážá á¡áá¶á¡ááááºá¡áááºá á
áááºááá¯á·á¡ááœáẠáááºáááºáá»á¬áž áá«ááŸááááºá á¡áá¶áááºá¡ááœááºááá¯á¡ááºáá±á¬á¡áá»ááºá¡áááºáá»á¬ážá (ááááºážááá¬ážáááºááá¯ážá¡á¬ážáá¯á¶ážááᯠLittle-Endian á¡á
á®á¡á
ááºááŒáá·áº áá±ážáá¬ážááá«áááº)
ááááºááá¯á·á¡áááº
ááááºááá¯á·á¡ááœááºá¡á
á¬áž (B)
áá±á¬áºááŒáá»ááº/áááºááœááºáá»ááº
áááºááá¯áž (á¡áá»áá¯á·á¡ááœááºáááºážááá¯áááºááŸááºáá¬ážáááºá
chunkId
4
ááá¯ááºááᯠáá®áá®áá¬ááœááºááááºáá¬á¡ááŒá
ẠáááºááŸááºááŒááºážá
Big-Endian ááœáẠ0x52494646 ("RIFF")
á¡áá¯á¶ážá¡ááœááºá¡á
á¬áž
4
chunkId ááŸáá·áº chunkSize ááá«áá² ááá¯ááºáá
áºáá¯áá¯á¶ážá á¡ááœááºá¡á
á¬áž
FILE_SIZE - á
áá¯á¶á
á¶
4
RIFF á០á¡áááá¹áá«ááºááœáá·áºááá¯áá»ááºááᯠááá¯ááºááá·áºáá«á
Big-Endian ááœáẠ0x57415645 (âWAVEâ)
subchunk1Id
4
áá±á¬áºáááºáááºáá¯ááºááŒááºážááŒáá·áº ááá¯ááºááẠáá±áá¬ááá¯áá°ááá¯ááºá
á±áááº
Big-Endian ááœáẠ0x666d7420 (âfmtâ)
á¡ááá¯ááºáž á á¡ááœááºá¡á
á¬áž
4
áááºáá»áẠáá±á«ááºážá
á®áž (ááá¯ááºáá»á¬áž)
16 áá°áááºážá¡ááá¯ááºáž (á¡áá¶á
á®ážááŒá±á¬ááºážáá»á¯á¶á·ááŒááºážáááŸááá² ááá
á¹á
á¡ááœááº)
á¡áá¶áá±á¬áºáááº
2
á¡áá¶áá±á¬áºááẠ(áá»á¯á¶á·áááºážááŸáá·áº á¡áá¶áá±áá¬ááœá²á·á
ááºážáá¯á¶á¡áá±á«áº áá°áááºáááº)
1 (PCM á¡ááœááºá áá»áœááºá¯ááºááá¯á· á
ááºážá
á¬ážáá±áááº)
ááá¯ááºážáá»á¬áž
2
ááá¯ááºážá¡áá±á¡ááœááº
1/2á áá»ááºááẠ1 áᯠ(3/4/5/6/7... - áá®ážááŒá¬ážá¡á±á¬áºáá®ááá¯áá
áºáá¯ááºá á¥ááᬠquad audio á¡ááœáẠ4 áá¯á á
áááºááŒáá·áº)
ááá°áá¬ááŸá¯ááºáž
4
á¡áá¶ááá°áá¬ááŸá¯ááºáž (Hertz ááŒáá·áº)
ááá¯ááŒáá·áºáá±á á¡áá¶ááá¯áá±á¬ááºážáá±á ááá¯á·áá±á¬áº áá°áá®áá±á¬á¡áá»á¬ážááŸááá±á¬ á¡á±á¬áºáá®ááá¯áá±ážááœá¬ážááᯠáááºáá®ážááẠáááºááá¯áá® ááá¯áá»á¬ážáá±áá±á á¡ááŒá¶ááŒá¯áá¬ážáá±á¬ áááºááá¯ážááŸá¬ 48000 (áááºáá¶ááá¯ááºáá¯á¶ážáá±á¬ á¡áá¶á¡áááºá¡ááœá±áž)
byteRate
4
áá
áºá
áá¹ááá·áºáá»áŸáẠbytes á¡áá±á¡ááœááº
ááá°áá¬ááŸá¯ááºáž ááá¯ááºážáá»á¬áž bitsPerSample (áá±á¬ááºáááº)
blockAlign
2
ááá°áᬠ1 á¡ááœáẠááá¯ááºá¡áá±á¡ááœááº
numChannels * bitsPerSample: á
bitsPerSample
2
ááá°áᬠ1 áá¯á¡ááœáẠáá
áºá¡áá±á¡ááœáẠ(á¡ááááºá¡áááº)
8 ááŸáá·áº áá±á«ááºážáá¬ážáá±á¬ áááºááá·áºááááºážáááᯠá¡áá±á¡ááœááºáá»á¬ážáá±áá± á¡áá¶ááá¯áá±á¬ááºážáá±áá±á 32 bits ááŸááẠáá°áá¬ážáá»á¬ážá¡ááœáẠááœá¬ááŒá¬ážáá»ááºáááŸááá±á
subchunk2Id
4
áá±áá¬áááºááœáŸááºážá¡ááŸááºá¡áá¬áž (á¡áá¶áá±á¬áºáááºáá±á«áºáá°áááºá á¡ááŒá¬ážáá±á«ááºážá
á®ážá¡á
áááºá¡ááá¯ááºážáá»á¬áž ááŸáááá¯ááºáá±á¬ááŒá±á¬áá·áº)
Big-Endian("áá±áá¬") ááœáẠ0x64617461
á¡ááá¯ááºáž á á¡ááœááºá¡á
á¬áž
4
áá±áá¬á§áááá¬á¡ááœááºá¡á
á¬áž
int ááœááºáá±áá¬á¡ááœááºá¡á
á¬áž
áá±áá¬
byteRate * á¡áá¶ááŒá¬áá»áááº
á¡áá¶áá±áá¬
?
WAVE á¥ááá¬
ááááºááá¬ážááᯠC ááŒáá·áºááœá²á·á
ááºážáá¯á¶ááá¯á· á¡ááœááºááá°ááŒááºááá¯ááá¯ááºáá±á¬áºáááºáž ááá±á·áá»áœááºá¯ááºááá¯á·ááá¬áá¬á
áá¬ážááŸá¬ Python ááŒá
áºáááºá áááºáá¯ááºááá¯ááºáá±á¬á¡ááœááºáá¯á¶ážá¡áá¬ááŸá¬ "ááŸáá¯ááºáž" - áá°áá¶áá¶áá»ááºááá±áá¬ááá¯áá¯á¶ážáá«á á€áá¯ááºáááºážá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááŒáá·áºáá¬ážáá±á¬ byteRate ááŸáá·áº compression áááá¯á¡ááºáá«á
ááááŠážá
áœá¬ ááá¯á¡ááºáá±á¬ 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)
ááá¯á·áá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááẠáááºážááá¯á·á á¡ááœááºá¡á á¬ážá¡ááá¯áẠááá¬ážá០ááá¯á¡ááºáá±á¬ variable á¡á¬ážáá¯á¶ážááᯠáááºáá®ážááẠááá¯á¡ááºáááºá áááºážááŸá ááááºážááŸááºáááºááá¯ážáá»á¬ážááẠnumSamples (ááá°áá¬á¡áá±á¡ááœááº) áá±á«áºááœááºáᬠáá°áááºáááºá áá°ááá¯á·ááœá± áá»á¬ážáá±áá± áá«ááá¯á·áá²á· áá°áá¶áá¶á ááá¯ááŒá¬áá±áá±áá«áá²á
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) # ÑаЌ ÑÑÐŒ
áá»ááºáá¬á¡á¬ážáá¯á¶ážááᯠááá¯á¡ááºáá±á¬ sequence (ááá¬ážááœááºáá«ááá·áºá¡ááá¯ááºáž) áá±ážááŸááºáá¬ážáááºááŒá áºáá«áááºá
with open(output_path, 'wb') as fh:
fh.write(chunkId + chunkSize + Format + subchunk1ID +
subchunk1Size + audioFormat + numChannels +
sampleRate + byteRate + blockAlign + bitsPerSample +
subchunk2ID + subchunk2Size + data) # запОÑÑваеЌ
áá«ááŒá±á¬áá·áº á¡áááºááá·áºááŒá
áºáá±áá«ááŒá®á script ááá¯á¡áá¯á¶ážááŒá¯áááºá ááá¯á¡ááºáá±á¬ command line arguments áá»á¬ážááá¯ááá·áºáááºááá¯á¡ááºáááº-
python3 WAV.py [num of samples] [output]
ááá°áá¬á¡áá±á¡ááœáẠ- á¡áá±á¡ááœááºá ááá°áá¬áá»á¬áž
output â á¡ááœááºááá¯ááºááá¯á· áááºážááŒá±á¬ááºáž
á€áááºááŸá¬ áá°áá¶áá¶áá«áá±á¬ á
ááºážáááºá¡áá¶ááá¯ááºáá
áºáá¯ááá¯á· ááá·áºááºáá
áºáá¯ááŒá
áºáá«áááºá ááá¯á·áá±á¬áº áááºááá¯áá®ááᯠááááºážáááºážáááºá¡ááœáẠáá»áœááºá¯ááºááẠBPS ááᯠ1b/s ááá¯á· áá»áŸá±á¬á·áá»ááá¯ááºááŒá®áž áá»ááºáááºá¡áá±á¡ááœááºááᯠ1 ááá¯á· áá»áŸá±á¬á·áá»áá²á·ááẠ(32-bit ááá»á¯á¶á·ááá¬ážáá±á¬ á
áá®áá®ááᯠá¡á±á¬áºáá®ááá¯áá¯ááºááœáŸáá·áºááŸá¯ááœáẠ64kbs ááŒáá·áº ááŒá
áºáá¬áá²á·áááºá ááá·áºá
ááºáá±á¬ .wav ááá¯áẠ80M ááŸáá·áº 10 áá¯áá¬)á
áá¯ááºáá áºáá¯áá¯á¶áž (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)
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) # запОÑÑваеЌ в Ñайл ÑезÑлÑÑаÑ
ááááº
ááá¯á·ááŒá±á¬áá·áº áá
áºáá»á
áºáááºá¡áá¶ááŸáá·áº áááºážááᯠááááºážáááºážáá¯á¶á¡ááŒá±á¬ááºáž á¡áááºážááẠááá¯áá±á·áá¬ááŒá®ážááŒá
áºáááºá á€ááá¯á·á
áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠcompression (audioFormat) ááá¯á¡áá¯á¶ážáááŒá¯áá² áá°ááŒáá¯ááºáá»á¬ážáá±á¬á¡ááŒá±á¬ááºážá¡áá¬áá
áºáá¯á
á®ááá¯áá¯á¶ážáááºáááºá¡ááœáẠáá±á¬ááºážáá«áž 10 áᯠááá¯á¡ááºáááºááŒá
áºáá«áááºá áááºááá¯ááºááá¯ááºá¡ááœáẠá¡áá
áºá¡áááºážáá
áºáá¯áá¯ááᯠáááºáá°áá²á·ááŒá®áž áááºážááẠááá·áºá¡á¬áž á¡áá¬áááºááá¯ážáááºááŸá¯áá»á¬ážááœáẠáá°áá®áá±ážáááá·áºáááºáᯠáá»áŸá±á¬áºááá·áºáá«áááºá
Thank you!
ááááºážáááºážááŒá áº
source: www.habr.com