3 Copyright (C) 2011 Ying-Chun Liu (PaulLiu) <paulliu@debian.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * Create an empty dat file
31 * @param filename the filename of dat file
33 void wfd_init(const char *filename) {
35 file1 = fopen(filename,"w");
42 * convert micro seconds to samples
44 * @param time time in ms
47 int wfd_ms2samples(double time) {
50 samples_f = ((double)wfh_samplerate) * time / 1000.0;
51 samples = (int)samples_f;
56 * skip the file by microseconds
58 * @param inputfile the file descriptor
59 * @param time time in ms
61 void wfd_skip(FILE *inputfile, double time) {
63 samples = wfd_ms2samples(time);
64 fseek(inputfile,SEEK_CUR,samples*wfh_channels*(wfh_bits/8));
68 * Get volume factor by frame number
70 * @param frame Current frame number
71 * @param p the p vector, 7 elements, sort by time (ms)
72 * @param v the v vector, 7 elements, sort based on p (%)
73 * @return the volume factor for frame. (%)
75 double wfd_append_linear_volume(int frame, const int *p, const double *v) {
79 if (p[i] <= frame && frame < p[i+1]) {
80 ret = v[i] + (v[i+1]-v[i]) * (((double)(frame-p[i])) / (((double)(p[i+1]-p[i]))));
88 * append data to dat file
90 * @param outputfilename the filename of output file
91 * @param inputfilename the filename of input file
92 * @param offset skip the ms in input file
93 * @param length the time in ms have to be handled
94 * @param ovr the overlap of output file and input file (ms)
95 * @param p the p position array
96 * @param v the v volume array
97 * @return 0 - ok, nonzero - error
99 int wfd_append(const char *outputfilename, const char *inputfilename,
100 double offset, double length,
101 double ovr, const double *p, const double *v) {
104 SNDFILE *inputfile=NULL;
105 SF_INFO inputfileinfo;
116 memset(&inputfileinfo,0,sizeof(SF_INFO));
117 outfile = fopen(outputfilename,"r+");
118 fseek(outfile,0,SEEK_END);
120 inputfile = sf_open(inputfilename,SFM_READ,&inputfileinfo);
121 sf_command(inputfile,SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
125 outputFrames = wfd_ms2samples(length);
128 if (wfd_ms2samples(offset)>0) {
130 sf_seek(inputfile,wfd_ms2samples(offset),SEEK_SET);
134 /* pre-calculate volume */
136 for (i=0; i<2; i++) {
137 p_f[i+1] = wfd_ms2samples(p[i]) + p_f[i];
139 p_f[3] = wfd_ms2samples(p[4]) + p_f[2];
140 p_f[6] = outputFrames;
141 p_f[5] = p_f[6] - wfd_ms2samples(p[3]);
142 p_f[4] = p_f[5] - wfd_ms2samples(p[2]);
153 if (p_f[1]==p_f[2]) {
156 if (p_f[0]==p_f[1]) {
159 if (p_f[5]==p_f[4]) {
162 if (p_f[6]==p_f[5]) {
166 ovrFrames = wfd_ms2samples(ovr);
168 fseek(outfile,(-1)*wfh_channels*(wfh_bits/8)*ovrFrames,SEEK_END);
169 } else if (ovr < 0.0) {
170 /* output blank samples */
173 ovrSamples = wfd_ms2samples(-ovr);
174 for (i=0; i<ovrSamples; i++) {
175 for (j=0; j<wfh_channels; j++) {
176 for (k=0; k<(wfh_bits/8); k++) {
177 fwrite("\0",1,1,outfile);
186 buf = (short *)malloc(sizeof(short)*(inputfileinfo.channels));
187 memset(buf,0,sizeof(short)*(inputfileinfo.channels));
190 for ( ; outputFrames > 0; outputFrames--) {
193 result1 = sf_readf_short(inputfile,buf,1);
195 memset(buf,0,sizeof(short)*(inputfileinfo.channels));
200 /* simple mix if there are multi-channels */
202 for (i=0; i<inputfileinfo.channels; i++) {
205 /* modify the volume */
206 if (inputfileinfo.channels>0) {
208 sum = sum/inputfileinfo.channels;
209 vf = wfd_append_linear_volume(currentFrame,p_f,v_f);
210 sum = (short)(((double)sum)*(vf/100.0));
219 goto wfd_append_normal;
224 goto wfd_append_normal;
226 fseek(outfile,-2,SEEK_CUR);
227 d = (c1 & (0x00ff)) | (((c2 & 0x00ff) << 8) & 0xff00);
229 fputc( (char)(r & (0x00ff)), outfile);
230 fputc( (char)((r>>8) & 0x00ff), outfile);
234 fputc( (char)(sum & (0x00ff)), outfile);
235 fputc( (char)((sum>>8) & 0x00ff), outfile);
248 ret = ftell(outfile);