Steve2/convert_spkr_buf_to_wav.py

60 lines
2.8 KiB
Python
Raw Normal View History

2024-01-06 15:11:52 +00:00
#!/usr/local/bin/python3
### Convert SPKR Buffer to WAV -- (c) by Tamas Rudnai 2022
###
### This utility convert SPKR buffer output to an uncompressed WAV file
###
### Purpose is that sound generation can be analyzed by audio editor - Audacity for example
###
import os
import sys
import struct
# binpath = '/Users/trudnai/Library/Containers/com.trudnai.steveii/Data/'
# binfilename = binpath + 'steve2_audio_debug.bin'
def convert_bin_to_audio(filename):
data_size = os.path.getsize(filename)
channels = 2
sample_rate = 1023000 # 192000 # must be the same as in speaker.c : spkr_sample_rate
bits_per_sample = 16
header_size = 44
with open( filename, 'rb') as binfile:
wavfilename = os.path.splitext( os.path.basename(filename) )[0] + '.wav'
with open( wavfilename, 'wb+') as wavfile:
# WAV HEADER
wavfile.write( 'RIFF'.encode() ) # Marks the file as a riff file. Characters are each 1 byte long
wavfile.write( struct.pack('I', data_size + header_size ) ) # Size of the overall file - 8 bytes, in bytes (32-bit integer). Typically youd fill this in after creation
wavfile.write( 'WAVE'.encode() ) # File Type Header. For our purposes, it always equals “WAVE”
# FMT HEADER
wavfile.write( 'fmt '.encode() ) # Format chunk marker. Includes trailing null (tr: Space works, null don't)
wavfile.write( struct.pack('I', 16 ) ) # Length of format data as listed above
# FMT DATA
wavfile.write( struct.pack('H', 1 ) ) # Type of format (1 is PCM) - 2 byte integer
wavfile.write( struct.pack('H', channels ) ) # Number of Channels - 2 byte integer
wavfile.write( struct.pack('I', sample_rate ) ) # Sample Rate - 32 byte integer. Common values are 44100 (CD), 48000 (DAT). Sample Rate = Number of Samples per second, or Hertz
wavfile.write( struct.pack('I', int(sample_rate * bits_per_sample * channels / 8) ) ) # (Sample Rate * BitsPerSample * Channels) / 8
wavfile.write( struct.pack('H', 4 ) ) # 0: (BitsPerSample * Channels) / 8
# 1: 8 bit mono2
# 2: 8 bit stereo
# 3: 16 bit mono
# 4: 16 bit stereo
wavfile.write( struct.pack('H', bits_per_sample ) ) # Bits per sample
# DATA HEADER
wavfile.write( 'data'.encode() ) # “data” chunk header. Marks the beginning of the data section
wavfile.write( struct.pack('I', data_size ) ) # Size of the data section
# // WAV DATA
wavfile.write( binfile.read() )
for filename in sys.argv:
convert_bin_to_audio(filename)