ืฉื™ื˜ื•ืช ืœื“ื—ื™ืกืช/ืื—ืกื•ืŸ ื ืชื•ื ื™ ืžื“ื™ื” ื‘ืคื•ืจืžื˜ื™ื WAVE ื•-JPEG, ื—ืœืง 1

ืฉืœื•ื! ืกื“ืจืช ื”ืžืืžืจื™ื ื”ืจืืฉื•ื ื” ืฉืœื™ ืชืชืžืงื“ ื‘ืœื™ืžื•ื“ ื“ื—ื™ืกืช ืชืžื•ื ื”/ืฉืžืข ื•ืฉื™ื˜ื•ืช ืื—ืกื•ืŸ ื›ืžื• JPEG (ืชืžื•ื ื”) ื•-WAVE (ืกืื•ื ื“), ื•ืชื›ืœื•ืœ ื’ื ื“ื•ื’ืžืื•ืช ืœืชื•ื›ื ื™ื•ืช ื”ืžืฉืชืžืฉื•ืช ื‘ืคื•ืจืžื˜ื™ื ืืœื• (.jpg, .wav) ื‘ืคื•ืขืœ. ื‘ื—ืœืง ื–ื” ื ืกืชื›ืœ ืขืœ WAVE.

ื›ืชื‘ื”

WAVE (Waveform Audio File Format) ื”ื•ื ืคื•ืจืžื˜ ืงื•ื‘ืฅ ืžื™ื›ืœ ืœืื—ืกื•ืŸ ื”ืงืœื˜ื” ืฉืœ โ€‹โ€‹ื–ืจื ืฉืžืข. ืžื™ื›ืœ ื–ื” ืžืฉืžืฉ ื‘ื“ืจืš ื›ืœืœ ืœืื—ืกื•ืŸ ืื•ื“ื™ื• ืžืื•ืคื ืŸ ื‘ืงื•ื“ ืคื•ืœืก ืœื ื“ื—ื•ืก. (ืœืงื•ื— ืžื•ื™ืงื™ืคื“ื™ื”)

ื”ื•ื ื”ื•ืžืฆื ื•ืคื•ืจืกื ื‘-1991 ื™ื—ื“ ืขื RIFF ืขืœ ื™ื“ื™ ืžื™ืงืจื•ืกื•ืคื˜ ื•-IBM (ื—ื‘ืจื•ืช IT ืžื•ื‘ื™ืœื•ืช ืฉืœ ืื–).

ืžื‘ื ื” ื”ืงื•ื‘ืฅ

ืœืงื•ื‘ืฅ ื™ืฉ ื—ืœืง ื›ื•ืชืจืช ืขืœื™ื•ื ื”, ื”ื ืชื•ื ื™ื ืขืฆืžื, ืืš ืœืœื ื›ื•ืชืจืช ืชื—ืชื•ื ื”. ื”ื›ื•ืชืจืช ืฉื•ืงืœืช ื‘ืกืš ื”ื›ืœ 44 ื‘ืชื™ื.
ื”ื›ื•ืชืจืช ืžื›ื™ืœื” ื”ื’ื“ืจื•ืช ืœืžืกืคืจ ื”ื‘ื™ื˜ื™ื ื‘ื“ื’ื™ืžื”, ืงืฆื‘ ื”ื“ื’ื™ืžื”, ืขื•ืžืง ื”ืฆืœื™ืœ ื•ื›ื•'. ืžื™ื“ืข ื”ื“ืจื•ืฉ ืขื‘ื•ืจ ื›ืจื˜ื™ืก ื”ืงื•ืœ. (ื›ืœ ืขืจื›ื™ ื”ื˜ื‘ืœื” ื”ืžืกืคืจื™ืช ื—ื™ื™ื‘ื™ื ืœื”ื™ื›ืชื‘ ื‘ืกื“ืจ ืœื™ื˜ืœ-ืื ื“ื™)

ืฉื ื‘ืœื•ืง
ื’ื•ื“ืœ ื‘ืœื•ืง (B)
ืชื™ืื•ืจ/ืžื˜ืจื”
ืขืจืš (ืขื‘ื•ืจ ื—ืœืง ื–ื” ืงื‘ื•ืข

chunkId
4
ื”ื’ื“ืจืช ืงื•ื‘ืฅ ื›ืžื™ื›ืœ ืžื“ื™ื”
0x52494646 ื‘-Big-Endian ("RIFF")

chunkSize
4
ื’ื•ื“ืœ ื”ืงื•ื‘ืฅ ื›ื•ืœื• ืœืœื chunkId ื•-chunkSize
FILE_SIZE - 8

ืคื•ึผืจืžึธื˜
4
ื”ื’ื“ืจืช ืกื•ื’ ืž-RIFF
0x57415645 ื‘-Big-Endian ("WAVE")

subchunk1Id
4
ื›ืš ืฉื”ืงื•ื‘ืฅ ืชื•ืคืก ื™ื•ืชืจ ืžืงื•ื ื›ื”ืžืฉืš ืœืคื•ืจืžื˜
0x666d7420 ื‘-Big-Endian ("fmt")

subchunk1Size
4
ื›ื•ืชืจืช ืฉื ื•ืชืจื” (ื‘ื‘ืชื™ื)
16 ื›ื‘ืจื™ืจืช ืžื—ื“ืœ (ืœืžืงืจื” ืœืœื ื“ื—ื™ืกืช ื–ืจื ืฉืžืข)

ืื•ื“ื™ื•ืคื•ืจืžื˜
2
ืคื•ืจืžื˜ ืฉืžืข (ืชืœื•ื™ ื‘ืฉื™ื˜ืช ื”ื“ื—ื™ืกื” ื•ื‘ืžื‘ื ื” ื ืชื•ื ื™ ื”ืฉืžืข)
1 (ืขื‘ื•ืจ PCM, ื•ื–ื” ืžื” ืฉืื ื—ื ื• ืฉื•ืงืœื™ื)

numChannels
2
ืžืกืคืจ ื”ืขืจื•ืฆื™ื
1/2, ื ื™ืงื— ืขืจื•ืฅ 1 (3/4/5/6/7... - ืจืฆื•ืขืช ืฉืžืข ืกืคืฆื™ืคื™ืช, ืœืžืฉืœ 4 ืขื‘ื•ืจ ืกืื•ื ื“ ืžืจื•ื‘ืข ื•ื›ื•')

ืงืฆื‘ ื“ื’ื™ืžื”
4
ืงืฆื‘ ื“ื’ื™ืžืช ืื•ื“ื™ื• (ื‘ื”ืจืฅ)
ื›ื›ืœ ืฉื”ืกืื•ื ื“ ื™ื”ื™ื” ื’ื‘ื•ื” ื™ื•ืชืจ, ื”ืกืื•ื ื“ ื™ื”ื™ื” ื˜ื•ื‘ ื™ื•ืชืจ, ืืš ื›ื›ืœ ืฉื™ื™ื“ืจืฉ ื™ื•ืชืจ ื–ื™ื›ืจื•ืŸ ืœื™ืฆื™ืจืช ืจืฆื•ืขืช ืฉืžืข ื‘ืื•ืชื• ืื•ืจืš, ื”ืขืจืš ื”ืžื•ืžืœืฅ ื”ื•ื 48000 (ืื™ื›ื•ืช ื”ืกืื•ื ื“ ื”ืžืงื•ื‘ืœืช ื‘ื™ื•ืชืจ)

byteRate
4
ืžืกืคืจ ื‘ืชื™ื ืœืฉื ื™ื™ื”
ืงืฆื‘ ื“ื’ื™ืžื” numChannels bitsPerSample (ืขื•ื“)

blockAlign
2
ืžืกืคืจ ื‘ืชื™ื ืขื‘ื•ืจ ื“ื•ื’ืžื” ืื—ืช
numChannels * bitsPerSample: 8

bitsPerSample
2
ืžืกืคืจ ื‘ื™ื˜ื™ื ืœื“ื’ื™ืžื” ืื—ืช (ืขื•ืžืง)
ื›ืœ ืžืกืคืจ ืฉื”ื•ื ื›ืคื•ืœื” ืฉืœ 8. ื›ื›ืœ ืฉื”ืžืกืคืจ ื’ื‘ื•ื” ื™ื•ืชืจ, ื”ืื•ื“ื™ื• ื™ื”ื™ื” ื˜ื•ื‘ ื•ื›ื‘ื“ ื™ื•ืชืจ; ืž-32 ืกื™ื‘ื™ื•ืช ืื™ืŸ ื”ื‘ื“ืœ ืขื‘ื•ืจ ื‘ื ื™ ืื“ื

subchunk2Id
4
ืกื™ืžืŸ ื”ืชื™ื™ื—ืกื•ืช ืœื ืชื•ื ื™ื (ืžื›ื™ื•ื•ืŸ ืฉืขืฉื•ื™ื™ื ืœื”ื™ื•ืช ืจื›ื™ื‘ื™ ื›ื•ืชืจืช ืื—ืจื™ื ื‘ื”ืชืื ืœ-audioFormat)
0x64617461 ื‘-Big-Endian("ื ืชื•ื ื™ื")

subchunk2Size
4
ื’ื•ื“ืœ ืฉื˜ื— ื”ื ืชื•ื ื™ื
ื’ื•ื“ืœ ื”ื ืชื•ื ื™ื ื‘-int

ื ืชื•ื ื™ื
byteRate * ืžืฉืš ืฉืžืข
ื ืชื•ื ื™ ืื•ื“ื™ื•
?

ื“ื•ื’ืžื” ืฉืœ WAVE

ื ื™ืชืŸ ืœืชืจื’ื ื‘ืงืœื•ืช ืืช ื”ื˜ื‘ืœื” ื”ืงื•ื“ืžืช ืœืžื‘ื ื” ื‘-C, ืื‘ืœ ื”ืฉืคื” ืฉืœื ื• ืœื”ื™ื•ื ื”ื™ื Python. ื”ื“ื‘ืจ ื”ืงืœ ื‘ื™ื•ืชืจ ืฉืืชื” ื™ื›ื•ืœ ืœืขืฉื•ืช ื”ื•ื ืœื”ืฉืชืžืฉ ื‘"ื’ืœ" - ืžื—ื•ืœืœ ืจืขืฉ. ืขื‘ื•ืจ ืžืฉื™ืžื” ื–ื• ืื™ื ื ื• ื–ืงื•ืงื™ื ืœ-byteRate ื•ื“ื—ื™ืกื” ื’ื‘ื•ื”ื™ื.
ืจืืฉื™ืช, ื‘ื•ืื• ืœื™ื™ื‘ื ืืช ื”ืžื•ื“ื•ืœื™ื ื”ื“ืจื•ืฉื™ื:

# 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 (ืžืกืคืจ ื”ื“ื’ื™ืžื•ืช). ื›ื›ืœ ืฉื™ื”ื™ื• ื™ื•ืชืจ ืžื”ื, ื›ืš ื”ืจืขืฉ ืฉืœื ื• ื™ื™ืžืฉืš ื–ืžืŸ ืจื‘ ื™ื•ืชืจ.

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)  # ัะฐะผ ัˆัƒะผ

ื›ืœ ืฉื ื•ืชืจ ื”ื•ื ืœืจืฉื•ื ืื•ืชื ื‘ืจืฆืฃ ื”ื ื“ืจืฉ (ื›ืžื• ื‘ื˜ื‘ืœื”):

with open(output_path, 'wb') as fh:
    fh.write(chunkId + chunkSize + Format + subchunk1ID +
            subchunk1Size + audioFormat + numChannels + 
            sampleRate + byteRate + blockAlign + bitsPerSample +
            subchunk2ID + subchunk2Size + data)  # ะทะฐะฟะธัั‹ะฒะฐะตะผ

ื•ื›ืš, ืžื•ื›ืŸ. ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ืกืงืจื™ืคื˜, ืขืœื™ื ื• ืœื”ื•ืกื™ืฃ ืืช ื”ืืจื’ื•ืžื ื˜ื™ื ื”ื ื—ื•ืฆื™ื ืฉืœ ืฉื•ืจืช ื”ืคืงื•ื“ื”:
python3 WAV.py [num of samples] [output]
ืžืกืคืจ ื“ื’ื™ืžื•ืช - ืกืคื™ืจื”. ื“ื’ื™ืžื•ืช
ืคืœื˜ - ื ืชื™ื‘ ืœืงื•ื‘ืฅ ื”ืคืœื˜

ื”ื ื” ืงื™ืฉื•ืจ ืœืงื•ื‘ืฅ ืื•ื“ื™ื• ืœื ื™ืกื™ื•ืŸ ืขื ืจืขืฉ, ืื‘ืœ ื›ื“ื™ ืœื—ืกื•ืš ื‘ื–ื™ื›ืจื•ืŸ ื”ื•ืจื“ืชื™ ืืช ื”-BPS ืœ-1b/s ื•ื”ื•ืจื“ืชื™ ืืช ืžืกืคืจ ื”ืขืจื•ืฆื™ื ืœ-1 (ืขื ื–ืจื ืื•ื“ื™ื• ืกื˜ืจื™ืื• ืœื ื“ื—ื•ืก ืฉืœ 32 ืกื™ื‘ื™ื•ืช ื‘-64kbs, ื”ืชื‘ืจืจ ืฉื›ืŸ 80M ืฉืœ ืงื•ื‘ืฅ WAV ื˜ื”ื•ืจ, ื•ืจืง 10): https://instaud.io/3Dcy

ื”ืงื•ื“ ื›ื•ืœื• (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)  # ะทะฐะฟะธัั‹ะฒะฐะตะผ ะฒ ั„ะฐะนะป ั€ะตะทัƒะปัŒั‚ะฐั‚

ืกืš ื”ื›ืœ

ืื– ืœืžื“ืช ืงืฆืช ื™ื•ืชืจ ืขืœ ืกืื•ื ื“ ื“ื™ื’ื™ื˜ืœื™ ื•ื›ื™ืฆื“ ื”ื•ื ื ืฉืžืจ. ื‘ืคื•ืกื˜ ื”ื–ื” ืœื ื”ืฉืชืžืฉื ื• ื‘ื“ื—ื™ืกื” (audioFormat), ืื‘ืœ ื›ื“ื™ ืœื”ืชื—ืฉื‘ ื‘ื›ืœ ืื—ื“ ืžื”ืคื•ืคื•ืœืจื™ื™ื, ื™ื™ื“ืจืฉื• 10 ืžืืžืจื™ื. ืื ื™ ืžืงื•ื•ื” ืฉืœืžื“ืช ืžืฉื”ื• ื—ื“ืฉ ื‘ืขืฆืžืš ื•ื–ื” ื™ืขื–ื•ืจ ืœืš ื‘ื”ืชืคืชื—ื•ื™ื•ืช ืขืชื™ื“ื™ื•ืช.
ืชื•ื“ื” ืœืš!

ืžืงื•ืจื•ืช

ืžื‘ื ื” ืงื•ื‘ืฅ WAV
WAV - ื•ื™ืงื™ืคื“ื™ื”

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”