Chris@40: /* Chris@40: ** Copyright (C) 1999-2015 Erik de Castro Lopo Chris@40: ** Chris@40: ** All rights reserved. Chris@40: ** Chris@40: ** Redistribution and use in source and binary forms, with or without Chris@40: ** modification, are permitted provided that the following conditions are Chris@40: ** met: Chris@40: ** Chris@40: ** * Redistributions of source code must retain the above copyright Chris@40: ** notice, this list of conditions and the following disclaimer. Chris@40: ** * Redistributions in binary form must reproduce the above copyright Chris@40: ** notice, this list of conditions and the following disclaimer in Chris@40: ** the documentation and/or other materials provided with the Chris@40: ** distribution. Chris@40: ** * Neither the author nor the names of any contributors may be used Chris@40: ** to endorse or promote products derived from this software without Chris@40: ** specific prior written permission. Chris@40: ** Chris@40: ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS Chris@40: ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED Chris@40: ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR Chris@40: ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR Chris@40: ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, Chris@40: ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, Chris@40: ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; Chris@40: ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, Chris@40: ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR Chris@40: ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF Chris@40: ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Chris@40: */ Chris@40: Chris@40: /* Chris@40: ** A quick/rough hack to add SF_INSTRUMENT data to a file. It compiles, but Chris@40: ** no guarantees beyond that. Happy to receive patches to fix/improve it. Chris@40: ** Chris@40: ** Code for this was stolen from programs/sndfile-convert.c and related code. Chris@40: */ Chris@40: Chris@40: #include Chris@40: #include Chris@40: #include Chris@40: #include Chris@40: Chris@40: #include Chris@40: Chris@40: #include "common.h" Chris@40: Chris@40: #define BUFFER_LEN (1 << 14) Chris@40: Chris@40: Chris@40: typedef struct Chris@40: { char *infilename, *outfilename ; Chris@40: SF_INFO infileinfo, outfileinfo ; Chris@40: } OptionData ; Chris@40: Chris@40: const char * program_name (const char * argv0) ; Chris@40: static void sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ; Chris@40: static void add_instrument_data (SNDFILE *outfile, const SF_INFO * in_info) ; Chris@40: Chris@40: static void Chris@40: usage_exit (const char *progname) Chris@40: { Chris@40: printf ("\nUsage : %s \n", progname) ; Chris@40: puts ("") ; Chris@40: exit (1) ; Chris@40: } /* usage_exit */ Chris@40: Chris@40: int Chris@40: main (int argc, char * argv []) Chris@40: { const char *progname, *infilename, *outfilename ; Chris@40: SNDFILE *infile = NULL, *outfile = NULL ; Chris@40: SF_INFO in_sfinfo, out_sfinfo ; Chris@40: Chris@40: progname = program_name (argv [0]) ; Chris@40: Chris@40: if (argc < 3 || argc > 5) Chris@40: usage_exit (progname) ; Chris@40: Chris@40: infilename = argv [argc-2] ; Chris@40: outfilename = argv [argc-1] ; Chris@40: Chris@40: if (strcmp (infilename, outfilename) == 0) Chris@40: { printf ("Error : Input and output filenames are the same.\n\n") ; Chris@40: usage_exit (progname) ; Chris@40: } ; Chris@40: Chris@40: if (strlen (infilename) > 1 && infilename [0] == '-') Chris@40: { printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ; Chris@40: usage_exit (progname) ; Chris@40: } ; Chris@40: Chris@40: if (outfilename [0] == '-') Chris@40: { printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ; Chris@40: usage_exit (progname) ; Chris@40: } ; Chris@40: Chris@40: memset (&in_sfinfo, 0, sizeof (in_sfinfo)) ; Chris@40: Chris@40: if ((infile = sf_open (infilename, SFM_READ, &in_sfinfo)) == NULL) Chris@40: { printf ("Not able to open input file %s.\n", infilename) ; Chris@40: puts (sf_strerror (NULL)) ; Chris@40: return 1 ; Chris@40: } ; Chris@40: Chris@40: memcpy (&out_sfinfo, &in_sfinfo, sizeof (out_sfinfo)) ; Chris@40: /* Open the output file. */ Chris@40: if ((outfile = sf_open (outfilename, SFM_WRITE, &out_sfinfo)) == NULL) Chris@40: { printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ; Chris@40: return 1 ; Chris@40: } ; Chris@40: Chris@40: /* Add the loop data */ Chris@40: add_instrument_data (outfile, &in_sfinfo) ; Chris@40: Chris@40: /* Copy the audio data */ Chris@40: sfe_copy_data_int (outfile, infile, in_sfinfo.channels) ; Chris@40: Chris@40: sf_close (infile) ; Chris@40: sf_close (outfile) ; Chris@40: Chris@40: return 0 ; Chris@40: } /* main */ Chris@40: Chris@40: const char * Chris@40: program_name (const char * argv0) Chris@40: { const char * tmp ; Chris@40: Chris@40: tmp = strrchr (argv0, '/') ; Chris@40: argv0 = tmp ? tmp + 1 : argv0 ; Chris@40: Chris@40: /* Remove leading libtool name mangling. */ Chris@40: if (strstr (argv0, "lt-") == argv0) Chris@40: return argv0 + 3 ; Chris@40: Chris@40: return argv0 ; Chris@40: } /* program_name */ Chris@40: Chris@40: static void Chris@40: sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) Chris@40: { static int data [BUFFER_LEN] ; Chris@40: int frames, readcount ; Chris@40: Chris@40: frames = BUFFER_LEN / channels ; Chris@40: readcount = frames ; Chris@40: Chris@40: while (readcount > 0) Chris@40: { readcount = sf_readf_int (infile, data, frames) ; Chris@40: sf_writef_int (outfile, data, readcount) ; Chris@40: } ; Chris@40: Chris@40: return ; Chris@40: } /* sfe_copy_data_int */ Chris@40: Chris@40: static void Chris@40: add_instrument_data (SNDFILE *file, const SF_INFO *info) Chris@40: { SF_INSTRUMENT instr ; Chris@40: Chris@40: memset (&instr, 0, sizeof (instr)) ; Chris@40: Chris@40: instr.gain = 1 ; Chris@40: instr.basenote = 0 ; Chris@40: instr.detune = 0 ; Chris@40: instr.velocity_lo = 0 ; Chris@40: instr.velocity_hi = 0 ; Chris@40: instr.key_lo = 0 ; Chris@40: instr.key_hi = 0 ; Chris@40: instr.loop_count = 1 ; Chris@40: Chris@40: instr.loops [0].mode = SF_LOOP_FORWARD ; Chris@40: instr.loops [0].start = 0 ; Chris@40: instr.loops [0].end = info->frames ; Chris@40: instr.loops [0].count = 0 ; Chris@40: Chris@40: if (sf_command (file, SFC_SET_INSTRUMENT, &instr, sizeof (instr)) == SF_FALSE) Chris@40: { printf ("\n\nLine %d : sf_command (SFC_SET_INSTRUMENT) failed.\n\n", __LINE__) ; Chris@40: exit (1) ; Chris@40: } ; Chris@40: Chris@40: return ; Chris@40: } /* add_instrument_data */ Chris@40: