| import numpy as np |
| import matplotlib.pyplot as plt |
| import sounddevice as sd |
| from scipy.fftpack import fft |
| import time |
| import os |
|
|
| |
| SAMPLE_RATE = 44100 |
| DURATION = 5 |
| CHUNK_SIZE = 1024 |
| PLOT_REFRESH_RATE = 0.1 |
|
|
| |
| plt.ion() |
| fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8)) |
| fig.suptitle('Live Microphone Waveform & Spectrum') |
|
|
| |
| line_wave, = ax1.plot(np.arange(CHUNK_SIZE), np.zeros(CHUNK_SIZE)) |
| line_spectrum, = ax2.plot(np.arange(CHUNK_SIZE//2), np.zeros(CHUNK_SIZE//2)) |
|
|
| |
| ax1.set_ylim(-1, 1) |
| ax1.set_xlim(0, CHUNK_SIZE) |
| ax1.set_title('Waveform') |
| ax1.set_ylabel('Amplitude') |
|
|
| ax2.set_xlim(0, CHUNK_SIZE//2) |
| ax2.set_ylim(0, 1) |
| ax2.set_title('Spectrum') |
| ax2.set_ylabel('Magnitude') |
| ax2.set_xlabel('Frequency Bin') |
|
|
| |
| def audio_callback(indata, frames, time, status): |
| if status: |
| print(status, flush=True) |
| |
| |
| line_wave.set_ydata(indata[:, 0]) |
| |
| |
| N = len(indata[:, 0]) |
| yf = fft(indata[:, 0]) |
| xf = np.linspace(0, SAMPLE_RATE//2, N//2) |
| line_spectrum.set_ydata(2/N * np.abs(yf[:N//2])) |
| |
| |
| fig.canvas.draw() |
| fig.canvas.flush_events() |
|
|
| |
| stream = sd.InputStream( |
| callback=audio_callback, |
| samplerate=SAMPLE_RATE, |
| channels=1, |
| blocksize=CHUNK_SIZE |
| ) |
|
|
| try: |
| print("Starting audio capture... Press Ctrl+C to stop.") |
| with stream: |
| while True: |
| time.sleep(PLOT_REFRESH_RATE) |
| except KeyboardInterrupt: |
| print("\nStopping audio capture...") |
| |
| |
| timestamp = time.strftime("%Y%m%d-%H%M%S") |
| filename = f"waveform_{timestamp}.png" |
| fig.savefig(filename) |
| print(f"Saved waveform image as {filename}") |
| |
| plt.close() |
| except Exception as e: |
| print(f"Error: {e}") |
| plt.close() |