andrew@5
|
1 /*
|
andrew@5
|
2 * BeatAnnotations.cpp
|
andrew@5
|
3 * BeatAnnotationViewer
|
andrew@5
|
4 *
|
andrew@5
|
5 * Created by Andrew on 31/10/2013.
|
andrew@5
|
6 * Copyright 2013 QMUL. All rights reserved.
|
andrew@5
|
7 *
|
andrew@5
|
8 */
|
andrew@5
|
9
|
andrew@5
|
10 #include "sndfile.h"
|
andrew@5
|
11 #include "BeatAnnotations.h"
|
andrew@5
|
12 //Beat tracking
|
andrew@5
|
13 #include "BTrack.h"
|
andrew@5
|
14 #include <Math.h>
|
andrew@5
|
15 #include "df.h"
|
andrew@5
|
16 #include "BeatWriter.h"
|
andrew@5
|
17
|
andrew@5
|
18 BeatAnnotations::BeatAnnotations(){
|
andrew@5
|
19 }
|
andrew@5
|
20
|
andrew@5
|
21 void BeatAnnotations::loadBeatsFromAnnotations(std::string filename){
|
andrew@5
|
22 reader.readInFile(filename);
|
andrew@5
|
23 }
|
andrew@5
|
24
|
andrew@5
|
25 int BeatAnnotations::processAudioForBeatTimes(std::string audiofile){
|
andrew@5
|
26
|
andrew@5
|
27 BeatWriter writer;
|
andrew@5
|
28
|
andrew@5
|
29 bool writeOutput = false;//write output to txt
|
andrew@5
|
30
|
andrew@5
|
31 // static double frame[FRAMESIZE]; // to hold a single frame
|
andrew@5
|
32 double buffer[FRAMESIZE*2];
|
andrew@5
|
33 double dfval;
|
andrew@5
|
34
|
andrew@5
|
35 for (int i = 0;i < (FRAMESIZE*2);i++)
|
andrew@5
|
36 {
|
andrew@5
|
37 buffer[i] = 0;
|
andrew@5
|
38 }
|
andrew@5
|
39
|
andrew@5
|
40 df *detfun;
|
andrew@5
|
41 BTrack b;
|
andrew@5
|
42
|
andrew@5
|
43 b.initialise(FRAMESIZE);
|
andrew@5
|
44
|
andrew@5
|
45 detfun = new df(1,(FRAMESIZE*2),0);
|
andrew@5
|
46
|
andrew@5
|
47 SNDFILE *infile, *outfile ; // define input and output sound files
|
andrew@5
|
48
|
andrew@5
|
49 SF_INFO sfinfo ; // struct to hold info about sound file
|
andrew@5
|
50 int readcount ; // counts number of samples read from sound file
|
andrew@5
|
51 const char *infilename = audiofile.c_str();
|
andrew@5
|
52 //"/Users/andrew/Music/Station To Station 2/3-03 Panic In Detroit (Live Nassau Coliseum '76).wav";//"ledzep.wav" ; // input file name
|
andrew@5
|
53 // const char *outfilename = "output.wav" ; // output file name
|
andrew@5
|
54
|
andrew@5
|
55 if (writeOutput)
|
andrew@5
|
56 writer.openFile("/Users/andrew/testFile.txt");
|
andrew@5
|
57
|
andrew@5
|
58 // Open Input File
|
andrew@5
|
59 if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
|
andrew@5
|
60 { // Open failed
|
andrew@5
|
61 printf ("Not able to open input file %s.\n", infilename) ;
|
andrew@5
|
62 /* Print the error message from libsndfile. */
|
andrew@5
|
63 puts (sf_strerror (NULL)) ;
|
andrew@5
|
64 return 1;
|
andrew@5
|
65 } ;
|
andrew@5
|
66
|
andrew@5
|
67 printf("opened '%s'\n", audiofile.c_str());
|
andrew@5
|
68
|
andrew@5
|
69 //STEREO OKAY
|
andrew@5
|
70
|
andrew@5
|
71 //HERE IS THE CLASSIC LOADING FILE CODE
|
andrew@5
|
72 //DEALS WITH MORE THAN MONO
|
andrew@5
|
73 int channels = sfinfo.channels;
|
andrew@5
|
74 int blocksize = FRAMESIZE;
|
andrew@5
|
75
|
andrew@5
|
76 float buf [channels * blocksize] ;
|
andrew@5
|
77 float frame[blocksize];
|
andrew@5
|
78
|
andrew@5
|
79 int k, m;
|
andrew@5
|
80 readcount = 1;
|
andrew@5
|
81 int counter = 0;
|
andrew@5
|
82
|
andrew@5
|
83 //DoubleVector d;
|
andrew@5
|
84 while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){
|
andrew@5
|
85 for (k = 0 ; k < readcount ; k++){
|
andrew@5
|
86 //d.clear();
|
andrew@5
|
87 frame[k] = 0;
|
andrew@5
|
88
|
andrew@5
|
89 for (m = 0 ; m < channels ; m++){
|
andrew@5
|
90 frame[k] += buf[k*channels + 0];//sum the channels together
|
andrew@5
|
91 //d.push_back(buf [k * channels + m]);
|
andrew@5
|
92 }
|
andrew@5
|
93
|
andrew@5
|
94 frame[k] /= channels;//average of the channels
|
andrew@5
|
95 }
|
andrew@5
|
96
|
andrew@5
|
97 //processing here
|
andrew@5
|
98 //add to our buffer for sending to Btrack
|
andrew@5
|
99 for (int i = 0; i< FRAMESIZE;i++)
|
andrew@5
|
100 {
|
andrew@5
|
101 buffer[i] = buffer[i+FRAMESIZE];
|
andrew@5
|
102 buffer[i+FRAMESIZE] = frame[i];
|
andrew@5
|
103 }
|
andrew@5
|
104
|
andrew@5
|
105 dfval = detfun->compute(buffer); // compute detection function sample
|
andrew@5
|
106
|
andrew@5
|
107 printf("det val %i: %f\n", counter, dfval);
|
andrew@5
|
108
|
andrew@5
|
109 b.process(dfval); // process df sample in beat tracker
|
andrew@5
|
110
|
andrew@5
|
111 if (b.playbeat == 1)
|
andrew@5
|
112 {
|
andrew@5
|
113 printf("BEAT:beat at frame %i, seconds %f\n", counter, (counter*FRAMESIZE/44100.));
|
andrew@5
|
114
|
andrew@5
|
115 if (writeOutput)
|
andrew@5
|
116 writer.writeBeatTime((counter*FRAMESIZE/44100.));
|
andrew@5
|
117 } else {
|
andrew@5
|
118 printf("not beat\n");
|
andrew@5
|
119 }
|
andrew@5
|
120 counter++;
|
andrew@5
|
121
|
andrew@5
|
122 //was sf_write_double(outfile, frame, readcount) ;
|
andrew@5
|
123
|
andrew@5
|
124 }//end readcount
|
andrew@5
|
125 //END STEREO OKAY
|
andrew@5
|
126
|
andrew@5
|
127 // Close input file
|
andrew@5
|
128 sf_close (infile);
|
andrew@5
|
129
|
andrew@5
|
130 if (writeOutput)
|
andrew@5
|
131 writer.closeFile();
|
andrew@5
|
132
|
andrew@5
|
133 delete detfun;
|
andrew@5
|
134
|
andrew@5
|
135 return 0;
|
andrew@5
|
136
|
andrew@5
|
137 }
|
andrew@5
|
138
|
andrew@5
|
139 void BeatAnnotations::draw(){
|
andrew@5
|
140
|
andrew@5
|
141 }
|
andrew@5
|
142
|