Dòighean airson dàta meadhanan a dhlùthadh / a stòradh ann an cruthan WAVE agus JPEG, Pàirt 1

Halò! Bidh a’ chiad sreath de artaigilean agam a’ cuimseachadh air a bhith a’ sgrùdadh dòighean teannachaidh ìomhaigh/claisneachd agus stòradh leithid JPEG (image) agus WAVE (fuaim), agus bheir iad a-steach cuideachd eisimpleirean de phrògraman a’ cleachdadh na cruthan sin (.jpg, .wav) ann an cleachdadh. Anns a’ phàirt seo bheir sinn sùil air WAVE.

История

Is e cruth faidhle soithich a th’ ann an WAVE (Waveform Audio File Format) airson clàradh de shruth claisneachd a stòradh. Mar as trice bithear a’ cleachdadh an t-soithich seo gus claisneachd modhail còd pulse neo-bhrùichte a stòradh. (Air a thoirt bho Wikipedia)

Chaidh a chruthachadh agus fhoillseachadh ann an 1991 còmhla ri RIFF le Microsoft agus IBM (Prìomh chompanaidhean IT aig an àm sin).

Structar faidhle

Tha ceann-cinn aig an fhaidhle, an dàta fhèin, ach chan eil bonn-coise ann. Tha cuideam iomlan de 44 bytes air a’ cheann.
Anns a’ cheann-cinn tha roghainnean airson an àireamh de phìosan san sampall, ìre sampall, doimhneachd fuaim, msaa. fiosrachadh a tha a dhìth airson a’ chairt-fuaim. (Feumar a h-uile luach clàr àireamhach a sgrìobhadh ann an òrdugh Little-Endian)

Ainm bloc
Meud bloca (B)
Tuairisgeul/Adhbhar
Luach (airson cuid tha e stèidhichte

chunkId
4
A 'mìneachadh faidhle mar inneal meadhain
0x52494646 ann an Big-Endian (“RIFF”)

meud meud
4
Meud an fhaidhle gu lèir gun chunkId agus chunkSize
FILE_SIZE - 8

Inneal a 'Chlàir
4
Seòrsa mìneachadh bho RIFF
0x57415645 in Big-Endian (“WAVE”)

subchunk1Id
4
Gus am bi am faidhle a’ gabhail barrachd rùm le bhith a’ leantainn air adhart leis a’ chruth
0x666d7420 ann an Big-Endian (“fmt”)

subchunk1 Meud
4
Ceann-cinn air fhàgail (ann am bytes)
16 gu bunaiteach (airson a’ chùis às aonais teannachadh sruth claisneachd)

cruth claisneachd
2
Cruth claisneachd (an urra ri modh teannachaidh agus structar dàta claisneachd)
1 (airson PCM, is e sin a tha sinn a’ beachdachadh)

numChannels
2
Àireamh de shianalan
1/2, gabhaidh sinn 1 sianal (3/4/5/6/7 ... - slighe claisneachd sònraichte, mar eisimpleir 4 airson claisneachd quad, msaa.)

Ìre sampall
4
Ìre samplachaidh claisneachd (ann an Hertz)
Mar as àirde, is ann as fheàrr a bhios am fuaim, ach mar as motha de chuimhne a bhios a dhìth gus slighe claisneachd den aon fhaid a chruthachadh, is e an luach a thathar a’ moladh 48000 (an càileachd fuaim as iomchaidh).

leiteadh
4
An àireamh de bytes gach diog
Ìre sampall numChannels bitsPerSample (tuilleadh)

blocAlign
2
An àireamh de bytes airson 1 sampall
numChannels * bitsPerSample: 8

bitsPerSample
2
Àireamh de bhuillean gach 1 sampall (doimhneachd)
Àireamh sam bith a tha na iomadachadh de 8. Mar as àirde an àireamh, 's ann as fheàrr agus as truime a bhios an fhuaim; bho 32 pìosan chan eil diofar ann dha daoine

subchunk2Id
4
Comharra fiosrachaidh dàta (leis gum faodadh eileamaidean cinn eile a bhith ann a rèir cruth claisneachd)
0x64617461 ann an Big-Endian ("dàta")

subchunk2 Meud
4
Meud sgìre dàta
meud dàta ann an int

dàta
byteRate * fad claisneachd
Dàta claisneachd
?

eisimpleir WAVE

Faodar an clàr roimhe eadar-theangachadh gu furasta gu structar ann an C, ach is e Python an cànan againn airson an-diugh. Is e an rud as fhasa as urrainn dhut a dhèanamh a bhith a’ cleachdadh “tonn” - gineadair fuaim. Airson na h-obrach seo chan eil feum againn air byteRate àrd agus teannachadh.
An toiseach, leig dhuinn na modalan riatanach a thoirt a-steach:

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

An ath rud, feumaidh sinn na caochladairean riatanach uile a chruthachadh bhon chlàr a rèir am meudan. Tha na luachan caochlaideach ann an crochadh a-mhàin air numSamples (àireamh de shamhlaichean). Mar as motha dhiubh a tha ann, 's ann as fhaide a thèid ar fuaim air adhart.

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

Chan eil air fhàgail ach an sgrìobhadh sìos san t-sreath a tha a dhìth (mar a tha sa chlàr):

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

Agus mar sin, deiseil. Gus an sgriobt a chleachdadh, feumaidh sinn na h-argamaidean loidhne-àithne riatanach a chur ris:
python3 WAV.py [num of samples] [output]
àireamh de shamhlaichean - cunntadh. shampaill
toradh - slighe chun fhaidhle toraidh

Seo ceangal gu faidhle claisneachd deuchainn le fuaim, ach airson cuimhne a shàbhaladh lughdaich mi am BPS gu 1b / s agus lughdaich mi an àireamh de shianalan gu 1 (le sruth claisneachd stereo neo-bhrùichte 32-bit aig 64kbs, thionndaidh e a-mach gu robh e 80M de fhaidhle .wav fìor-ghlan, agus dìreach 10): https://instaud.io/3Dcy

An còd gu lèir (WAV.py) (Tha tòrr luachan caochlaideach dùblaichte aig a’ chòd, chan eil ann an seo ach sgeidse):

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

An toradh

Mar sin tha thu air beagan a bharrachd ionnsachadh mu fhuaim didseatach agus mar a tha e air a stòradh. Anns an dreuchd seo cha do chleachd sinn teannachadh (audioFormat), ach airson beachdachadh air gach fear de na daoine measail, bidh feum air artaigilean 10. Tha mi an dòchas gun do dh’ ionnsaich thu rudeigin ùr dhut fhèin agus cuidichidh seo thu ann an leasachaidhean san àm ri teachd.
Tapadh leibh!

Stòran

Structar faidhle WAV
WAV - Wikipedia

Source: www.habr.com

Cuir beachd ann