WAVE සහ JPEG ආකෘතිවලින් මාධ්‍ය දත්ත සම්පීඩනය/ ගබඩා කිරීම සඳහා ක්‍රම, 1 කොටස

ආයුබෝවන්! මගේ පළමු ලිපි මාලාව JPEG (රූපය) සහ WAVE (ශබ්ද) වැනි රූප/ශ්‍රව්‍ය සම්පීඩන සහ ගබඩා ක්‍රම අධ්‍යයනය කිරීම කෙරෙහි අවධානය යොමු කරනු ඇති අතර ප්‍රායෝගිකව මෙම ආකෘති (.jpg, .wav) භාවිතා කරන වැඩසටහන් සඳහා උදාහරණ ද ඇතුළත් වනු ඇත. මෙම කොටසේදී අපි WAVE දෙස බලමු.

කතාව

WAVE (Waveform Audio File Format) යනු ශ්‍රව්‍ය ප්‍රවාහයක පටිගත කිරීමක් ගබඩා කිරීම සඳහා බහාලුම් ගොනු ආකෘතියකි. මෙම කන්ටේනරය සාමාන්‍යයෙන් සම්පීඩිත ස්පන්දන කේතය මොඩියුලේටඩ් ශ්‍රව්‍ය ගබඩා කිරීමට භාවිතා කරයි. (විකිපීඩියාවෙන් උපුටා ගන්නා ලදී)

එය මයික්‍රොසොෆ්ට් සහ අයිබීඑම් (එකල ප්‍රමුඛ පෙළේ තොරතුරු තාක්ෂණ සමාගම්) විසින් RIFF සමඟ එක්ව 1991 දී සොයා ගෙන ප්‍රකාශයට පත් කරන ලදී.

ගොනු ව්යුහය

ගොනුවට ශීර්ෂක කොටසක් ඇත, දත්තම ඇත, නමුත් පාදකයක් නොමැත. ශීර්ෂයේ සම්පූර්ණ බර බයිට් 44 කි.
ශීර්ෂයේ නියැදියේ ඇති බිටු ගණන, නියැදි අනුපාතය, ශබ්ද ගැඹුර යනාදිය සඳහා සැකසුම් අඩංගු වේ. ශබ්ද කාඩ්පත සඳහා අවශ්ය තොරතුරු. (සියලු සංඛ්‍යාත්මක වගු අගයන් ලිට්ල් එන්ඩියන් අනුපිළිවෙලින් ලිවිය යුතුය)

බ්ලොක් නම
වාරණ ප්‍රමාණය (B)
විස්තරය/අරමුණ
අගය (සමහරු සඳහා එය ස්ථාවර වේ

chunkId
4
ගොනුවක් මාධ්‍ය බහාලුමක් ලෙස අර්ථ දැක්වීම
Big-Endian හි 0x52494646 ("RIFF")

chunkSize
4
chunkId සහ chunkSize නොමැතිව සම්පූර්ණ ගොනුවේ ප්‍රමාණය
FILE_SIZE - 8

ආකෘතිය
4
RIFF වෙතින් අර්ථ දැක්වීම ටයිප් කරන්න
Big-Endian හි 0x57415645 ("WAVE")

subchunk1Id
4
එබැවින් ආකෘතිය දිගටම කරගෙන යාමෙන් ගොනුව වැඩි ඉඩක් ගනී
Big-Endian හි 0x666d7420 ("fmt")

subchunk1size
4
ඉතිරි ශීර්ෂකය (බයිට් වලින්)
16 පෙරනිමියෙන් (ශ්‍රව්‍ය ප්‍රවාහ සම්පීඩනය නොමැති නඩුව සඳහා)

ශ්රව්ය ආකෘතිය
2
ශ්‍රව්‍ය ආකෘතිය (සම්පීඩන ක්‍රමය සහ ශ්‍රව්‍ය දත්ත ව්‍යුහය මත රඳා පවතී)
1 (PCM සඳහා, අප සලකා බලන්නේ එයයි)

numChannels
2
නාලිකා ගණන
1/2, අපි 1 නාලිකාවක් ගනිමු (3/4/5/6/7... - නිශ්චිත ශ්‍රව්‍ය පථයක්, උදාහරණයක් ලෙස 4 ශ්‍රව්‍ය සඳහා, ආදිය)

නියැදි අනුපාතය
4
ශ්‍රව්‍ය නියැදි අනුපාතය (හර්ට්ස් වලින්)
වැඩි වන තරමට ශබ්දය වඩා හොඳ වනු ඇත, නමුත් එකම දිගකින් යුත් ශ්‍රව්‍ය පථයක් සෑදීමට වැඩි මතකයක් අවශ්‍ය වේ, නිර්දේශිත අගය 48000 (වඩාත් පිළිගත හැකි ශබ්ද ගුණය)

byteRate
4
තත්පරයකට බයිට් ගණන
නියැදි අනුපාතය numChannels bitsPerSample (තවත්)

අවහිර කරන්න
2
සාම්පල 1ක් සඳහා බයිට් ගණන
numChannels * bitsPerSample: 8

bitsPerSample
2
සාම්පල 1කට බිටු ගණන (ගැඹුර)
8 හි ගුණාකාරයක් වන ඕනෑම සංඛ්‍යාවක්. සංඛ්‍යාව වැඩි වන තරමට ශ්‍රව්‍ය වඩා හොඳ සහ බර වනු ඇත; බිටු 32 සිට මිනිසුන්ට වෙනසක් නැත.

subchunk2Id
4
දත්ත සමුද්දේශ සලකුණ (ශ්‍රව්‍ය ආකෘතිය මත පදනම්ව වෙනත් ශීර්ෂ මූලද්‍රව්‍ය තිබිය හැකි බැවින්)
Big-Endian ("දත්ත") හි 0x64617461

subchunk2size
4
දත්ත ප්රදේශයේ ප්රමාණය
දත්ත ප්රමාණය int

දත්ත
byteRate * ශ්‍රව්‍ය කාල සීමාව
ශ්රව්ය දත්ත
?

WAVE උදාහරණය

පෙර වගුව පහසුවෙන් C හි ව්‍යුහයකට පරිවර්තනය කළ හැකි නමුත් අද අපගේ භාෂාව පයිතන් වේ. ඔබට කළ හැකි පහසුම දෙය නම් "රැල්ලක්" - ශබ්ද උත්පාදක යන්ත්රයක් භාවිතා කිරීමයි. මෙම කාර්යය සඳහා අපට ඉහළ බයිට් රේට් සහ සම්පීඩනය අවශ්‍ය නොවේ.
පළමුව, අවශ්‍ය මොඩියුල ආයාත කරමු:

# 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]
සාම්පල ගණන - ගණන් කරන්න. සාම්පල
output — ප්‍රතිදාන ගොනුව වෙත මාර්ගය

මෙන්න ශබ්දය සහිත පරීක්ෂණ ශ්‍රව්‍ය ගොනුවකට සබැඳියක්, නමුත් මතකය සුරැකීමට මම BPS 1b/s දක්වා පහත් කර නාලිකා සංඛ්‍යාව 1 දක්වා අඩු කළෙමි (බිට් 32-සම්පීඩනය නොකළ ස්ටීරියෝ ශ්‍රව්‍ය ප්‍රවාහයක් 64kbs සමඟ, එය එසේ විය. පිරිසිදු .wav ගොනුව 80M, සහ 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

අදහස් එක් කරන්න