r663: This commit was generated by cvs2svn to compensate for changes in r662,
[cinelerra_cv.git] / libsndfile / examples / cooledit-fixer.c
blobd446f677082ebab0c2f34fda67d117fec0b2216a
1 #include <stdio.h>
2 #include <string.h>
3 #include <math.h>
4 #include <sys/stat.h>
6 #include <sndfile.h>
8 #define BUFFER_LEN 1024
10 static void usage_exit (char *progname) ;
11 static int is_data_really_float (SNDFILE *sndfile) ;
12 static void fix_file (char *filename) ;
13 static off_t file_size (char *filename) ;
15 static int buffer [BUFFER_LEN] ;
17 int
18 main (int argc, char *argv [])
19 { SNDFILE *sndfile ;
20 SF_INFO sfinfo ;
21 int k, data_is_float, converted = 0 ;
23 puts ("\nCooledit Fixer.\n---------------") ;
25 if (argc < 2)
26 usage_exit (argv [0]) ;
28 for (k = 1 ; k < argc ; k++)
29 { if ((sndfile = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL)
30 { /*-printf ("Failed to open : %s\n", argv [k]) ;-*/
31 continue ;
32 } ;
34 if (sfinfo.format != (SF_FORMAT_WAV | SF_FORMAT_PCM_32))
35 { /*-printf ("%-50s : not a 32 bit PCM WAV file.\n", argv [k]) ;-*/
36 sf_close (sndfile) ;
37 continue ;
38 } ;
40 data_is_float = is_data_really_float (sndfile) ;
42 sf_close (sndfile) ;
44 if (data_is_float == SF_FALSE)
45 { /*-printf ("%-50s : not a Cooledit abomination.\n", argv [k]) ;-*/
46 continue ;
47 } ;
49 fix_file (argv [k]) ;
50 converted ++ ;
51 } ;
53 if (converted == 0)
54 puts ("\nNo files converted.") ;
56 puts ("") ;
58 return 0 ;
59 } /* main */
62 static void
63 usage_exit (char *progname)
64 { char *cptr ;
66 if ((cptr = strrchr (progname, '/')))
67 progname = cptr + 1 ;
68 if ((cptr = strrchr (progname, '\\')))
69 progname = cptr + 1 ;
71 printf ("\n Usage : %s <filename>\n", progname) ;
72 puts ("\n"
73 "Fix broken files created by Syntrillium's Cooledit. These files are \n"
74 "marked as containing PCM data but actually contain floating point \n"
75 "data. Only the broken files created by Cooledit are processed. All \n"
76 "other files remain untouched.\n"
77 "\n"
78 "More than one file may be included on the command line. \n"
79 ) ;
81 exit (1) ;
82 } /* usage_exit */
84 static int
85 is_data_really_float (SNDFILE *sndfile)
86 { float *fptr ;
87 int k, readcount ;
89 fptr = (float *) buffer ;
91 while ((readcount = sf_read_int (sndfile, buffer, BUFFER_LEN)) > 0)
92 { for (k = 0 ; k < readcount ; k++)
93 { if (buffer [k] == 0)
94 continue ;
96 if (fabs (fptr [k]) > 32768.0)
97 return SF_FALSE ;
98 } ;
99 } ;
101 return SF_TRUE ;
102 } /* is_data_really_float */
104 static void
105 fix_file (char *filename)
106 { static char newfilename [512] ;
108 SNDFILE *infile, *outfile ;
109 SF_INFO sfinfo ;
110 int readcount, k ;
111 float *fptr, normfactor ;
112 char *cptr ;
114 printf ("\nFixing : %s\n", filename) ;
116 if ((infile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
117 { printf ("Not able to open input file %s\n", filename) ;
118 exit (1) ;
121 if (strlen (filename) >= sizeof (newfilename) - 1)
122 { puts ("Error : Path name too long.\n") ;
123 exit (1) ;
126 strncpy (newfilename, filename, sizeof (newfilename)) ;
127 newfilename [sizeof (newfilename) - 1] = 0 ;
129 if ((cptr = strrchr (newfilename, '/')) == NULL)
130 cptr = strrchr (newfilename, '\\') ;
132 if (cptr)
133 { cptr [1] = 0 ;
134 strncat (newfilename, "fixed.wav", sizeof (newfilename) - strlen (newfilename) - 1) ;
136 else
137 strncpy (newfilename, "fixed.wav", sizeof (newfilename) - 1) ;
139 newfilename [sizeof (newfilename) - 1] = 0 ;
141 printf (" Output : %s\n", newfilename) ;
143 sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT ;
145 if ((outfile = sf_open (newfilename, SFM_WRITE, &sfinfo)) == NULL)
146 { printf ("Not able to output open file %s\n", filename) ;
147 exit (1) ;
150 /* Find the file peak. sf-command (SFC_CALC_SIGNAL_MAX) cannot be used. */
152 fptr = (float *) buffer ;
154 normfactor = 0.0 ;
156 while ((readcount = sf_read_int (infile, buffer, BUFFER_LEN)) > 0)
157 { for (k = 0 ; k < readcount ; k++)
158 if (fabs (fptr [k]) > normfactor)
159 normfactor = fabs (fptr [k]) ;
162 printf (" Peak : %g\n", normfactor) ;
164 normfactor = 1.0 / normfactor ;
166 sf_seek (infile, 0, SEEK_SET) ;
168 while ((readcount = sf_read_int (infile, buffer, BUFFER_LEN)) > 0)
169 { for (k = 0 ; k < readcount ; k++)
170 fptr [k] *= normfactor ;
171 sf_write_float (outfile, fptr, readcount) ;
174 sf_close (infile) ;
175 sf_close (outfile) ;
177 if (abs (file_size (filename) - file_size (newfilename)) > 50)
178 { puts ("Error : file size mismatch.\n") ;
179 exit (1) ;
182 printf (" Renaming : %s\n", filename) ;
184 if (remove (filename) != 0)
185 { perror ("rename") ;
186 exit (1) ;
189 if (rename (newfilename, filename) != 0)
190 { perror ("rename") ;
191 exit (1) ;
194 return ;
195 } /* fix_file */
197 static off_t
198 file_size (char *filename)
199 { struct stat buf ;
201 if (stat (filename, &buf) != 0)
202 { perror ("stat") ;
203 exit (1) ;
206 return buf.st_size ;
207 } /* file_size */