1/* 2** Copyright (C) 1999-2015 Erik de Castro Lopo <erikd@mega-nerd.com> 3** 4** All rights reserved. 5** 6** Redistribution and use in source and binary forms, with or without 7** modification, are permitted provided that the following conditions are 8** met: 9** 10** * Redistributions of source code must retain the above copyright 11** notice, this list of conditions and the following disclaimer. 12** * Redistributions in binary form must reproduce the above copyright 13** notice, this list of conditions and the following disclaimer in 14** the documentation and/or other materials provided with the 15** distribution. 16** * Neither the author nor the names of any contributors may be used 17** to endorse or promote products derived from this software without 18** specific prior written permission. 19** 20** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*/ 32 33/* 34** A quick/rough hack to add SF_INSTRUMENT data to a file. It compiles, but 35** no guarantees beyond that. Happy to receive patches to fix/improve it. 36** 37** Code for this was stolen from programs/sndfile-convert.c and related code. 38*/ 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43#include <ctype.h> 44 45#include <sndfile.h> 46 47#define BUFFER_LEN (1 << 14) 48 49const char * program_name (const char * argv0) ; 50static void sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ; 51static void add_instrument_data (SNDFILE *outfile, const SF_INFO * in_info) ; 52 53static void 54usage_exit (const char *progname) 55{ 56 printf ("\nUsage : %s <input file> <output file>\n", progname) ; 57 puts ("") ; 58 exit (1) ; 59} /* usage_exit */ 60 61int 62main (int argc, char * argv []) 63{ const char *progname, *infilename, *outfilename ; 64 SNDFILE *infile = NULL, *outfile = NULL ; 65 SF_INFO in_sfinfo, out_sfinfo ; 66 67 progname = program_name (argv [0]) ; 68 69 if (argc < 3 || argc > 5) 70 usage_exit (progname) ; 71 72 infilename = argv [argc-2] ; 73 outfilename = argv [argc-1] ; 74 75 if (strcmp (infilename, outfilename) == 0) 76 { printf ("Error : Input and output filenames are the same.\n\n") ; 77 usage_exit (progname) ; 78 } ; 79 80 if (strlen (infilename) > 1 && infilename [0] == '-') 81 { printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ; 82 usage_exit (progname) ; 83 } ; 84 85 if (outfilename [0] == '-') 86 { printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ; 87 usage_exit (progname) ; 88 } ; 89 90 memset (&in_sfinfo, 0, sizeof (in_sfinfo)) ; 91 92 if ((infile = sf_open (infilename, SFM_READ, &in_sfinfo)) == NULL) 93 { printf ("Not able to open input file %s.\n", infilename) ; 94 puts (sf_strerror (NULL)) ; 95 return 1 ; 96 } ; 97 98 memcpy (&out_sfinfo, &in_sfinfo, sizeof (out_sfinfo)) ; 99 /* Open the output file. */ 100 if ((outfile = sf_open (outfilename, SFM_WRITE, &out_sfinfo)) == NULL) 101 { printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ; 102 sf_close (infile) ; 103 return 1 ; 104 } ; 105 106 /* Add the loop data */ 107 add_instrument_data (outfile, &in_sfinfo) ; 108 109 /* Copy the audio data */ 110 sfe_copy_data_int (outfile, infile, in_sfinfo.channels) ; 111 112 sf_close (infile) ; 113 sf_close (outfile) ; 114 115 return 0 ; 116} /* main */ 117 118const char * 119program_name (const char * argv0) 120{ const char * tmp ; 121 122 tmp = strrchr (argv0, '/') ; 123 argv0 = tmp ? tmp + 1 : argv0 ; 124 125 /* Remove leading libtool name mangling. */ 126 if (strstr (argv0, "lt-") == argv0) 127 return argv0 + 3 ; 128 129 return argv0 ; 130} /* program_name */ 131 132static void 133sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) 134{ static int data [BUFFER_LEN] ; 135 int frames, readcount ; 136 137 frames = BUFFER_LEN / channels ; 138 readcount = frames ; 139 140 while (readcount > 0) 141 { readcount = (int) sf_readf_int (infile, data, frames) ; 142 sf_writef_int (outfile, data, readcount) ; 143 } ; 144 145 return ; 146} /* sfe_copy_data_int */ 147 148static void 149add_instrument_data (SNDFILE *file, const SF_INFO *info) 150{ SF_INSTRUMENT instr ; 151 152 memset (&instr, 0, sizeof (instr)) ; 153 154 instr.gain = 1 ; 155 instr.basenote = 0 ; 156 instr.detune = 0 ; 157 instr.velocity_lo = 0 ; 158 instr.velocity_hi = 0 ; 159 instr.key_lo = 0 ; 160 instr.key_hi = 0 ; 161 instr.loop_count = 1 ; 162 163 instr.loops [0].mode = SF_LOOP_FORWARD ; 164 instr.loops [0].start = 0 ; 165 instr.loops [0].end = info->frames ; 166 instr.loops [0].count = 0 ; 167 168 if (sf_command (file, SFC_SET_INSTRUMENT, &instr, sizeof (instr)) == SF_FALSE) 169 { printf ("\n\nLine %d : sf_command (SFC_SET_INSTRUMENT) failed.\n\n", __LINE__) ; 170 exit (1) ; 171 } ; 172 173 return ; 174} /* add_instrument_data */ 175 176