aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRangi42 <remy.oukaour+rangi42@gmail.com>2023-11-23 00:18:07 -0500
committerRangi42 <remy.oukaour+rangi42@gmail.com>2023-11-23 00:18:07 -0500
commitabc34756d131b327eff548aa13aff8e4b677a96e (patch)
treec2716697cea347a40ed96c59fa9fe73258cf8b1b /tools
parentRename pikachu palette packets (diff)
downloadpokeyellow-abc34756d131b327eff548aa13aff8e4b677a96e.tar.gz
pokeyellow-abc34756d131b327eff548aa13aff8e4b677a96e.tar.xz
pokeyellow-abc34756d131b327eff548aa13aff8e4b677a96e.zip
Remove pcm.py since pcm.c handles it
Diffstat (limited to 'tools')
-rw-r--r--tools/pokemontools/pcm.py156
1 files changed, 0 insertions, 156 deletions
diff --git a/tools/pokemontools/pcm.py b/tools/pokemontools/pcm.py
deleted file mode 100644
index 428d5730..00000000
--- a/tools/pokemontools/pcm.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# pcm.py
-# Converts between .wav files and 1-bit pcm data. (pcm = pulse-code modulation)
-
-import argparse
-import os
-import struct
-import wave
-
-
-BASE_SAMPLE_RATE = 22050
-
-def convert_to_wav(filenames=[]):
- """
- Converts a file containing 1-bit pcm data into a .wav file.
- """
- for filename in filenames:
- with open(filename, 'rb') as pcm_file:
- # Generate array of on/off pcm values.
- samples = []
- byte = pcm_file.read(1)
- while byte != "":
- byte = struct.unpack('B', byte)[0]
- for i in range(8):
- bit_index = 7 - i
- value = (byte >> bit_index) & 1
- samples.append(value)
- byte = pcm_file.read(1)
-
- # Write a .wav file using the pcm data.
- name, extension = os.path.splitext(filename)
- wav_filename = name + '.wav'
- wave_file = wave.open(wav_filename, 'w')
- wave_file.setframerate(BASE_SAMPLE_RATE)
- wave_file.setnchannels(1)
- wave_file.setsampwidth(1)
-
- for value in samples:
- if value > 0:
- value = 0xff
-
- packed_value = struct.pack('B', value)
- wave_file.writeframesraw(packed_value)
-
- wave_file.close()
-
-
-def convert_to_pcm(filenames=[]):
- """
- Converts a .wav file into 1-bit pcm data.
- Samples in the .wav file are simply clamped to on/off.
-
- This currently works correctly on .wav files with the following attributes:
- 1. Sample Width = 1 or 2 bytes (Some wave files use 3 bytes per sample...)
- 2. Arbitrary sample sample_rate
- 3. Mono or Stereo (1 or 2 channels)
- """
- for filename in filenames:
- samples, average_sample = get_wav_samples(filename)
-
- # Generate a list of clamped samples
- clamped_samples = []
- for sample in samples:
- # Clamp the raw sample to on/off
- if sample < average_sample:
- clamped_samples.append(0)
- else:
- clamped_samples.append(1)
-
- # The pcm data must be a multiple of 8, so pad the clamped samples with 0.
- while len(clamped_samples) % 8 != 0:
- clamped_samples.append(0)
-
- # Pack the 1-bit samples together.
- packed_samples = bytearray()
- for i in range(0, len(clamped_samples), 8):
- # Read 8 pcm values to pack one byte.
- packed_value = 0
- for j in range(8):
- packed_value <<= 1
- packed_value += clamped_samples[i + j]
- packed_samples.append(packed_value)
-
- # Open the output .pcm file, and write all 1-bit samples.
- name, extension = os.path.splitext(filename)
- pcm_filename = name + '.pcm'
- with open(pcm_filename, 'wb') as out_file:
- out_file.write(packed_samples)
-
-
-def get_wav_samples(filename):
- """
- Reads the given .wav file and returns a list of its samples after re-sampling
- to BASE_SAMPLE_RATE.
- Also returns the average sample amplitude.
- """
- wav_file = wave.open(filename, 'r')
- sample_width = wav_file.getsampwidth()
- sample_count = wav_file.getnframes()
- sample_rate = wav_file.getframerate()
- num_channels = wav_file.getnchannels()
-
- samples = bytearray(wav_file.readframes(sample_count))
-
- # Unpack the values based on the sample byte width.
- unpacked_samples = []
- for i in range(0, len(samples), sample_width):
- if sample_width == 1:
- fmt = 'B'
- elif sample_width == 2:
- fmt = 'h'
- else:
- # todo: support 3-byte sample width
- raise (Exception, "Unsupported sample width: " + str(sample_width))
-
- value = struct.unpack(fmt, samples[i:i + sample_width])[0]
- unpacked_samples.append(value)
-
- # Only keep the samples from the first audio channel.
- unpacked_samples = unpacked_samples[::num_channels]
-
- # Approximate the BASE_SAMPLE_RATE.
- # Also find the average amplitude of the samples.
- resampled_samples = []
- total_value = 0
- interval = float(sample_rate) / BASE_SAMPLE_RATE
- index = 0
- while index < sample_count:
- sample = unpacked_samples[int(index)]
- total_value += sample
-
- resampled_samples.append(sample)
- index += interval
-
- average_sample = float(total_value) / len(resampled_samples)
-
- return resampled_samples, average_sample
-
-
-def main():
- ap = argparse.ArgumentParser()
- ap.add_argument('mode')
- ap.add_argument('filenames', nargs='*')
- args = ap.parse_args()
-
- method = {
- 'wav': convert_to_wav,
- 'pcm': convert_to_pcm,
- }.get(args.mode, None)
-
- if method == None:
- raise (Exception, "Unknown conversion method!")
-
- method(args.filenames)
-
-if __name__ == "__main__":
- main()