examples: more header updates to GPLv3
[aubio.git] / examples / aubionotes.c
1 /*
2   Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
3
4   This file is part of aubio.
5
6   aubio is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   aubio is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #define AUBIO_UNSTABLE 1 // for fvec_median_channel
22
23 #include "utils.h"
24
25 /* pitch objects */
26 smpl_t pitch = 0.;
27
28 uint_t median = 6;
29 smpl_t curlevel = 0.;
30
31 aubio_pitch_t *pitchdet;
32
33 fvec_t *note_buffer = NULL;
34 fvec_t *note_buffer2 = NULL;
35
36 smpl_t curnote = 0.;
37 smpl_t newnote = 0.;
38 uint_t isready = 0;
39 unsigned int pos = 0; /*frames%dspblocksize*/
40
41 aubio_pitch_t *pitchdet;
42 aubio_onset_t *o;
43 fvec_t *onset;
44 fvec_t *pitch_obuf;
45
46 /** append new note candidate to the note_buffer and return filtered value. we
47  * need to copy the input array as fvec_median destroy its input data.*/
48 void note_append (fvec_t * note_buffer, smpl_t curnote);
49 uint_t get_note (fvec_t * note_buffer, fvec_t * note_buffer2);
50
51 static int aubio_process(smpl_t **input, smpl_t **output, int nframes) {
52   unsigned int i;       /*channels*/
53   unsigned int j;       /*frames*/
54   for (j=0;j<(unsigned)nframes;j++) {
55     if(usejack) {
56       for (i=0;i<channels;i++) {
57         /* write input to datanew */
58         fvec_write_sample(ibuf, input[i][j], i, pos);
59         /* put synthnew in output */
60         output[i][j] = fvec_read_sample(obuf, i, pos);
61       }
62     }
63     /*time for fft*/
64     if (pos == overlap_size-1) {         
65       /* block loop */
66       aubio_onset_do(o, ibuf, onset);
67       
68       aubio_pitch_do (pitchdet, ibuf, pitch_obuf);
69       pitch = fvec_read_sample(pitch_obuf, 0, 0);
70       if(median){
71               note_append(note_buffer, pitch);
72       }
73
74       /* curlevel is negatif or 1 if silence */
75       curlevel = aubio_level_detection(ibuf, silence);
76       if (fvec_read_sample(onset, 0, 0)) {
77               /* test for silence */
78               if (curlevel == 1.) {
79                       if (median) isready = 0;
80                       /* send note off */
81                       send_noteon(curnote,0);
82               } else {
83                       if (median) {
84                               isready = 1;
85                       } else {
86                               /* kill old note */
87                               send_noteon(curnote,0);
88                               /* get and send new one */
89                               send_noteon(pitch,127+(int)floor(curlevel));
90                               curnote = pitch;
91                       }
92
93                       for (pos = 0; pos < overlap_size; pos++){
94                               obuf->data[0][pos] = woodblock->data[0][pos];
95                       }
96               }
97       } else {
98               if (median) {
99                       if (isready > 0)
100                               isready++;
101                       if (isready == median)
102                       {
103                               /* kill old note */
104                               send_noteon(curnote,0);
105                               newnote = get_note(note_buffer, note_buffer2);
106                               curnote = newnote;
107                               /* get and send new one */
108                               if (curnote>45){
109                                       send_noteon(curnote,127+(int)floor(curlevel));
110                               }
111                       }
112               } // if median
113         for (pos = 0; pos < overlap_size; pos++)
114           obuf->data[0][pos] = 0.;
115       }
116       /* end of block loop */
117       pos = -1; /* so it will be zero next j loop */
118     }
119     pos++;
120   }
121   return 1;
122 }
123
124 static void process_print (void) {
125       if (verbose) outmsg("%f\n",pitch);
126 }
127
128 void
129 note_append (fvec_t * note_buffer, smpl_t curnote)
130 {
131   uint_t i = 0;
132   for (i = 0; i < note_buffer->length - 1; i++) {
133     note_buffer->data[0][i] = note_buffer->data[0][i + 1];
134   }
135   note_buffer->data[0][note_buffer->length - 1] = curnote;
136   return;
137 }
138
139 uint_t
140 get_note (fvec_t * note_buffer, fvec_t * note_buffer2)
141 {
142   uint_t i;
143   for (i = 0; i < note_buffer->length; i++) {
144     note_buffer2->data[0][i] = note_buffer->data[0][i];
145   }
146   return fvec_median_channel (note_buffer2, 0);
147 }
148
149 int main(int argc, char **argv) {
150   examples_common_init(argc,argv);
151
152   o = new_aubio_onset (onset_mode, buffer_size, overlap_size, channels,
153           samplerate);
154   if (threshold != 0.) aubio_onset_set_threshold (o, threshold);
155   onset = new_fvec (1, channels);
156
157   pitchdet = new_aubio_pitch (pitch_mode, buffer_size * 4,
158           overlap_size, channels, samplerate);
159   aubio_pitch_set_tolerance (pitchdet, 0.7);
160   pitch_obuf = new_fvec (1, channels);
161   if (median) {
162       note_buffer = new_fvec (median, 1);
163       note_buffer2 = new_fvec (median, 1);
164   }
165
166   examples_common_process(aubio_process, process_print);
167
168   send_noteon (curnote, 0);
169   del_aubio_pitch (pitchdet);
170   if (median) {
171       del_fvec (note_buffer);
172       del_fvec (note_buffer2);
173   }
174   del_fvec (pitch_obuf);
175
176   examples_common_del();
177   debug("End of program.\n");
178   fflush(stderr);
179   return 0;
180 }
181