diff --git a/intro/conv_nsb_resample.py b/intro/conv_nsb_resample.py index edaee99..ad2369d 100644 --- a/intro/conv_nsb_resample.py +++ b/intro/conv_nsb_resample.py @@ -2,7 +2,7 @@ import sys import numpy as np from scipy.io import wavfile -from scipy import signal +from scipy import signal as sg @@ -29,6 +29,85 @@ def noise_shape_and_quantize(signal, bits): return np.clip(shaped, signal.min(), signal.max()) +def quantize(signal, bits): + steps = 2 ** bits + step_size = (signal.max() - signal.min()) / steps + for i in range(len(signal)): + quantized = np.round(signal[i] / step_size) * step_size + signal[i] = quantized + return np.clip(signal, signal.min(), signal.max()) + + +def adaptive_quantize(signal, bits): + steps = 2 ** bits + max_amp = np.max(np.abs(signal)) + + quantized = np.zeros_like(signal) + for i in range(len(signal)): + local_max = np.max(np.abs(signal[max(0, i - 1000):min(len(signal), i + 1000)])) + print(local_max) + step_size = (local_max * 2) / steps + quantized[i] = np.round(signal[i] / step_size) * step_size + + return quantized + + +def nonlinear_quantize(signal, bits): + steps = 2 ** bits + abs_max = np.max(np.abs(signal)) + + # Apply non-linear transformation (e.g., cube root) + transformed = np.sign(signal) * np.power(np.abs(signal) / abs_max, 1 / 3) + + # Quantize the transformed signal + step_size = 2 / steps + quantized = np.round(transformed / step_size) * step_size + + # Inverse transform + return np.sign(quantized) * np.power(np.abs(quantized), 3) * abs_max + + +import numpy as np + + +def smooth_and_quantize(signal, bits, window_length=5): + # Apply smoothing + smoothed = np.convolve(signal, np.ones(window_length) / window_length, mode='same') + + # Quantize + steps = 2 ** bits + step_size = (smoothed.max() - smoothed.min()) / steps + quantized = np.round(smoothed / step_size) * step_size + + return quantized + + +def advanced_noise_shape_and_quantize(signal, bits, shaping_coefficient=0.5, filter_cutoff=0.5): + steps = 2 ** bits + step_size = (signal.max() - signal.min()) / steps + + shaped = np.zeros_like(signal) + error = np.zeros_like(signal) + + # Noise shaping and dithering + for i in range(len(signal)): + dither = np.random.uniform(-step_size / 8, step_size / 8) + shaped[i] = signal[i] + dither - error[i] + quantized = np.round(shaped[i] / step_size) * step_size + error[i] = quantized - signal[i] + if i < len(signal) - 1: + error[i + 1] = error[i] * shaping_coefficient + + # Design low-pass filter + filter_order = 4 + b, a = sg.butter(filter_order, filter_cutoff, 'low') + + # Apply low-pass filter + filtered = sg.filtfilt(b, a, shaped) + + # Final quantization + quantized = np.round(filtered / step_size) * step_size + return np.clip(quantized, signal.min(), signal.max()) # Read the WAV file original_sr, data = wavfile.read(sys.argv[1]) @@ -39,12 +118,20 @@ data = data / np.max(np.abs(data)) target_sr = 5000 # 6 kHz # Resample the audio -resampled_data = resample_audio(data, original_sr, target_sr) +#resampled_data = resample_audio(data, original_sr, target_sr) +resampled_data = data # Apply noise shaping and quantization quantized = noise_shape_and_quantize(resampled_data, 4) - +# quantized = quantize(resampled_data, 4) +# quantized = adaptive_quantize(resampled_data, 4) +# quantized = nonlinear_quantize(resampled_data, 4) +# quantized = smooth_and_quantize(resampled_data, 4) +# quantized = advanced_noise_shape_and_quantize(resampled_data, 4, shaping_coefficient=0.5, filter_cutoff=0.5) # Scale to 0-15 range and round to integers + + + scaled = np.round((quantized - quantized.min()) / (quantized.max() - quantized.min()) * 15).astype(int) scaled = np.clip(scaled, 0, 15) @@ -57,8 +144,8 @@ packed = [] for i in range(0, len(scaled), 2): if i + 1 < len(scaled): byte = (scaled[i] << 4) | scaled[i + 1] - else: - byte = scaled[i] << 4 + # else: + # byte = scaled[i] << 4 packed.append(byte) # Write packed data to binary file @@ -72,8 +159,9 @@ print(f"Number of samples: {len(scaled)}") print(f"Duration: {len(scaled) / target_sr:.2f} seconds") # Print first few bytes in hex -print("First 10 bytes in hex:") +print("First and last 10 bytes in hex:") print(" ".join(f"{b:02X}" for b in packed[:10])) +print(" ".join(f"{b:02X}" for b in packed[-10:])) # Save the resampled audio as a WAV file for verification # Correctly scale back to 16-bit audio range diff --git a/intro/tech_diff.xex b/intro/tech_diff.xex index feb9b46..cee4a66 100644 Binary files a/intro/tech_diff.xex and b/intro/tech_diff.xex differ diff --git a/intro/wait1.wav b/intro/wait1.wav index c3ea1b5..84f9b93 100644 Binary files a/intro/wait1.wav and b/intro/wait1.wav differ diff --git a/intro/wait1.wav.bin b/intro/wait1.wav.bin index 431f0bd..55fb2d0 100644 Binary files a/intro/wait1.wav.bin and b/intro/wait1.wav.bin differ diff --git a/intro/wait2.wav b/intro/wait2.wav index 6ac371b..067bc73 100644 Binary files a/intro/wait2.wav and b/intro/wait2.wav differ diff --git a/intro/wait2.wav.bin b/intro/wait2.wav.bin index 07ccfe4..d27cc10 100644 Binary files a/intro/wait2.wav.bin and b/intro/wait2.wav.bin differ diff --git a/intro/wait3.wav b/intro/wait3.wav index 5faa8ec..2aace4f 100644 Binary files a/intro/wait3.wav and b/intro/wait3.wav differ diff --git a/intro/wait3.wav.bin b/intro/wait3.wav.bin index afd4f31..7311b6e 100644 Binary files a/intro/wait3.wav.bin and b/intro/wait3.wav.bin differ diff --git a/intro/wait4.wav b/intro/wait4.wav index 2fb1b45..ebb719e 100644 Binary files a/intro/wait4.wav and b/intro/wait4.wav differ diff --git a/intro/wait4.wav.bin b/intro/wait4.wav.bin index 5cdfa37..3fa5d33 100644 Binary files a/intro/wait4.wav.bin and b/intro/wait4.wav.bin differ diff --git a/intro/wait5.wav b/intro/wait5.wav index 1c38792..38ff085 100644 Binary files a/intro/wait5.wav and b/intro/wait5.wav differ diff --git a/intro/wait5.wav.bin b/intro/wait5.wav.bin index 172b1e0..e59f0ad 100644 Binary files a/intro/wait5.wav.bin and b/intro/wait5.wav.bin differ diff --git a/intro/wait6.wav b/intro/wait6.wav index 6280e44..7d121e2 100644 Binary files a/intro/wait6.wav and b/intro/wait6.wav differ diff --git a/intro/wait6.wav.bin b/intro/wait6.wav.bin index 5990aab..416496f 100644 Binary files a/intro/wait6.wav.bin and b/intro/wait6.wav.bin differ