Разделить аудиофайл на части произвольного размера

У меня есть большой звуковой файл (150 МБ), который я хотел бы разделить на более мелкие файлы с более легким управлением, скажем, файлы с 5-минутным звуком. Ясно, что последний сегмент будет <= 5 минут, и это нормально. Есть ли способ легко выполнить такую ​​задачу?

Небольшой пример файла.mp3, который будет использоваться для этой проблемы, можно загрузить по этой ссылке: download.linnrecords.com/test/mp3/recit.aspx.

Вот что я пробовал до сих пор. Я импортировал данные, используя readMP3 от tuneR и собирался использовать cutw функции, но не нашли эффективного способа ее использования.

library(tuneR)

sample<-readMP3("recit.mp3") 

# the file is only 9.04 seconds long (44.1 Hz, 16-bit, sterio)
# so, for this example we can cut it into 0.5 second intervals)
subsamp1<-cutw(sample, from=0, to=0.5, output="Wave")

# then I would have to do this for each interval up to:
subsampn<-cutw(sample, from=9, to=9.04, output="Wave") 
# where I have to explicitly state the maximum second (i.e. 9.04), 
# unless there is a way I don't know of to extract this information.

Этот подход неэффективен, когда интервалы становятся маленькими по сравнению с общей длиной файла. Также, sample было стерео, но subsamp1 является моно, и я предпочел бы не менять данные, если это возможно.

Для повышения эффективности я попытался ввести векторы в from а также to аргументы, но я получил ошибку (см. ниже). Даже если бы это сработало, это не было бы особенно хорошим решением. Кто-нибудь знает более элегантный способ решения этой проблемы с помощью R?

cutw(subsamp1,from=seq(0,9,0.5),to=c(seq(0.5,9.0,0.5),9.04) 
# had to explicitly supply the max second (i.e. 9.04). 
# must be a better way to extract the maximum second

Error in wave[a:b, ] : subscript out of bounds
In addition: Warning messages:
1: In if (from > to) stop("'from' cannot be superior to 'to'") :
  the condition has length > 1 and only the first element will be used
2: In if (from == 0) { :
  the condition has length > 1 and only the first element will be used
3: In a:b : numerical expression has 19 elements: only the first used

3 ответа

Решение

У меня нет опыта работы с аудиофайлами в R, но я смог придумать подход, который мог бы вам помочь. Проверьте код ниже.

library(seewave)

# your audio file (using example file from seewave package)
data(tico)
audio <- tico
# the frequency of your audio file
freq <- 22050
# the length and duration of your audio file
totlen <- length(audio)
totsec <- totlen/freq

# the duration that you want to chop the file into
seglen <- 0.5

# defining the break points
breaks <- unique(c(seq(0, totsec, seglen), totsec))
index <- 1:(length(breaks)-1)
# a list of all the segments
subsamps <- lapply(index, function(i) cutw(audio, f=freq, from=breaks[i], to=breaks[i+1]))

Опираясь на превосходный ответ @Jean V. Adams, я нашел решение с использованием индексации (т.е. [).

library(seewave)

# your audio file (using example file from seewave package)
data(tico)
audio <- tico
# the frequency of your audio file
freq <- 22050
# the length and duration of your audio file
totlen <- length(audio)
totsec <- totlen/freq

# the duration that you want to chop the file into
seglen <- 0.5

# defining the break points
breaks <- unique(c(seq(0, totsec, seglen), totsec))
index <- 1:(length(breaks)-1)
# a list of all the segments
lapply(index, function(i) audio[(breaks[i]*freq):(breaks[i+1]*freq)])
# the above final line is the only difference between this code and the 
# code provided by @Jean V. Adams

Преимущество здесь в том, что если ваш входной аудиообъект является стереофоническим, возвращаемые объекты также будут стереофоническими. cutw меняет выходные объекты на моно, насколько я могу судить.

Проверьте https://github.com/schultzm/SliceAudio.py Я написал этот скрипт, чтобы сделать очень похожую вещь, как задано в этом вопросе, но я написал это на python. Не уверен, что это все еще актуально, но вот мое решение в любом случае. При желании вы можете запустить скрипт на Python из R.

Скрипт python разрезает аудиофайлы (в пакетном режиме, если это необходимо) по длине файла, пока не достигнет конца файла. По умолчанию он разбивает файл на 2-секундные блоки, причем каждый блок начинается в конце следующего блока, а каждый блок выводится как отдельный файл (в папку, содержащую входной файл; имена выходных файлов в соответствии с входными данными, но с позиция в исходном файле, добавленная к имени выходного файла). По умолчанию формат выходных срезов - 16-битный, 48 кГц, моно. Пользователь может раздавить семпл до 8-битной ширины или иметь среднюю (16-битную) или высококачественную (32-битную). Частота дискретизации может быть от низкого качества (11025 Гц) до высокого качества (48000 Гц) - фактически частота дискретизации может быть любой, какой вы хотите, но ваш компьютер может не знать, как работать с этими нестандартными частотами (например, я тестировал с частотой 1 Гц, и iTunes умер при попытке его воспроизвести - см. меню справки для стандартных / принятых опций [python SliceAudio.py -h]). Пользователь также может изменить длину среза образца и слайд с перекрытием на предыдущем срезе (например, вы можете срезать в 10-секундные окна, причем каждое последующее окно скользит вдоль 1 секунды, чтобы перекрывать предыдущее окно на 1 секунду. NB. Время измеряется в миллисекунды, поэтому умножьте x-секунд на 1000, чтобы получить желаемую длину среза в секундах). Есть опция для стерео выхода. Сценарий может вводить и выводить любой формат, поддерживаемый ffmpeg**.

Зависимости: 1. gcc 2. pydub (sudo pip install pydub), см. github.com/jiaaro/pydub 3. ffmpeg (brew install libav --with-libvorbis --with-sdl --with-theora) 4. аудиозапись (sudo pip install audioread)

Пример использования: python SliceAudio.py -i xyz.m4a -f m4a -b 2 -s 11025 -l 10000 python SliceAudio.py -h

** форматы ffmpeg: trac.ffmpeg.org/wiki/audio%20types

Другие вопросы по тегам