Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way I can get SoX to just print the amplitude values from a wav file?

Tags:

c++

sox

I'm using a simple line of code:

sox vocal2.wav -t dat vocal2.dat

via SoX to convert a wav file to a text file showing the amplitude values at certain time positions. The output data also has a header showing sample rate and number of channels.

I need to use the amplitude data in a C++ program to determine the pitch of the input, but it's annoying to have to convert the file, drag the data into Excel, copy one column, save it to a new .txt file and then work with it.

Is there a way I can tell SoX to JUST output the amplitude in the converted file?

like image 701
Tom_Anks Avatar asked Nov 20 '25 07:11

Tom_Anks


1 Answers

If you want the data specifically for use in C++, it's very easy to use something like Libsndfile. It's a pretty mature C library, but comes with a convenient C++ wrapper (sndfile.hh).

Here's example usage lifted from something I wrote recently where I needed easy access to audio data.

std::string infile_name = "/path/to/vocal2.wav";

// Open input file.
SndfileHandle infile_handle( infile_name );
if( !infile_handle || infile_handle.error() != 0 )
{
    std::cerr << "Unable to read " << infile_name << std::endl;
    std::cerr << infile_handle.strError() << std::endl;
    return 1;
}

// Show file stats
int64_t in_frames = infile_handle.frames();
int in_channels = infile_handle.channels();
int in_samplerate = infile_handle.samplerate();
std::cerr << "Input file: " << infile_name << std::endl;
std::cerr << " * Frames      : " << std::setw(6) << in_frames << std::endl;
std::cerr << " * Channels    : " << std::setw(6) << in_channels << std::endl;
std::cerr << " * Sample Rate : " << std::setw(6) << in_samplerate << std::endl;

// Read audio data as float
std::vector<float> in_data( in_frames * in_channels );
infile_handle.read( in_data.data(), in_data.size() );

If you just want to use SoX on the command line and get text output, you can do something like this:

sox vocal2.wav -t f32 - | od -ve -An | more

Here I've specified an output of raw 32-bit float, and run it through GNU od. It's a little frustrating that you can't tell od how many columns you want, but you can clean that up with other simple tools. Have a look at the manpage for od if you want different sample encodings.

like image 138
paddy Avatar answered Nov 22 '25 21:11

paddy