1/* 2** Copyright (C) 2001-2013 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#include <stdio.h> 34#include <string.h> 35 36/* Include this header file to use functions from libsndfile. */ 37#include <sndfile.h> 38 39/* This will be the length of the buffer used to hold.frames while 40** we process them. 41*/ 42#define BUFFER_LEN 1024 43 44/* libsndfile can handle more than 6 channels but we'll restrict it to 6. */ 45#define MAX_CHANNELS 6 46 47/* Function prototype. */ 48static void process_data (double *data, int count, int channels) ; 49 50 51int 52main (void) 53{ /* This is a buffer of double precision floating point values 54 ** which will hold our data while we process it. 55 */ 56 static double data [BUFFER_LEN] ; 57 58 /* A SNDFILE is very much like a FILE in the Standard C library. The 59 ** sf_open function return an SNDFILE* pointer when they sucessfully 60 ** open the specified file. 61 */ 62 SNDFILE *infile, *outfile ; 63 64 /* A pointer to an SF_INFO struct is passed to sf_open. 65 ** On read, the library fills this struct with information about the file. 66 ** On write, the struct must be filled in before calling sf_open. 67 */ 68 SF_INFO sfinfo ; 69 int readcount ; 70 const char *infilename = "input.wav" ; 71 const char *outfilename = "output.wav" ; 72 73 /* The SF_INFO struct must be initialized before using it. 74 */ 75 memset (&sfinfo, 0, sizeof (sfinfo)) ; 76 77 /* Here's where we open the input file. We pass sf_open the file name and 78 ** a pointer to an SF_INFO struct. 79 ** On successful open, sf_open returns a SNDFILE* pointer which is used 80 ** for all subsequent operations on that file. 81 ** If an error occurs during sf_open, the function returns a NULL pointer. 82 ** 83 ** If you are trying to open a raw headerless file you will need to set the 84 ** format and channels fields of sfinfo before calling sf_open(). For 85 ** instance to open a raw 16 bit stereo PCM file you would need the following 86 ** two lines: 87 ** 88 ** sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 ; 89 ** sfinfo.channels = 2 ; 90 */ 91 if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) 92 { /* Open failed so print an error message. */ 93 printf ("Not able to open input file %s.\n", infilename) ; 94 /* Print the error message from libsndfile. */ 95 puts (sf_strerror (NULL)) ; 96 return 1 ; 97 } ; 98 99 if (sfinfo.channels > MAX_CHANNELS) 100 { printf ("Not able to process more than %d channels\n", MAX_CHANNELS) ; 101 sf_close (infile) ; 102 return 1 ; 103 } ; 104 /* Open the output file. */ 105 if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo))) 106 { printf ("Not able to open output file %s.\n", outfilename) ; 107 puts (sf_strerror (NULL)) ; 108 sf_close (infile) ; 109 return 1 ; 110 } ; 111 112 /* While there are.frames in the input file, read them, process 113 ** them and write them to the output file. 114 */ 115 while ((readcount = (int) sf_read_double (infile, data, BUFFER_LEN))) 116 { process_data (data, readcount, sfinfo.channels) ; 117 sf_write_double (outfile, data, readcount) ; 118 } ; 119 120 /* Close input and output files. */ 121 sf_close (infile) ; 122 sf_close (outfile) ; 123 124 return 0 ; 125} /* main */ 126 127static void 128process_data (double *data, int count, int channels) 129{ double channel_gain [MAX_CHANNELS] = { 0.5, 0.8, 0.1, 0.4, 0.4, 0.9 } ; 130 int k, chan ; 131 132 /* Process the data here. 133 ** If the soundfile contains more then 1 channel you need to take care of 134 ** the data interleaving youself. 135 ** Current we just apply a channel dependant gain. 136 */ 137 138 for (chan = 0 ; chan < channels ; chan ++) 139 for (k = chan ; k < count ; k+= channels) 140 data [k] *= channel_gain [chan] ; 141 142 return ; 143} /* process_data */ 144 145