Loop info
Download sourcecode: loopinfo.c
/*
Phill Phelps (zenpho@zenpho.co.uk) 2014 June 01
Recently I found a big collection of WAV files exported from soundfonts, and I needed to display the loop offset values so I could dial in the loops on a hardware sampler.
I wrote this very simple linux command line program (using the excellent libsndfile library) to help me do this.
Note: commandline argument handling is very crude - getopt.h is not used
*/
#include <stdio.h>
#include <sndfile.h>
#include <stdlib.h>
#include <string.h>
void disp_sfinfo(SF_INFO *sfinfo)
{
printf("frames:\t\t%ld\n", (long)sfinfo-> frames);
printf("samplerate:\t%d\n", sfinfo-> samplerate);
printf("channels:\t%d\n", sfinfo-> channels);
printf("format number:\t%d\n", sfinfo-> format);
printf("sections:\t%d\n", sfinfo-> sections);
printf("seekable?:\t%d\n", sfinfo-> seekable);
printf("\n");
}
void disp_sfloopinfo(SF_LOOP_INFO *sfloopinfo)
{
printf("WARNING - currently ignored\n");
printf("\n");
}
void disp_sfinstrument(SF_INSTRUMENT *sfinstrument)
{
printf("note:\t\t%d\n", sfinstrument-> basenote);
printf("detune:\t\t%d\n", sfinstrument-> detune);
printf("num loops:\t%d\n", sfinstrument-> loop_count);
int loop = 0;
while(loop < sfinstrument-> loop_count) {
printf("loop [%d]\n", loop);
printf("\tmode:\t%d\n", sfinstrument-> loops[loop].mode);
printf("\tstart:\t%d\n", sfinstrument-> loops[loop].start);
printf("\tend:\t%d\n", sfinstrument-> loops[loop].end);
loop++;
}
printf("\n");
}
void exitDisplayingUsage(char *command)
{
// display usage and exit with returncode 1
printf("usage: %s < filename> [< display mode 0|1|2> ]\n", command);
exit(1);
}
int main(int argc, char* argv[])
{
char *command = argv[0];
char *filename = NULL;
SNDFILE *infile;
SF_INFO sfinfo;
SF_LOOP_INFO sfloopinfo;
SF_INSTRUMENT sfinstrument;
int displaymode = 0;
/*
== Mode values ==
0, just instrument info
1, drum/loop/playlist info
> 1, above plus basic info
*/
// abort if the argument count is invalid
if (argc < 2 || argc > 3)
{
exitDisplayingUsage(command);
}
// try to set the displaymode - abort on error
else if (argc == 3)
{
if (sscanf(argv[2], "%i", &displaymode;)!=1) // not an integer?
exitDisplayingUsage(command);
// clip range
if (displaymode < 0) displaymode = 0;
if (displaymode > 2) displaymode = 2;
}
// abort if we fail to read file
memset(&sfinfo;, 0, sizeof (sfinfo));
filename = argv[1];
if ((infile = sf_open(filename, SFM_READ, &sfinfo;)) == NULL)
{
printf("==%s Error reading/parsing==\n", filename);
sf_close(infile);
exit(1);
}
// shoud we show basic info?
if ( displaymode > 1 )
{
printf("==%s Basic information==\n", filename);
disp_sfinfo(&sfinfo;);
}
// should we show drum/beat/playlist info?
if ( displaymode > = 1 )
{
// report if we fail/succeed obtaining info
memset(&sfloopinfo;, 0, sizeof(sfloopinfo));
if (sf_command(infile, SFC_GET_LOOP_INFO, &sfloopinfo;, sizeof(sfloopinfo) ) == SF_FALSE)
printf("==%s Error reading loop (drum/beat/playlist) info=='\n", filename);
else
{
printf("==%s Loop (drum/beat/playlist) info==\n", filename);
disp_sfloopinfo(&sfloopinfo;);
}
}
// should we show instrument info?
if ( displaymode > = 0 )
{
// report if we fail/succeed obtaining info
memset(&sfinstrument;, 0, sizeof(sfinstrument));
if (sf_command(infile, SFC_GET_INSTRUMENT, &sfinstrument;, sizeof(sfinstrument) ) == SF_FALSE)
printf("==%s Error reading instrument (MIDI/Sample) info==\n", filename);
else
{
printf("==%s Instrument (MIDI/Sample) info==\n", filename);
disp_sfinstrument(&sfinstrument;);
}
}
exit(0);
}