import sys
import json
import numpy as np
import librosa
def compute_librosa_stft(
audio_file: str,
n_fft: int = 512,
hop_length: int = 160,
win_length: int = 400,
center: bool = False,
) -> np.ndarray:
y, sr = librosa.load(audio_file, sr=None, mono=True)
stft = librosa.stft(
y,
n_fft=n_fft,
hop_length=hop_length,
win_length=win_length,
window="hann",
center=center,
)
power_spectrogram = np.abs(stft) ** 2
return power_spectrogram, sr
def compute_librosa_mel(
audio_file: str,
n_fft: int = 512,
hop_length: int = 160,
win_length: int = 400,
n_mels: int = 40,
f_min: float = 0.0,
f_max: float = None,
htk: bool = True,
center: bool = False,
) -> np.ndarray:
power_spec, sr = compute_librosa_stft(
audio_file, n_fft, hop_length, win_length, center
)
if f_max is None:
f_max = sr / 2.0
mel_spec = librosa.feature.melspectrogram(
S=power_spec, sr=sr, n_fft=n_fft, n_mels=n_mels, fmin=f_min, fmax=f_max, htk=htk
)
return mel_spec, sr
def main():
if len(sys.argv) < 3:
print(
"Usage: python generate_librosa_spectrogram.py <audio_file> <output_json> [params_json]"
)
sys.exit(1)
audio_file = sys.argv[1]
output_file = sys.argv[2]
params = {
"type": "stft", "n_fft": 512,
"hop_length": 160,
"win_length": 400,
"center": False,
"n_mels": 40,
"f_min": 0.0,
"f_max": None,
"htk": True,
}
if len(sys.argv) > 3:
with open(sys.argv[3], "r") as f:
custom_params = json.load(f)
params.update(custom_params)
if params["type"] == "mel":
spec, sr = compute_librosa_mel(
audio_file,
n_fft=params["n_fft"],
hop_length=params["hop_length"],
win_length=params["win_length"],
n_mels=params["n_mels"],
f_min=params["f_min"],
f_max=params["f_max"],
htk=params["htk"],
center=params["center"],
)
else: spec, sr = compute_librosa_stft(
audio_file,
n_fft=params["n_fft"],
hop_length=params["hop_length"],
win_length=params["win_length"],
center=params["center"],
)
output = {
"data": spec.tolist(),
"shape": spec.shape,
"sample_rate": int(sr),
"params": params,
}
with open(output_file, "w") as f:
json.dump(output, f)
print(f"Librosa spectrogram saved to {output_file}")
print(f"Shape: {spec.shape}")
print(f"Sample rate: {sr}")
if __name__ == "__main__":
main()