3 * gtk2 spectrum analyzer
5 * Copyright (C) 2004-2012 Monty
7 * This analyzer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * The analyzer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <fenv.h> // Thank you C99!
35 char *inputname
[MAX_FILES
];
37 int blocksize
= 32768;
40 void handler(int sig
){
44 "\nTrapped signal %d; exiting!\n"
45 "This signal almost certainly indicates a bug in the analyzer;\n"
46 "If this version of the analyzer is newer than a few months old,\n"
47 "please email a detailed report of the crash along with\n"
48 "processor type, OS version, FFTW3 version, and as much\n"
49 "information as possible about what caused the crash. The best\n"
50 "possible report will outline the exact steps needed to\n"
51 "reproduce the error, ensuring that I can fix the bug as\n"
52 "quickly as possible.\n\n"
53 "-- monty@xiph.org, spectrum revision %s\n\n",sig
,version
);
59 const char *optstring
= "-r:c:EeBlb:suhF:T";
61 struct option options
[] = {
62 {"bold",no_argument
,NULL
,'T'},
63 {"rate",required_argument
,NULL
,'r'},
64 {"channels",required_argument
,NULL
,'c'},
65 {"big-endian",no_argument
,NULL
,'E'},
66 {"little-endian",no_argument
,NULL
,'e'},
67 {"bits",required_argument
,NULL
,'b'},
68 {"signed",no_argument
,NULL
,'s'},
69 {"unsigned",no_argument
,NULL
,'u'},
70 {"help",no_argument
,NULL
,'h'},
71 {"fft-size",required_argument
,NULL
,'F'},
76 static void usage(FILE *f
){
78 "\ngtk2 spectrum analyzer, revision %s\n\n"
81 " spectrum [options] [file]\n\n"
84 " -b --bits <bits> : Force input to be read as 8, 16, 24 or 32 bit\n"
85 " PCM. Default bit depth is normally read from\n"
86 " the file/stream header or set to 16 bits\n"
88 " -B -E --big-endian : Force input to be read as big endian.\n"
89 " Default endianness is normally read from the\n"
90 " file/stream header or set to host"
91 " endianness for raw input.\n"
92 " -c --channels <channels> : Input channel number override; use to\n"
93 " specify the number of channels in a raw\n"
94 " input. default: 1\n"
95 " -e -l --little-endian : Force input to be read as little endian.\n"
96 " Default endianness is normally read from the\n"
97 " file/stream header or set to host"
98 " endianness for raw input.\n"
99 " -F --fft-size : Set the size of the fft transform used. Valid\n"
100 " range 8192 to 262144, 131072 default.\n"
101 " -h --help : print this help\n"
102 " -r --rate <Hz> : Input sample rate override in Hz; use to\n"
103 " specify the rate of a raw input.\n"
105 " -s --signed : Force input to be read as signed PCM.\n"
106 " Signedness is normally read from the \n"
107 " file/stream header or set to signed for raw\n"
109 " -T --bold : plot spectrum with thicker/bolder lines.\n"
110 " -u --unsigned : Force input to be read as unsigned PCM.\n"
111 " Signedness is normally read from the \n"
112 " file/stream header or set to signed for raw\n"
117 " Spectrum takes raw, WAV or AIFF input either from stdin or from \n"
118 " file[s]/stream[s] specified on the command line.\n\n",version
);
122 void parse_command_line(int argc
, char **argv
){
123 int c
,long_option_index
;
125 while((c
=getopt_long(argc
,argv
,optstring
,options
,&long_option_index
))!=EOF
){
128 /* file name that belongs to current group */
129 if(inputs
>=MAX_FILES
){
130 fprintf(stderr
,"Maximum of MAX_FILES input files exceeded. Oops. Programmer was lazy.\n\n");
133 inputname
[inputs
++]=strdup(optarg
);
139 /* force bit width */
143 bits_force
[inputs
]=1;
144 if(a
!=8 && a
!=16 && a
!=24 && a
!=32){
151 blocksize
= atoi(optarg
);
152 if(blocksize
<8192 || blocksize
>262144){
158 /* force big endian */
160 bigendian_force
[inputs
]=1;
167 channels_force
[inputs
]=1;
175 /* force little endian */
177 bigendian_force
[inputs
]=1;
187 rate_force
[inputs
]=1;
188 if(a
<4000 || a
>200000){
197 signed_force
[inputs
]=1;
202 signed_force
[inputs
]=1;
212 void sigill_handler(int sig
){
214 if(sig
==SIGILL
)sigill
=1;
217 int main(int argc
, char **argv
){
219 version
=strstr(VERSION
,"version.h");
221 char *versionend
=strchr(version
,' ');
222 if(versionend
)versionend
=strchr(versionend
+1,' ');
223 if(versionend
)versionend
=strchr(versionend
+1,' ');
224 if(versionend
)versionend
=strchr(versionend
+1,' ');
226 int len
=versionend
-version
-9;
227 version
=strdup(version
+10);
234 /* parse command line and open all the input files */
235 parse_command_line(argc
, argv
);
237 /* We do not care about FPEs; rather, underflow is nominal case, and
238 its better to ignore other traps in production than to crash the
239 app. Please inform the FPU of this. */
242 fedisableexcept(FE_INVALID
);
243 fedisableexcept(FE_INEXACT
);
244 fedisableexcept(FE_UNDERFLOW
);
245 fedisableexcept(FE_OVERFLOW
);
247 feenableexcept(FE_INVALID
);
248 feenableexcept(FE_INEXACT
);
249 feenableexcept(FE_UNDERFLOW
);
250 feenableexcept(FE_OVERFLOW
);
253 /* Linux Altivec support has a very annoying problem; by default,
254 math on denormalized floats will simply crash the program. FFTW3
255 uses Altivec, so boom, but only random booms.
257 By the C99 spec, the above exception configuration is also
258 supposed to handle Altivec config, but doesn't. So we use the
259 below ugliness to both handle altivec and non-alitvec PPC. */
263 signal(SIGILL
,sigill_handler
);
265 #if (defined __GNUC__) && (__GNUC__ == 3) && ! (defined __APPLE_CC__)
266 __vector
unsigned short noTrap
=
267 (__vector
unsigned short){0,0,0,0,0,0,0x1,0};
269 vector
unsigned short noTrap
=
270 (vector
unsigned short)(0,0,0,0,0,0,0x1,0);
276 /* easiest way to inform gtk of changes and not deal with locking
277 issues around the UI */
279 fprintf(stderr
,"Unable to open event pipe:\n"
280 " %s\n",strerror(errno
));
285 /* Allows event compression on the read side */
286 if(fcntl(eventpipe
[0], F_SETFL
, O_NONBLOCK
)){
287 fprintf(stderr
,"Unable to set O_NONBLOCK on event pipe:\n"
288 " %s\n",strerror(errno
));
293 //signal(SIGINT,handler);
294 signal(SIGSEGV
,handler
);
297 if(input_load())exit(1);