Split mp3 file to TIME sec each using SoX
You can run SoX like this:
sox file_in.mp3 file_out.mp3 trim 0 15 : newfile : restart
It will create a series of files with a 15-second chunk of the audio each. (Obviously, you may specify a value other than 15.) There is no need to know the total length.
Note that SoX, unlike mp3splt, will decode and reencode the audio (see generation loss). You should make sure to use at least SoX 14.4.0 because previous versions had a bug where audio got lost between chunks.
Trim audio files with Sox in milliseconds
If you want to trim with millisecond precision, specify it:
sox in.mp3 out.mp3 trim 2 0.195
Saves 195 milliseconds with an offset of 2 seconds of in.mp3
to out.mp3
.
If you only want the first two seconds of the file use trim like this:
sox in.mp3 out.mp3 trim 0 2
If you want to skip the first two seconds of the file use trim like this:
sox in.mp3 out.mp3 trim 2
If you want to trim 195 milliseconds from the end of the file, use gerald's answer.
Excerpt from the manual:
trim start [length|=end]
The optional length parameter gives the length of audio to output after the
start sample and is thus used to trim off the end of the audio.
Alternatively, an absolute end location can be given by preceding it with
an equals sign. Using a value of 0 for the start parameter will allow trimming
off the end only.
How do you trim the audio file's end using SoX?
The syntax is sox input output trim <start> <duration>
e.g. sox input.wav output.wav trim 0 00:35
will output the first 35 seconds into output.wav
.
(you can know what the length is using sox input -n stat
)
From the SoX documentation on the trim
command:
Cuts portions out of the audio. Any number of positions may be given; audio is not sent to the output until the first position is reached. The effect then alternates between copying and discarding audio at each position. Using a value of 0 for the first position parameter allows copying from the beginning of the audio.
For example,
sox infile outfile trim 0 10
will copy the first ten seconds, while
play infile trim 12:34 =15:00 -2:00
and
play infile trim 12:34 2:26 -2:00
will both play from 12 minutes 34 seconds into the audio up to 15 minutes into the audio (i.e. 2 minutes and 26 seconds long), then resume playing two minutes before the end of audio.
Per dpwe's comment, the position values are interpreted as being relative to the previous position, unless they start with =
(in which case they are relative to the start of the file) or -
(in which case they are relative to the end of the file).
So, trimming five seconds off the end would be sox input output trim 0 -5
How do I reduce the play time of a voice mp3 file with sox to 75%?
Try this (with input.wav as your input file)
sox input.wav output.wav speed 1.33
Taken from this, its example 13.
Regarding pitch correction, if the pitch should stay the same, use this command instead.
sox input.wav output.wav tempo 1.33
Regarding filesize. It depends on the audio format you want to use. If it is compressed, select settings for higher compression. If not, you may want to convert it to mono, reduce the sample rate or bits.
Split audio file into pieces
EDIT
With SOX:
string sox = @"C:\Program Files (x86)\sox-14-4-1\sox.exe";
string inputFile = @"D:\Brothers Vibe - Rainforest.mp3";
string outputDirectory = @"D:\splittest";
string outputPrefix = "split";
int[] segments = { 10, 15, 30 };
IEnumerable<string> enumerable = segments.Select(s => "trim 0 " + s.ToString(CultureInfo.InvariantCulture));
string @join = string.Join(" : newfile : ", enumerable);
string cmdline = string.Format("\"{0}\" \"{1}%1n.wav" + "\" {2}", inputFile,
Path.Combine(outputDirectory, outputPrefix), @join);
var processStartInfo = new ProcessStartInfo(sox, cmdline);
Process start = System.Diagnostics.Process.Start(processStartInfo);
If SOX complains about libmad (for MP3) : copy DLLs next to it, see here
Alternatively you can use FFMPEG in the same manner :
ffmpeg -ss 0 -t 30 -i "Brothers Vibe - Rainforest.mp3" "Brothers Vibe - Rainforest.wav"
(see the docs for all the details)
You can do that easily with BASS.NET :
For the code below you pass in :
- input file name
- desired duration for each segment
- output directory
- prefix to use for each segment file
The method will check whether the file is long enough for the specified segments, if yes then it will cut the file to WAVs with the same sample rate, channels, bit depth.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Un4seen.Bass;
using Un4seen.Bass.Misc;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (!Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
throw new InvalidOperationException("Couldn't initialize BASS");
string fileName = @"D:\Brothers Vibe - Rainforest.mp3";
var segments = new double[] {30, 15, 20};
string[] splitAudio = SplitAudio(fileName, segments, "output", @"D:\split");
}
private static string[] SplitAudio(string fileName, double[] segments, string prefix, string outputDirectory)
{
if (fileName == null) throw new ArgumentNullException("fileName");
if (segments == null) throw new ArgumentNullException("segments");
if (prefix == null) throw new ArgumentNullException("prefix");
if (outputDirectory == null) throw new ArgumentNullException("outputDirectory");
int i = Bass.BASS_StreamCreateFile(fileName, 0, 0,
BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE);
if (i == 0)
throw new InvalidOperationException("Couldn't create stream");
double sum = segments.Sum();
long length = Bass.BASS_ChannelGetLength(i);
double seconds = Bass.BASS_ChannelBytes2Seconds(i, length);
if (sum > seconds)
throw new ArgumentOutOfRangeException("segments", "Required segments exceed file duration");
BASS_CHANNELINFO info = Bass.BASS_ChannelGetInfo(i);
if (!Directory.Exists(outputDirectory)) Directory.CreateDirectory(outputDirectory);
int index = 0;
var list = new List<string>();
foreach (double segment in segments)
{
double d = segment;
long seconds2Bytes = Bass.BASS_ChannelSeconds2Bytes(i, d);
var buffer = new byte[seconds2Bytes];
int getData = Bass.BASS_ChannelGetData(i, buffer, buffer.Length);
string name = string.Format("{0}_{1}.wav", prefix, index);
string combine = Path.Combine(outputDirectory, name);
int bitsPerSample = info.Is8bit ? 8 : info.Is32bit ? 32 : 16;
var waveWriter = new WaveWriter(combine, info.chans, info.freq, bitsPerSample, true);
waveWriter.WriteNoConvert(buffer, buffer.Length);
waveWriter.Close();
list.Add(combine);
index++;
}
bool free = Bass.BASS_StreamFree(i);
return list.ToArray();
}
}
}
TODO
The extraction is not optimized, if you are concerned with memory usage, then the function should be enhanced to grab parts of a segments and write them progressively to the WaveWriter
.
Notes
BASS.NET has a nag screen, but you can request for a free registration serial at their website.
Note, install BASS.NET then make sure to copy bass.dll from the base package next to your EXE. Also, you can use pretty much any audio formats, see their website for formats plugins and how to load them (BASS_PluginLoad).
Splitting an Audio File Into Equal-Lenght Segments Using FFmpeg
You can use the segment muxer. Basic example:
ffmpeg -i input.wav -f segment -segment_time 2 output_%03d.wav
-f segment
indicates that the segment muxer should be used for the output.-segment_time 2
makes each segment 2 seconds long.output_%03d.wav
is the output file name pattern which will result iinoutput_000.wav
,output_001.wav
,output_002.wav
, and so on.
Related Topics
How to Assign Execute Permission to a .Sh File in Windows to Be Executed in Linux
Bash Variables: Case Sensitive or Not
How to Sort The Output of "Grep -L" Chronologically by Newest Modification Date Last
Use Conditional in Bash Script to Check String Argument
Find The Number of Files in a Directory
How Are Interrupts Handled on Smp
How to Touch a File and Mkdir If Needed in One Line
Transpose Rows into Column in Unix
What Ncurses Frameworks Are Available for Bash
Berkeley Db Mismatch Error While Configuring Ldap
Find The Depth of The Current Path
How to Do a While Loop with a String Redirected into It
Does I2C Driver Need to Be Implemented Just Like Any Other Character Device Driver
Load Warning: Cannot Find Entry Symbol _Start
How to Store Output from Printf with Formatting in a Variable
How to Find The Memory Consumption of a Particular Process in Linux for Every 5 Seconds