File outputs

This commit is contained in:
Mark Hills 2011-12-06 15:40:21 +00:00
parent 9d7dcb001c
commit e3cfa32fc8
1 changed files with 46 additions and 19 deletions

55
bpm.c
View File

@ -25,8 +25,8 @@
#include <sysexits.h> #include <sysexits.h>
#include <unistd.h> #include <unistd.h>
#define BANNER "tempo 0.1 (C) Copyright 2011 Mark Hills <mark@pogo.org.uk>" #define BANNER "bpm 0.1 (C) Copyright 2011 Mark Hills <mark@pogo.org.uk>"
#define NAME "tempo" #define NAME "bpm"
#define RATE 44100 /* of input data */ #define RATE 44100 /* of input data */
@ -122,7 +122,7 @@ double scan_for_bpm(float nrg[], size_t len,
double slowest, double fastest, double slowest, double fastest,
unsigned int steps, unsigned int steps,
unsigned int samples, unsigned int samples,
bool graph) FILE *file)
{ {
double step, interval, trough, height; double step, interval, trough, height;
unsigned int s; unsigned int s;
@ -140,8 +140,8 @@ double scan_for_bpm(float nrg[], size_t len,
for (s = 0; s < samples; s++) for (s = 0; s < samples; s++)
t += autodifference(nrg, len, interval); t += autodifference(nrg, len, interval);
if (graph) { if (file != NULL) {
printf("%lf\t%lf\n", fprintf(file, "%lf\t%lf\n",
interval_to_bpm(interval), interval_to_bpm(interval),
t / samples); t / samples);
} }
@ -161,17 +161,18 @@ void usage(FILE *f)
{ {
fprintf(f, "Usage: " NAME " [options]\n" fprintf(f, "Usage: " NAME " [options]\n"
"Analyse the tempo (in beats-per-minute, BPM) of incoming audio\n\n" "Analyse the tempo (in beats-per-minute, BPM) of incoming audio\n\n"
" -g Output autodifference graph to stdout\n" " -g <path> Output autodifference data to file\n"
" -e <path> Output energy data to file\n"
" -f Print format for final BPM value (default \"%%0.1f\")\n" " -f Print format for final BPM value (default \"%%0.1f\")\n"
" -v Print progress information to stderr\n" " -v Print progress information to stderr\n"
" -h Display this help message and exit\n\n"); " -h Display this help message and exit\n\n");
fprintf(f, "Incoming audio is raw audio on stdin at %dHz, mono, 32-bit float; eg.\n" fprintf(f, "Incoming audio is raw audio on stdin at %dHz, mono, 32-bit float; eg.\n"
" $ sox file.mp3 -t raw -r %d -e float -c 1 | ./" NAME "\n\n", " $ sox file.mp3 -t raw -r %d -e float -c 1 - | ./" NAME "\n\n",
RATE, RATE); RATE, RATE);
fprintf(f, "To view autodifference graph:\n" fprintf(f, "To view autodifference or energy data:\n"
" $ sox [...] | ./tempo -g > file.dat\n" " $ sox [...] | ./tempo -g file.dat\n"
" $ gnuplot\n" " $ gnuplot\n"
" gnuplot> plot \"file.dat\"\n\n"); " gnuplot> plot \"file.dat\"\n\n");
} }
@ -183,11 +184,12 @@ int main(int argc, char *argv[])
off_t n = 0; off_t n = 0;
float bpm, v = 0.0; float bpm, v = 0.0;
const char *format = "%0.1f"; const char *format = "%0.1f";
FILE *fdiff = NULL, *fnrg = NULL;
for (;;) { for (;;) {
int c; int c;
c = getopt(argc, argv, "vf:gh"); c = getopt(argc, argv, "vf:g:e:h");
if (c == -1) if (c == -1)
break; break;
@ -197,7 +199,19 @@ int main(int argc, char *argv[])
break; break;
case 'g': case 'g':
format = NULL; fdiff = fopen(optarg, "w");
if (fdiff == NULL) {
perror(optarg);
return -1;
}
break;
case 'e':
fnrg = fopen(optarg, "w");
if (fnrg == NULL) {
perror(optarg);
return -1;
}
break; break;
case 'h': case 'h':
@ -253,17 +267,30 @@ int main(int argc, char *argv[])
buf = n; buf = n;
} }
if (fnrg != NULL) {
fprintf(fnrg, "%lf\t%lf\n",
(double)len * INTERVAL / RATE, v);
}
nrg[len++] = v; nrg[len++] = v;
} }
bpm = scan_for_bpm(nrg, len, 60.0, 170.0, 800, 1000, (format == NULL)); bpm = scan_for_bpm(nrg, len, 72.0, 168.0, 1200, 1200, fdiff);
if (format != NULL) {
printf(format, bpm); printf(format, bpm);
putc('\n', stdout); putc('\n', stdout);
}
free(nrg); free(nrg);
if (fdiff != NULL) {
if (fclose(fdiff) != 0)
perror("fclose");
}
if (fnrg != NULL) {
if (fclose(fnrg) != 0)
perror("fclose");
}
return 0; return 0;
} }