pythonbinaryvisualizationwav

Binary Visualisation of a WAV file using Python


I want to achive something like this:
IMAGE

However not really sure what is the best way to approach this, only one idea came to my mind but it's not working as I want to.

import wave
import time
import tkinter as tk


def byte_to_binary(byte_data):
    return bin(byte_data)[2:].zfill(8)


wav_file = wave.open("horror_sound.wav", "rb")
duration_seconds = wav_file.getnframes() / wav_file.getframerate()
binary_data = wav_file.readframes(wav_file.getnframes())
wav_file.close()


bits_per_second = 50


total_bits = int(duration_seconds * bits_per_second)


root = tk.Tk()
root.title("Binary Data Loading")


canvas = tk.Canvas(root, width=400, height=400, bg="black")
canvas.pack()


x1, y1, x2, y2 = 0, 0, 10, 10

# Update the loading visualization (row-wise)
for i in range(total_bits):
    color = "black" if int(byte_to_binary(binary_data[i // 8])[i % 8]) == 0 else "white"
    canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="")
    canvas.update()
    time.sleep(1 / bits_per_second)
    x1, x2 = x1 + 10, x2 + 10
    if x1 >= 400:
        x1, y1, x2, y2 = 0, y1 + 10, 10, y2 + 10


x1, y1, x2, y2 = 200, 0, 210, 10


for i in range(total_bits):
    color = "black" if int(byte_to_binary(binary_data[i // 8])[i % 8]) == 0 else "white"
    canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="")
    canvas.update()
    time.sleep(1 / bits_per_second)
    y1, y2 = y1 + 10, y2 + 10
    if y1 >= 400:
        x1, y1, x2, y2 = x1 + 10, 0, x2 + 10, 10

root.mainloop()

it should be filled with some sort of animation to simulate receiving of the traffic. Actual outcome of code:
IMAGE


Solution

  • I was able to fix it and get it to looks something like this: IMAGE

    Code:

    import wave
    import numpy as np
    from PIL import Image, ImageTk
    import tkinter as tk
    
    
    def add_noise(audio_array, noise_level=0.1):
        noise = np.random.normal(scale=noise_level, size=len(audio_array))
        return audio_array + noise
    
    
    def wav_to_image(input_wav):
        with wave.open(input_wav, "rb") as wav_file:
            num_frames = wav_file.getnframes()
            # sample_rate = wav_file.getframerate()
            audio_data = wav_file.readframes(num_frames)
    
        audio_array = np.frombuffer(audio_data, dtype=np.int16)
    
        num_pixels = len(audio_array)
        image_size = int(num_pixels**0.5)
    
        noisy_audio = add_noise(audio_array)
    
        image_height = int(len(noisy_audio) / image_size)
    
        # Reshape the audio array into a two-dimensional array for plotting
        reshaped_audio = noisy_audio[: image_height * image_size].reshape(image_height, -1)
    
        return reshaped_audio
    
    
    def numpy_to_photoimage(numpy_array):
        image = Image.fromarray(numpy_array.astype(np.uint8))
    
        photo = ImageTk.PhotoImage(image)
    
        return photo
    
    
    def display_image_in_window(image_data):
        root = tk.Tk()
        root.title("Binary Visualization")
    
        photo = numpy_to_photoimage(image_data)
    
        canvas = tk.Canvas(root, width=image_data.shape[1], height=image_data.shape[0])
        canvas.pack()
    
        canvas.create_image(0, 0, anchor=tk.NW, image=photo)
    
        root.mainloop()
    
    
    input_wav = "horror_sound.wav"
    satellite_image_data = wav_to_image(input_wav)
    display_image_in_window(satellite_image_data)