Reputation: 435
I have an audio file and I want to split it every 2 seconds. Is there a way to do this with librosa?
So if I had a 60 seconds file, I would split it into 30 two second files.
Upvotes: 7
Views: 16860
Reputation: 1620
you can split array in chunks just using index spliting, in order to get 2 seconds you need 2 * sample rate values from array and then step ahead
import librosa
import soundfile as sf
audio_file = "0.wav"
y, sr = librosa.load(audio_file, sr=None)
# chunk duration 2 seconds
chunk_duration = 2
chunk_samples = int(chunk_duration * sr)
chunks = [y[i:i + chunk_samples] for i in range(0, len(y), chunk_samples)]
for i, chunk in enumerate(chunks):
output_file = f"chunk_{i}.wav"
sf.write(output_file, chunk, sr)
Upvotes: 5
Reputation: 1192
Here a funciton to get a certain time frame of the file:
def split_music(
audio_file: Tuple[np.ndarray, float] | str,
from_second: int = 0,
to_second: int = None,
save_file_path: str = None,
) -> Tuple[np.ndarray, float]:
"""
This code splits an audio file based on the provided seconds
:param audio_file: either an audio file loaded by librosa or an filepath to load audio from
:param from_second: the second when the split starts
:param to_second: the second when the split ends
:param save_file_path: if provided audio snippet will be saved at location
:return: the audio snippet as ndarray, sample_rate
"""
# load audio from file
if type(audio_file) == str:
audio_file, sr = librosa.load(file_path)
elif type(audio_file) == Tuple[np.ndarray, float]:
audio_file, sr = audio_file
# last second is end of file if not provided
to_second = len(audio_file) if to_second is None else to_second
# split audio
audio_file = audio_file[from_second*sr:to_second*sr]
if save_file_path is not None and type(save_file_path) == str:
# add extension if necessary
save_file_path, ext = os.path.splitext(save_file_path)
save_file_path = save_file_path + ".wav" if not ext else save_file_path + ext
# save to file
sf.write(save_file_path, audio_file, sr)
return audio_file, sr
Upvotes: 0
Reputation: 2639
You can split your file using librosa running the following code. I have added comments necessary so that you understand the steps carried out.
# First load the file
audio, sr = librosa.load(file_name)
# Get number of samples for 2 seconds; replace 2 by any number
buffer = 2 * sr
samples_total = len(audio)
samples_wrote = 0
counter = 1
while samples_wrote < samples_total:
#check if the buffer is not exceeding total samples
if buffer > (samples_total - samples_wrote):
buffer = samples_total - samples_wrote
block = audio[samples_wrote : (samples_wrote + buffer)]
out_filename = "split_" + str(counter) + "_" + file_name
# Write 2 second segment
librosa.output.write_wav(out_filename, block, sr)
counter += 1
samples_wrote += buffer
[Update]
librosa.output.write_wav()
has been removed from librosa, so now we have to use soundfile.write()
Import required library
import soundfile as sf
replace
librosa.output.write_wav(out_filename, block, sr)
with
sf.write(out_filename, block, sr)
Upvotes: 4
Reputation: 5310
librosa is first and foremost a library for audio analysis, not audio synthesis or processing. The support for writing simple audio files is given (see here), but it is also stated there:
This function is deprecated in librosa 0.7.0. It will be removed in 0.8. Usage of write_wav should be replaced by soundfile.write.
Given this information, I'd rather use a tool like sox to split audio files.
From "Split mp3 file to TIME sec each using SoX":
You can run SoX like this:
sox file_in.mp3 file_out.mp3 trim 0 2 : newfile : restart
It will create a series of files with a 2-second chunk of the audio each.
If you'd rather stay within Python, you might want to use pysox for the job.
Upvotes: 3