Steve2/convert_spkr_buf_to_wav.py

60 lines
2.8 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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