Day 3: Loading, Visualizing, and Preprocessing Audio with Librosa
This is Day 3 of my Multimodal AI from Scratch series.
Yesterday, I learned that audio is stored as a sequence of numerical samples. I also learned about waveforms, sampling rate, amplitude, and frequency.
Today, I learned how to load, visualize, and preprocess audio using Librosa.
Why preprocessing matters
Raw audio files can have different sampling rates, channels, lengths, and levels of noise.
Before using audio in a machine-learning model, we need to make the data consistent.
For example, one file may be stereo with a 44,100 Hz sampling rate, while another may be mono with 16,000 Hz. If we do not preprocess them, the model may receive inconsistent inputs.
A simple preprocessing workflow is:
Raw audio file
↓
Convert to mono
↓
Resample to a fixed rate
↓
Trim silence
↓
Normalize or scale
↓
Ready for feature extractionLoading audio with Librosa
Librosa makes it easy to load an audio file.
import librosa
audio, sr = librosa.load(
"speech.wav",
sr=16000,
mono=True
)print("Sample rate:", sr)
print("Number of samples:", len(audio))
print("Duration:", len(audio) / sr, "seconds")Here:
audiois a NumPy array of amplitude values.sris the sampling rate.sr=16000resamples the audio to 16,000 Hz.mono=Trueconverts stereo audio to one channel.
Using one fixed sampling rate is important because all audio files should have the same format before feature extraction.
Visualizing a waveform
A waveform helps us see the audio signal over time.
import librosa
import librosa.display
import matplotlib.pyplot as plt
audio, sr = librosa.load(
"speech.wav",
sr=16000,
mono=True
)
plt.figure(figsize=(12, 4))
librosa.display.waveshow(audio, sr=sr)
plt.title("Audio Waveform")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.show()From the waveform, we can observe:
- When speech begins and ends.
- Periods of silence.
- Loud and quiet parts.
- Sudden changes in the signal.
However, a waveform does not show frequency information clearly. For that, we need spectrograms, which I will learn about later.
Trimming silence
Many recordings begin or end with silence. This silence may not be useful for sentiment analysis.
Get Sunayana Parikh’s stories in your inbox
Join Medium for free to get updates from this writer.
Librosa provides a trimming function:
trimmed_audio, index = librosa.effects.trim(
audio,
top_db=30
)
print("Original length:", len(audio))
print("Trimmed length:", len(trimmed_audio))top_db=30 means Librosa will remove quiet parts that are more than 30 decibels below the reference level.
Trimming can help reduce unnecessary silence, but it should be used carefully. In speech, pauses can also be meaningful, especially when studying hesitation, emphasis, or emotional expression.
Normalizing audio
Normalization changes the scale of the audio signal without changing its relative shape.
One simple method is peak normalization:
import numpy as np
normalized_audio = audio / np.max(np.abs(audio))This scales the audio so that the largest absolute amplitude becomes 1.
Normalization can help when recordings have different volume levels. However, it should be used carefully because it removes information about the original loudness. In some tasks, loudness itself may be useful.
Checking audio duration
Before training, it is useful to check the duration of every file.
duration = len(audio) / sr
print(duration)If some clips are very short, they may not contain enough information. If some are very long, you may need to divide them into smaller segments.
For example, a 10-minute video may be divided into 5-second or 10-second windows. Each window can then receive its own features and, if available, its own sentiment label.
A complete basic pipeline
import librosa
import numpy as np
import librosa.display
import matplotlib.pyplot as plt
audio_path = "speech.wav"
audio, sr = librosa.load(
audio_path,
sr=16000,
mono=True
)
trimmed_audio, _ = librosa.effects.trim(
audio,
top_db=30
)
normalized_audio = trimmed_audio / np.max(np.abs(trimmed_audio))
duration = len(normalized_audio) / sr
print("Sample rate:", sr)
print("Duration after trimming:", duration, "seconds")
plt.figure(figsize=(12, 4))
librosa.display.waveshow(normalized_audio, sr=sr)
plt.title("Preprocessed Audio Waveform")
plt.xlabel("Time (seconds)")
plt.ylabel("Normalized amplitude")
plt.show()This pipeline:
- Loads the audio.
- Converts it to mono.
- Resamples it to 16,000 Hz.
- Trims silence.
- Normalizes the amplitude.
- Visualizes the result.
What I learned today
Today’s main lesson is:
Before extracting features or training a model, audio must be loaded and preprocessed consistently.
For multimodal sentiment analysis, preprocessing is important because audio must be aligned with video and text later. If the audio files have different sampling rates or lengths, the multimodal pipeline can become inconsistent.
#MultimodalAI #Librosa #AudioProcessing #MachineLearning #DataScience #SentimentAnalysis #LearningInPublic




