Revision 0:635e8745ccc9
| .hgsub | ||
|---|---|---|
| 1 |
onsetsds = [git]https://github.com/danstowell/onsetsds |
|
| 2 |
|
|
| .hgsubstate | ||
|---|---|---|
| 1 |
3b5daceeb8f419e95c72ed767765714177ff275f onsetsds |
|
| Makefile | ||
|---|---|---|
| 1 | 1 |
|
| 2 |
CXXFLAGS := -I../vamp-plugin-sdk -O3 -Wall -fPIC |
|
| 3 |
CFLAGS := -O3 -Wall -fPIC |
|
| 2 |
CXXFLAGS := -I../vamp-plugin-sdk -O3 -Wall |
|
| 3 |
#CXXFLAGS := -I../vamp-plugin-sdk -g -Wall -march=pentium4 -msse -msse2 -ffast-math |
|
| 4 |
#CXXFLAGS := -I../vamp-plugin-sdk -O3 -Wall -march=pentium4 -msse -msse2 -fomit-frame-pointer -ffast-math |
|
| 4 | 5 |
|
| 5 |
vamp-onsetsds.so: onsetsdsplugin.o onsetsds/src/onsetsds.o
|
|
| 6 |
vamp-onsetsds.so: onsetsdsplugin.o onsetsds/onsetsds.o |
|
| 6 | 7 |
g++ -shared $^ -o $@ -L../vamp-plugin-sdk/vamp-sdk -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -lpthread |
| 7 | 8 |
|
| 8 | 9 |
clean: |
| 9 |
rm -f *.o */src/*.o
|
|
| 10 |
rm -f *.o */*.o |
|
| 10 | 11 |
|
| 11 |
onsetsdsplugin.o: onsetsdsplugin.h onsetsds/src/onsetsds.h |
|
| 12 |
onsetsds/onsetsds.o: onsetsds/src/onsetsds.h |
|
| 12 |
onsetsdsplugin.o: onsetsdsplugin.h onsetsds/onsetsds.h |
|
| 13 |
onsetsds/onsetsds.o: onsetsds/onsetsds.h |
|
| Makefile.osx | ||
|---|---|---|
| 1 |
PLUGIN_LIBRARY_NAME = onsetsdsplugin |
|
| 2 |
VAMP_SDK_DIR = ../vamp-plugin-sdk |
|
| 3 |
|
|
| 4 |
PLUGIN_CODE_OBJECTS = onsetsdsplugin.o onsetsds/src/onsetsds.o |
|
| 5 |
|
|
| 6 |
ARCHFLAGS = -mmacosx-version-min=10.7 -arch x86_64 -stdlib=libc++ |
|
| 7 |
CFLAGS = $(ARCHFLAGS) -Wall -fPIC -g -O3 |
|
| 8 |
CXXFLAGS = $(CFLAGS) -I$(VAMP_SDK_DIR) -I. |
|
| 9 |
PLUGIN_EXT = .dylib |
|
| 10 |
PLUGIN = $(PLUGIN_LIBRARY_NAME)$(PLUGIN_EXT) |
|
| 11 |
LDFLAGS = $(ARCHFLAGS) -dynamiclib -install_name $(PLUGIN) $(VAMP_SDK_DIR)/libvamp-sdk.a -framework Accelerate |
|
| 12 |
|
|
| 13 |
|
|
| 14 |
$(PLUGIN): $(PLUGIN_CODE_OBJECTS) |
|
| 15 |
$(CXX) -o $@ $^ $(LDFLAGS) |
|
| 16 |
|
|
| 17 |
clean: |
|
| 18 |
rm -f *.o */src/*.o |
|
| 19 |
|
|
| 20 |
onsetsdsplugin.o: onsetsdsplugin.h onsetsds/src/onsetsds.h |
|
| 21 |
onsetsds/onsetsds.o: onsetsds/src/onsetsds.h |
|
| README | ||
|---|---|---|
| 1 |
This is a Vamp plugin of the OnsetsDS note onset detection library. |
|
| 2 |
See https://github.com/danstowell/onsetsds, http://vamp-plugins.org/, |
|
| 3 |
https://code.soundsoftware.ac.uk/projects/vamp-onsetsds-plugin |
|
| onsetsds/AUTHORS | ||
|---|---|---|
| 1 |
|
|
| 2 |
Dan Stowell, dan.stowell@elec.qmul.ac.uk |
|
| onsetsds/COPYING | ||
|---|---|---|
| 1 |
GNU GENERAL PUBLIC LICENSE |
|
| 2 |
Version 2, June 1991 |
|
| 3 |
|
|
| 4 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
|
| 5 |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 6 |
Everyone is permitted to copy and distribute verbatim copies |
|
| 7 |
of this license document, but changing it is not allowed. |
|
| 8 |
|
|
| 9 |
Preamble |
|
| 10 |
|
|
| 11 |
The licenses for most software are designed to take away your |
|
| 12 |
freedom to share and change it. By contrast, the GNU General Public |
|
| 13 |
License is intended to guarantee your freedom to share and change free |
|
| 14 |
software--to make sure the software is free for all its users. This |
|
| 15 |
General Public License applies to most of the Free Software |
|
| 16 |
Foundation's software and to any other program whose authors commit to |
|
| 17 |
using it. (Some other Free Software Foundation software is covered by |
|
| 18 |
the GNU Library General Public License instead.) You can apply it to |
|
| 19 |
your programs, too. |
|
| 20 |
|
|
| 21 |
When we speak of free software, we are referring to freedom, not |
|
| 22 |
price. Our General Public Licenses are designed to make sure that you |
|
| 23 |
have the freedom to distribute copies of free software (and charge for |
|
| 24 |
this service if you wish), that you receive source code or can get it |
|
| 25 |
if you want it, that you can change the software or use pieces of it |
|
| 26 |
in new free programs; and that you know you can do these things. |
|
| 27 |
|
|
| 28 |
To protect your rights, we need to make restrictions that forbid |
|
| 29 |
anyone to deny you these rights or to ask you to surrender the rights. |
|
| 30 |
These restrictions translate to certain responsibilities for you if you |
|
| 31 |
distribute copies of the software, or if you modify it. |
|
| 32 |
|
|
| 33 |
For example, if you distribute copies of such a program, whether |
|
| 34 |
gratis or for a fee, you must give the recipients all the rights that |
|
| 35 |
you have. You must make sure that they, too, receive or can get the |
|
| 36 |
source code. And you must show them these terms so they know their |
|
| 37 |
rights. |
|
| 38 |
|
|
| 39 |
We protect your rights with two steps: (1) copyright the software, and |
|
| 40 |
(2) offer you this license which gives you legal permission to copy, |
|
| 41 |
distribute and/or modify the software. |
|
| 42 |
|
|
| 43 |
Also, for each author's protection and ours, we want to make certain |
|
| 44 |
that everyone understands that there is no warranty for this free |
|
| 45 |
software. If the software is modified by someone else and passed on, we |
|
| 46 |
want its recipients to know that what they have is not the original, so |
|
| 47 |
that any problems introduced by others will not reflect on the original |
|
| 48 |
authors' reputations. |
|
| 49 |
|
|
| 50 |
Finally, any free program is threatened constantly by software |
|
| 51 |
patents. We wish to avoid the danger that redistributors of a free |
|
| 52 |
program will individually obtain patent licenses, in effect making the |
|
| 53 |
program proprietary. To prevent this, we have made it clear that any |
|
| 54 |
patent must be licensed for everyone's free use or not licensed at all. |
|
| 55 |
|
|
| 56 |
The precise terms and conditions for copying, distribution and |
|
| 57 |
modification follow. |
|
| 58 |
|
|
| 59 |
GNU GENERAL PUBLIC LICENSE |
|
| 60 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
| 61 |
|
|
| 62 |
0. This License applies to any program or other work which contains |
|
| 63 |
a notice placed by the copyright holder saying it may be distributed |
|
| 64 |
under the terms of this General Public License. The "Program", below, |
|
| 65 |
refers to any such program or work, and a "work based on the Program" |
|
| 66 |
means either the Program or any derivative work under copyright law: |
|
| 67 |
that is to say, a work containing the Program or a portion of it, |
|
| 68 |
either verbatim or with modifications and/or translated into another |
|
| 69 |
language. (Hereinafter, translation is included without limitation in |
|
| 70 |
the term "modification".) Each licensee is addressed as "you". |
|
| 71 |
|
|
| 72 |
Activities other than copying, distribution and modification are not |
|
| 73 |
covered by this License; they are outside its scope. The act of |
|
| 74 |
running the Program is not restricted, and the output from the Program |
|
| 75 |
is covered only if its contents constitute a work based on the |
|
| 76 |
Program (independent of having been made by running the Program). |
|
| 77 |
Whether that is true depends on what the Program does. |
|
| 78 |
|
|
| 79 |
1. You may copy and distribute verbatim copies of the Program's |
|
| 80 |
source code as you receive it, in any medium, provided that you |
|
| 81 |
conspicuously and appropriately publish on each copy an appropriate |
|
| 82 |
copyright notice and disclaimer of warranty; keep intact all the |
|
| 83 |
notices that refer to this License and to the absence of any warranty; |
|
| 84 |
and give any other recipients of the Program a copy of this License |
|
| 85 |
along with the Program. |
|
| 86 |
|
|
| 87 |
You may charge a fee for the physical act of transferring a copy, and |
|
| 88 |
you may at your option offer warranty protection in exchange for a fee. |
|
| 89 |
|
|
| 90 |
2. You may modify your copy or copies of the Program or any portion |
|
| 91 |
of it, thus forming a work based on the Program, and copy and |
|
| 92 |
distribute such modifications or work under the terms of Section 1 |
|
| 93 |
above, provided that you also meet all of these conditions: |
|
| 94 |
|
|
| 95 |
a) You must cause the modified files to carry prominent notices |
|
| 96 |
stating that you changed the files and the date of any change. |
|
| 97 |
|
|
| 98 |
b) You must cause any work that you distribute or publish, that in |
|
| 99 |
whole or in part contains or is derived from the Program or any |
|
| 100 |
part thereof, to be licensed as a whole at no charge to all third |
|
| 101 |
parties under the terms of this License. |
|
| 102 |
|
|
| 103 |
c) If the modified program normally reads commands interactively |
|
| 104 |
when run, you must cause it, when started running for such |
|
| 105 |
interactive use in the most ordinary way, to print or display an |
|
| 106 |
announcement including an appropriate copyright notice and a |
|
| 107 |
notice that there is no warranty (or else, saying that you provide |
|
| 108 |
a warranty) and that users may redistribute the program under |
|
| 109 |
these conditions, and telling the user how to view a copy of this |
|
| 110 |
License. (Exception: if the Program itself is interactive but |
|
| 111 |
does not normally print such an announcement, your work based on |
|
| 112 |
the Program is not required to print an announcement.) |
|
| 113 |
|
|
| 114 |
These requirements apply to the modified work as a whole. If |
|
| 115 |
identifiable sections of that work are not derived from the Program, |
|
| 116 |
and can be reasonably considered independent and separate works in |
|
| 117 |
themselves, then this License, and its terms, do not apply to those |
|
| 118 |
sections when you distribute them as separate works. But when you |
|
| 119 |
distribute the same sections as part of a whole which is a work based |
|
| 120 |
on the Program, the distribution of the whole must be on the terms of |
|
| 121 |
this License, whose permissions for other licensees extend to the |
|
| 122 |
entire whole, and thus to each and every part regardless of who wrote it. |
|
| 123 |
|
|
| 124 |
Thus, it is not the intent of this section to claim rights or contest |
|
| 125 |
your rights to work written entirely by you; rather, the intent is to |
|
| 126 |
exercise the right to control the distribution of derivative or |
|
| 127 |
collective works based on the Program. |
|
| 128 |
|
|
| 129 |
In addition, mere aggregation of another work not based on the Program |
|
| 130 |
with the Program (or with a work based on the Program) on a volume of |
|
| 131 |
a storage or distribution medium does not bring the other work under |
|
| 132 |
the scope of this License. |
|
| 133 |
|
|
| 134 |
3. You may copy and distribute the Program (or a work based on it, |
|
| 135 |
under Section 2) in object code or executable form under the terms of |
|
| 136 |
Sections 1 and 2 above provided that you also do one of the following: |
|
| 137 |
|
|
| 138 |
a) Accompany it with the complete corresponding machine-readable |
|
| 139 |
source code, which must be distributed under the terms of Sections |
|
| 140 |
1 and 2 above on a medium customarily used for software interchange; or, |
|
| 141 |
|
|
| 142 |
b) Accompany it with a written offer, valid for at least three |
|
| 143 |
years, to give any third party, for a charge no more than your |
|
| 144 |
cost of physically performing source distribution, a complete |
|
| 145 |
machine-readable copy of the corresponding source code, to be |
|
| 146 |
distributed under the terms of Sections 1 and 2 above on a medium |
|
| 147 |
customarily used for software interchange; or, |
|
| 148 |
|
|
| 149 |
c) Accompany it with the information you received as to the offer |
|
| 150 |
to distribute corresponding source code. (This alternative is |
|
| 151 |
allowed only for noncommercial distribution and only if you |
|
| 152 |
received the program in object code or executable form with such |
|
| 153 |
an offer, in accord with Subsection b above.) |
|
| 154 |
|
|
| 155 |
The source code for a work means the preferred form of the work for |
|
| 156 |
making modifications to it. For an executable work, complete source |
|
| 157 |
code means all the source code for all modules it contains, plus any |
|
| 158 |
associated interface definition files, plus the scripts used to |
|
| 159 |
control compilation and installation of the executable. However, as a |
|
| 160 |
special exception, the source code distributed need not include |
|
| 161 |
anything that is normally distributed (in either source or binary |
|
| 162 |
form) with the major components (compiler, kernel, and so on) of the |
|
| 163 |
operating system on which the executable runs, unless that component |
|
| 164 |
itself accompanies the executable. |
|
| 165 |
|
|
| 166 |
If distribution of executable or object code is made by offering |
|
| 167 |
access to copy from a designated place, then offering equivalent |
|
| 168 |
access to copy the source code from the same place counts as |
|
| 169 |
distribution of the source code, even though third parties are not |
|
| 170 |
compelled to copy the source along with the object code. |
|
| 171 |
|
|
| 172 |
4. You may not copy, modify, sublicense, or distribute the Program |
|
| 173 |
except as expressly provided under this License. Any attempt |
|
| 174 |
otherwise to copy, modify, sublicense or distribute the Program is |
|
| 175 |
void, and will automatically terminate your rights under this License. |
|
| 176 |
However, parties who have received copies, or rights, from you under |
|
| 177 |
this License will not have their licenses terminated so long as such |
|
| 178 |
parties remain in full compliance. |
|
| 179 |
|
|
| 180 |
5. You are not required to accept this License, since you have not |
|
| 181 |
signed it. However, nothing else grants you permission to modify or |
|
| 182 |
distribute the Program or its derivative works. These actions are |
|
| 183 |
prohibited by law if you do not accept this License. Therefore, by |
|
| 184 |
modifying or distributing the Program (or any work based on the |
|
| 185 |
Program), you indicate your acceptance of this License to do so, and |
|
| 186 |
all its terms and conditions for copying, distributing or modifying |
|
| 187 |
the Program or works based on it. |
|
| 188 |
|
|
| 189 |
6. Each time you redistribute the Program (or any work based on the |
|
| 190 |
Program), the recipient automatically receives a license from the |
|
| 191 |
original licensor to copy, distribute or modify the Program subject to |
|
| 192 |
these terms and conditions. You may not impose any further |
|
| 193 |
restrictions on the recipients' exercise of the rights granted herein. |
|
| 194 |
You are not responsible for enforcing compliance by third parties to |
|
| 195 |
this License. |
|
| 196 |
|
|
| 197 |
7. If, as a consequence of a court judgment or allegation of patent |
|
| 198 |
infringement or for any other reason (not limited to patent issues), |
|
| 199 |
conditions are imposed on you (whether by court order, agreement or |
|
| 200 |
otherwise) that contradict the conditions of this License, they do not |
|
| 201 |
excuse you from the conditions of this License. If you cannot |
|
| 202 |
distribute so as to satisfy simultaneously your obligations under this |
|
| 203 |
License and any other pertinent obligations, then as a consequence you |
|
| 204 |
may not distribute the Program at all. For example, if a patent |
|
| 205 |
license would not permit royalty-free redistribution of the Program by |
|
| 206 |
all those who receive copies directly or indirectly through you, then |
|
| 207 |
the only way you could satisfy both it and this License would be to |
|
| 208 |
refrain entirely from distribution of the Program. |
|
| 209 |
|
|
| 210 |
If any portion of this section is held invalid or unenforceable under |
|
| 211 |
any particular circumstance, the balance of the section is intended to |
|
| 212 |
apply and the section as a whole is intended to apply in other |
|
| 213 |
circumstances. |
|
| 214 |
|
|
| 215 |
It is not the purpose of this section to induce you to infringe any |
|
| 216 |
patents or other property right claims or to contest validity of any |
|
| 217 |
such claims; this section has the sole purpose of protecting the |
|
| 218 |
integrity of the free software distribution system, which is |
|
| 219 |
implemented by public license practices. Many people have made |
|
| 220 |
generous contributions to the wide range of software distributed |
|
| 221 |
through that system in reliance on consistent application of that |
|
| 222 |
system; it is up to the author/donor to decide if he or she is willing |
|
| 223 |
to distribute software through any other system and a licensee cannot |
|
| 224 |
impose that choice. |
|
| 225 |
|
|
| 226 |
This section is intended to make thoroughly clear what is believed to |
|
| 227 |
be a consequence of the rest of this License. |
|
| 228 |
|
|
| 229 |
8. If the distribution and/or use of the Program is restricted in |
|
| 230 |
certain countries either by patents or by copyrighted interfaces, the |
|
| 231 |
original copyright holder who places the Program under this License |
|
| 232 |
may add an explicit geographical distribution limitation excluding |
|
| 233 |
those countries, so that distribution is permitted only in or among |
|
| 234 |
countries not thus excluded. In such case, this License incorporates |
|
| 235 |
the limitation as if written in the body of this License. |
|
| 236 |
|
|
| 237 |
9. The Free Software Foundation may publish revised and/or new versions |
|
| 238 |
of the General Public License from time to time. Such new versions will |
|
| 239 |
be similar in spirit to the present version, but may differ in detail to |
|
| 240 |
address new problems or concerns. |
|
| 241 |
|
|
| 242 |
Each version is given a distinguishing version number. If the Program |
|
| 243 |
specifies a version number of this License which applies to it and "any |
|
| 244 |
later version", you have the option of following the terms and conditions |
|
| 245 |
either of that version or of any later version published by the Free |
|
| 246 |
Software Foundation. If the Program does not specify a version number of |
|
| 247 |
this License, you may choose any version ever published by the Free Software |
|
| 248 |
Foundation. |
|
| 249 |
|
|
| 250 |
10. If you wish to incorporate parts of the Program into other free |
|
| 251 |
programs whose distribution conditions are different, write to the author |
|
| 252 |
to ask for permission. For software which is copyrighted by the Free |
|
| 253 |
Software Foundation, write to the Free Software Foundation; we sometimes |
|
| 254 |
make exceptions for this. Our decision will be guided by the two goals |
|
| 255 |
of preserving the free status of all derivatives of our free software and |
|
| 256 |
of promoting the sharing and reuse of software generally. |
|
| 257 |
|
|
| 258 |
NO WARRANTY |
|
| 259 |
|
|
| 260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
|
| 261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
|
| 262 |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
|
| 263 |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
|
| 264 |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
| 265 |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
|
| 266 |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
|
| 267 |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
|
| 268 |
REPAIR OR CORRECTION. |
|
| 269 |
|
|
| 270 |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
|
| 271 |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
|
| 272 |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
|
| 273 |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
|
| 274 |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
|
| 275 |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
|
| 276 |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
|
| 277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
|
| 278 |
POSSIBILITY OF SUCH DAMAGES. |
|
| 279 |
|
|
| 280 |
END OF TERMS AND CONDITIONS |
|
| 281 |
|
|
| 282 |
How to Apply These Terms to Your New Programs |
|
| 283 |
|
|
| 284 |
If you develop a new program, and you want it to be of the greatest |
|
| 285 |
possible use to the public, the best way to achieve this is to make it |
|
| 286 |
free software which everyone can redistribute and change under these terms. |
|
| 287 |
|
|
| 288 |
To do so, attach the following notices to the program. It is safest |
|
| 289 |
to attach them to the start of each source file to most effectively |
|
| 290 |
convey the exclusion of warranty; and each file should have at least |
|
| 291 |
the "copyright" line and a pointer to where the full notice is found. |
|
| 292 |
|
|
| 293 |
<one line to give the program's name and a brief idea of what it does.> |
|
| 294 |
Copyright (C) <year> <name of author> |
|
| 295 |
|
|
| 296 |
This program is free software; you can redistribute it and/or modify |
|
| 297 |
it under the terms of the GNU General Public License as published by |
|
| 298 |
the Free Software Foundation; either version 2 of the License, or |
|
| 299 |
(at your option) any later version. |
|
| 300 |
|
|
| 301 |
This program is distributed in the hope that it will be useful, |
|
| 302 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 303 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 304 |
GNU General Public License for more details. |
|
| 305 |
|
|
| 306 |
You should have received a copy of the GNU General Public License |
|
| 307 |
along with this program; if not, write to the Free Software |
|
| 308 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 309 |
|
|
| 310 |
|
|
| 311 |
Also add information on how to contact you by electronic and paper mail. |
|
| 312 |
|
|
| 313 |
If the program is interactive, make it output a short notice like this |
|
| 314 |
when it starts in an interactive mode: |
|
| 315 |
|
|
| 316 |
Gnomovision version 69, Copyright (C) year name of author |
|
| 317 |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
|
| 318 |
This is free software, and you are welcome to redistribute it |
|
| 319 |
under certain conditions; type `show c' for details. |
|
| 320 |
|
|
| 321 |
The hypothetical commands `show w' and `show c' should show the appropriate |
|
| 322 |
parts of the General Public License. Of course, the commands you use may |
|
| 323 |
be called something other than `show w' and `show c'; they could even be |
|
| 324 |
mouse-clicks or menu items--whatever suits your program. |
|
| 325 |
|
|
| 326 |
You should also get your employer (if you work as a programmer) or your |
|
| 327 |
school, if any, to sign a "copyright disclaimer" for the program, if |
|
| 328 |
necessary. Here is a sample; alter the names: |
|
| 329 |
|
|
| 330 |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
|
| 331 |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
| 332 |
|
|
| 333 |
<signature of Ty Coon>, 1 April 1989 |
|
| 334 |
Ty Coon, President of Vice |
|
| 335 |
|
|
| 336 |
This General Public License does not permit incorporating your program into |
|
| 337 |
proprietary programs. If your program is a subroutine library, you may |
|
| 338 |
consider it more useful to permit linking proprietary applications with the |
|
| 339 |
library. If this is what you want to do, use the GNU Library General |
|
| 340 |
Public License instead of this License. |
|
| onsetsds/ChangeLog | ||
|---|---|---|
| 1 |
2007-11 Dan Stowell |
|
| 2 |
* Significant refactoring from v0.1, which was a set of SuperCollider UGens. |
|
| 3 |
* VERSION: 0.2.0 |
|
| onsetsds/README | ||
|---|---|---|
| 1 |
|
|
| 2 |
---------------------------------------------------------- |
|
| 3 |
OnsetsDS |
|
| 4 |
|
|
| 5 |
Musical onset detection library |
|
| 6 |
(c) 2007 Dan Stowell |
|
| 7 |
Made available under the GPL v2 - see COPYING for details. |
|
| 8 |
---------------------------------------------------------- |
|
| 9 |
|
|
| 10 |
|
|
| 11 |
|
|
| 12 |
USAGE |
|
| 13 |
|
|
| 14 |
If your system can provide frequency-domain data (e.g. by performing FFT on the |
|
| 15 |
input audio), then to perform onset detection you only need onsetsds.h and |
|
| 16 |
onsetsds.c. These need no additional libraries beyond the standard C libraries. |
|
| 17 |
|
|
| 18 |
If you aren't already doing the FFT then you can also use onsetsdshelpers.c |
|
| 19 |
and onsetsdshelpers.h, which can process raw audio, from a buffer or from a |
|
| 20 |
file. These require two additional libraries: |
|
| 21 |
|
|
| 22 |
* libsndfile - I used version 1.0.17 |
|
| 23 |
http://www.meganerd.com/libsndfile |
|
| 24 |
|
|
| 25 |
* FFTW 3 (floating-point version) - I used version 3.1.2 |
|
| 26 |
http://www.fftw.org |
|
| 27 |
|
|
| 28 |
See the HTML documentation for a worked example. |
|
| 29 |
|
|
| onsetsds/doc/Doxyfile | ||
|---|---|---|
| 1 |
# Doxyfile 1.5.3 |
|
| 2 |
|
|
| 3 |
#--------------------------------------------------------------------------- |
|
| 4 |
# Project related configuration options |
|
| 5 |
#--------------------------------------------------------------------------- |
|
| 6 |
DOXYFILE_ENCODING = UTF-8 |
|
| 7 |
PROJECT_NAME = OnsetsDS |
|
| 8 |
PROJECT_NUMBER = v0.2 |
|
| 9 |
OUTPUT_DIRECTORY = . |
|
| 10 |
CREATE_SUBDIRS = NO |
|
| 11 |
OUTPUT_LANGUAGE = English |
|
| 12 |
BRIEF_MEMBER_DESC = YES |
|
| 13 |
REPEAT_BRIEF = YES |
|
| 14 |
ABBREVIATE_BRIEF = "The $name class " \ |
|
| 15 |
"The $name widget " \ |
|
| 16 |
"The $name file " \ |
|
| 17 |
is \ |
|
| 18 |
provides \ |
|
| 19 |
specifies \ |
|
| 20 |
contains \ |
|
| 21 |
represents \ |
|
| 22 |
a \ |
|
| 23 |
an \ |
|
| 24 |
the |
|
| 25 |
ALWAYS_DETAILED_SEC = NO |
|
| 26 |
INLINE_INHERITED_MEMB = NO |
|
| 27 |
FULL_PATH_NAMES = NO |
|
| 28 |
STRIP_FROM_PATH = /Applications/ |
|
| 29 |
STRIP_FROM_INC_PATH = |
|
| 30 |
SHORT_NAMES = NO |
|
| 31 |
JAVADOC_AUTOBRIEF = NO |
|
| 32 |
QT_AUTOBRIEF = NO |
|
| 33 |
MULTILINE_CPP_IS_BRIEF = NO |
|
| 34 |
DETAILS_AT_TOP = NO |
|
| 35 |
INHERIT_DOCS = YES |
|
| 36 |
SEPARATE_MEMBER_PAGES = NO |
|
| 37 |
TAB_SIZE = 8 |
|
| 38 |
ALIASES = |
|
| 39 |
OPTIMIZE_OUTPUT_FOR_C = YES |
|
| 40 |
OPTIMIZE_OUTPUT_JAVA = NO |
|
| 41 |
BUILTIN_STL_SUPPORT = NO |
|
| 42 |
CPP_CLI_SUPPORT = NO |
|
| 43 |
DISTRIBUTE_GROUP_DOC = NO |
|
| 44 |
SUBGROUPING = YES |
|
| 45 |
#--------------------------------------------------------------------------- |
|
| 46 |
# Build related configuration options |
|
| 47 |
#--------------------------------------------------------------------------- |
|
| 48 |
EXTRACT_ALL = YES |
|
| 49 |
EXTRACT_PRIVATE = YES |
|
| 50 |
EXTRACT_STATIC = YES |
|
| 51 |
EXTRACT_LOCAL_CLASSES = YES |
|
| 52 |
EXTRACT_LOCAL_METHODS = NO |
|
| 53 |
EXTRACT_ANON_NSPACES = NO |
|
| 54 |
HIDE_UNDOC_MEMBERS = NO |
|
| 55 |
HIDE_UNDOC_CLASSES = NO |
|
| 56 |
HIDE_FRIEND_COMPOUNDS = NO |
|
| 57 |
HIDE_IN_BODY_DOCS = NO |
|
| 58 |
INTERNAL_DOCS = NO |
|
| 59 |
CASE_SENSE_NAMES = NO |
|
| 60 |
HIDE_SCOPE_NAMES = NO |
|
| 61 |
SHOW_INCLUDE_FILES = YES |
|
| 62 |
INLINE_INFO = YES |
|
| 63 |
SORT_MEMBER_DOCS = NO |
|
| 64 |
SORT_BRIEF_DOCS = NO |
|
| 65 |
SORT_BY_SCOPE_NAME = NO |
|
| 66 |
GENERATE_TODOLIST = NO |
|
| 67 |
GENERATE_TESTLIST = NO |
|
| 68 |
GENERATE_BUGLIST = NO |
|
| 69 |
GENERATE_DEPRECATEDLIST= NO |
|
| 70 |
ENABLED_SECTIONS = |
|
| 71 |
MAX_INITIALIZER_LINES = 30 |
|
| 72 |
SHOW_USED_FILES = YES |
|
| 73 |
SHOW_DIRECTORIES = NO |
|
| 74 |
FILE_VERSION_FILTER = |
|
| 75 |
#--------------------------------------------------------------------------- |
|
| 76 |
# configuration options related to warning and progress messages |
|
| 77 |
#--------------------------------------------------------------------------- |
|
| 78 |
QUIET = NO |
|
| 79 |
WARNINGS = YES |
|
| 80 |
WARN_IF_UNDOCUMENTED = YES |
|
| 81 |
WARN_IF_DOC_ERROR = YES |
|
| 82 |
WARN_NO_PARAMDOC = NO |
|
| 83 |
WARN_FORMAT = "$file:$line: $text " |
|
| 84 |
WARN_LOGFILE = |
|
| 85 |
#--------------------------------------------------------------------------- |
|
| 86 |
# configuration options related to the input files |
|
| 87 |
#--------------------------------------------------------------------------- |
|
| 88 |
INPUT = .. |
|
| 89 |
INPUT_ENCODING = UTF-8 |
|
| 90 |
FILE_PATTERNS = *.c \ |
|
| 91 |
*.cc \ |
|
| 92 |
*.cxx \ |
|
| 93 |
*.cpp \ |
|
| 94 |
*.c++ \ |
|
| 95 |
*.d \ |
|
| 96 |
*.java \ |
|
| 97 |
*.ii \ |
|
| 98 |
*.ixx \ |
|
| 99 |
*.ipp \ |
|
| 100 |
*.i++ \ |
|
| 101 |
*.inl \ |
|
| 102 |
*.h \ |
|
| 103 |
*.hh \ |
|
| 104 |
*.hxx \ |
|
| 105 |
*.hpp \ |
|
| 106 |
*.h++ \ |
|
| 107 |
*.idl \ |
|
| 108 |
*.odl \ |
|
| 109 |
*.cs \ |
|
| 110 |
*.php \ |
|
| 111 |
*.php3 \ |
|
| 112 |
*.inc \ |
|
| 113 |
*.m \ |
|
| 114 |
*.mm \ |
|
| 115 |
*.dox \ |
|
| 116 |
*.py |
|
| 117 |
RECURSIVE = YES |
|
| 118 |
EXCLUDE = |
|
| 119 |
EXCLUDE_SYMLINKS = NO |
|
| 120 |
EXCLUDE_PATTERNS = */.svn* */doc/html* |
|
| 121 |
EXCLUDE_SYMBOLS = |
|
| 122 |
EXAMPLE_PATH = |
|
| 123 |
EXAMPLE_PATTERNS = * |
|
| 124 |
EXAMPLE_RECURSIVE = NO |
|
| 125 |
IMAGE_PATH = |
|
| 126 |
INPUT_FILTER = |
|
| 127 |
FILTER_PATTERNS = |
|
| 128 |
FILTER_SOURCE_FILES = NO |
|
| 129 |
#--------------------------------------------------------------------------- |
|
| 130 |
# configuration options related to source browsing |
|
| 131 |
#--------------------------------------------------------------------------- |
|
| 132 |
SOURCE_BROWSER = NO |
|
| 133 |
INLINE_SOURCES = NO |
|
| 134 |
STRIP_CODE_COMMENTS = YES |
|
| 135 |
REFERENCED_BY_RELATION = NO |
|
| 136 |
REFERENCES_RELATION = NO |
|
| 137 |
REFERENCES_LINK_SOURCE = YES |
|
| 138 |
USE_HTAGS = NO |
|
| 139 |
VERBATIM_HEADERS = NO |
|
| 140 |
#--------------------------------------------------------------------------- |
|
| 141 |
# configuration options related to the alphabetical class index |
|
| 142 |
#--------------------------------------------------------------------------- |
|
| 143 |
ALPHABETICAL_INDEX = NO |
|
| 144 |
COLS_IN_ALPHA_INDEX = 5 |
|
| 145 |
IGNORE_PREFIX = |
|
| 146 |
#--------------------------------------------------------------------------- |
|
| 147 |
# configuration options related to the HTML output |
|
| 148 |
#--------------------------------------------------------------------------- |
|
| 149 |
GENERATE_HTML = YES |
|
| 150 |
HTML_OUTPUT = html |
|
| 151 |
HTML_FILE_EXTENSION = .html |
|
| 152 |
HTML_HEADER = |
|
| 153 |
HTML_FOOTER = footer.html |
|
| 154 |
HTML_STYLESHEET = |
|
| 155 |
HTML_ALIGN_MEMBERS = YES |
|
| 156 |
GENERATE_HTMLHELP = NO |
|
| 157 |
HTML_DYNAMIC_SECTIONS = NO |
|
| 158 |
CHM_FILE = |
|
| 159 |
HHC_LOCATION = |
|
| 160 |
GENERATE_CHI = NO |
|
| 161 |
BINARY_TOC = NO |
|
| 162 |
TOC_EXPAND = NO |
|
| 163 |
DISABLE_INDEX = NO |
|
| 164 |
ENUM_VALUES_PER_LINE = 4 |
|
| 165 |
GENERATE_TREEVIEW = NO |
|
| 166 |
TREEVIEW_WIDTH = 250 |
|
| 167 |
#--------------------------------------------------------------------------- |
|
| 168 |
# configuration options related to the LaTeX output |
|
| 169 |
#--------------------------------------------------------------------------- |
|
| 170 |
GENERATE_LATEX = NO |
|
| 171 |
LATEX_OUTPUT = latex |
|
| 172 |
LATEX_CMD_NAME = latex |
|
| 173 |
MAKEINDEX_CMD_NAME = makeindex |
|
| 174 |
COMPACT_LATEX = NO |
|
| 175 |
PAPER_TYPE = a4wide |
|
| 176 |
EXTRA_PACKAGES = |
|
| 177 |
LATEX_HEADER = |
|
| 178 |
PDF_HYPERLINKS = NO |
|
| 179 |
USE_PDFLATEX = NO |
|
| 180 |
LATEX_BATCHMODE = NO |
|
| 181 |
LATEX_HIDE_INDICES = NO |
|
| 182 |
#--------------------------------------------------------------------------- |
|
| 183 |
# configuration options related to the RTF output |
|
| 184 |
#--------------------------------------------------------------------------- |
|
| 185 |
GENERATE_RTF = NO |
|
| 186 |
RTF_OUTPUT = rtf |
|
| 187 |
COMPACT_RTF = NO |
|
| 188 |
RTF_HYPERLINKS = NO |
|
| 189 |
RTF_STYLESHEET_FILE = |
|
| 190 |
RTF_EXTENSIONS_FILE = |
|
| 191 |
#--------------------------------------------------------------------------- |
|
| 192 |
# configuration options related to the man page output |
|
| 193 |
#--------------------------------------------------------------------------- |
|
| 194 |
GENERATE_MAN = NO |
|
| 195 |
MAN_OUTPUT = man |
|
| 196 |
MAN_EXTENSION = .3 |
|
| 197 |
MAN_LINKS = NO |
|
| 198 |
#--------------------------------------------------------------------------- |
|
| 199 |
# configuration options related to the XML output |
|
| 200 |
#--------------------------------------------------------------------------- |
|
| 201 |
GENERATE_XML = NO |
|
| 202 |
XML_OUTPUT = xml |
|
| 203 |
XML_SCHEMA = |
|
| 204 |
XML_DTD = |
|
| 205 |
XML_PROGRAMLISTING = YES |
|
| 206 |
#--------------------------------------------------------------------------- |
|
| 207 |
# configuration options for the AutoGen Definitions output |
|
| 208 |
#--------------------------------------------------------------------------- |
|
| 209 |
GENERATE_AUTOGEN_DEF = NO |
|
| 210 |
#--------------------------------------------------------------------------- |
|
| 211 |
# configuration options related to the Perl module output |
|
| 212 |
#--------------------------------------------------------------------------- |
|
| 213 |
GENERATE_PERLMOD = NO |
|
| 214 |
PERLMOD_LATEX = NO |
|
| 215 |
PERLMOD_PRETTY = YES |
|
| 216 |
PERLMOD_MAKEVAR_PREFIX = |
|
| 217 |
#--------------------------------------------------------------------------- |
|
| 218 |
# Configuration options related to the preprocessor |
|
| 219 |
#--------------------------------------------------------------------------- |
|
| 220 |
ENABLE_PREPROCESSING = YES |
|
| 221 |
MACRO_EXPANSION = NO |
|
| 222 |
EXPAND_ONLY_PREDEF = NO |
|
| 223 |
SEARCH_INCLUDES = YES |
|
| 224 |
INCLUDE_PATH = |
|
| 225 |
INCLUDE_FILE_PATTERNS = |
|
| 226 |
PREDEFINED = |
|
| 227 |
EXPAND_AS_DEFINED = |
|
| 228 |
SKIP_FUNCTION_MACROS = YES |
|
| 229 |
#--------------------------------------------------------------------------- |
|
| 230 |
# Configuration::additions related to external references |
|
| 231 |
#--------------------------------------------------------------------------- |
|
| 232 |
TAGFILES = |
|
| 233 |
GENERATE_TAGFILE = |
|
| 234 |
ALLEXTERNALS = NO |
|
| 235 |
EXTERNAL_GROUPS = YES |
|
| 236 |
PERL_PATH = /usr/bin/perl |
|
| 237 |
#--------------------------------------------------------------------------- |
|
| 238 |
# Configuration options related to the dot tool |
|
| 239 |
#--------------------------------------------------------------------------- |
|
| 240 |
CLASS_DIAGRAMS = NO |
|
| 241 |
MSCGEN_PATH = /Applications/Doxygen.app/Contents/Resources/ |
|
| 242 |
HIDE_UNDOC_RELATIONS = YES |
|
| 243 |
HAVE_DOT = YES |
|
| 244 |
CLASS_GRAPH = YES |
|
| 245 |
COLLABORATION_GRAPH = YES |
|
| 246 |
GROUP_GRAPHS = YES |
|
| 247 |
UML_LOOK = NO |
|
| 248 |
TEMPLATE_RELATIONS = NO |
|
| 249 |
INCLUDE_GRAPH = NO |
|
| 250 |
INCLUDED_BY_GRAPH = NO |
|
| 251 |
CALL_GRAPH = NO |
|
| 252 |
CALLER_GRAPH = NO |
|
| 253 |
GRAPHICAL_HIERARCHY = YES |
|
| 254 |
DIRECTORY_GRAPH = YES |
|
| 255 |
DOT_IMAGE_FORMAT = png |
|
| 256 |
DOT_PATH = /Applications/Doxygen.app/Contents/Resources/ |
|
| 257 |
DOTFILE_DIRS = |
|
| 258 |
DOT_GRAPH_MAX_NODES = 50 |
|
| 259 |
MAX_DOT_GRAPH_DEPTH = 1000 |
|
| 260 |
DOT_TRANSPARENT = NO |
|
| 261 |
DOT_MULTI_TARGETS = NO |
|
| 262 |
GENERATE_LEGEND = YES |
|
| 263 |
DOT_CLEANUP = YES |
|
| 264 |
#--------------------------------------------------------------------------- |
|
| 265 |
# Configuration::additions related to the search engine |
|
| 266 |
#--------------------------------------------------------------------------- |
|
| 267 |
SEARCHENGINE = NO |
|
| onsetsds/doc/footer.html | ||
|---|---|---|
| 1 |
</body></html> |
|
| onsetsds/doc/mainpage.dox | ||
|---|---|---|
| 1 |
/** \mainpage OnsetsDS - real time musical onset detection C/C++ library |
|
| 2 |
|
|
| 3 |
<small>Copyright (c) 2007 Dan Stowell (Published under the GNU Public License v2). |
|
| 4 |
http://onsetsds.sourceforge.net/</small> |
|
| 5 |
|
|
| 6 |
<h2>Introduction</h2> |
|
| 7 |
|
|
| 8 |
The purpose of %OnsetsDS is to provide capabilities for FFT-based onset |
|
| 9 |
detection that works very efficiently in real-time, and can detect onsets |
|
| 10 |
pretty well in a broad variety of musical signals, with a fast reaction |
|
| 11 |
time. |
|
| 12 |
|
|
| 13 |
It is not specialised for any particular type of signal. Nor is it |
|
| 14 |
particularly tailored towards non-real-time use (if we were working in |
|
| 15 |
non-real-time there are extra things we could do to improve the precision). |
|
| 16 |
Its efficiency and fast reaction are designed with general real-time musical |
|
| 17 |
applications in mind. |
|
| 18 |
|
|
| 19 |
<h2>Download</h2> |
|
| 20 |
|
|
| 21 |
<ul> |
|
| 22 |
<li><a href="http://sourceforge.net/">Download the sourcecode bundle</a></li> |
|
| 23 |
<li>Or access the current development version using subversion [<small><a href="http://sourceforge.net/svn/?group_id=54622" title="What is subversion, and how to use it">info</a></small>]: <br /> |
|
| 24 |
<tt>svn co %https://onsetsds.svn.sourceforge.net/svnroot/onsetsds onsetsds</tt></li> |
|
| 25 |
</ul> |
|
| 26 |
|
|
| 27 |
<h2>Typical usage</h2> |
|
| 28 |
|
|
| 29 |
\code |
|
| 30 |
|
|
| 31 |
// This example uses the recommended settings of an FFT size of 512 (@44.1kHz), |
|
| 32 |
// and a median span of 11. It also uses the "rectified complex deviation" |
|
| 33 |
// onset detection function - your choice of function may be down to taste, |
|
| 34 |
// or to performance on the particular type of sound you're using. |
|
| 35 |
|
|
| 36 |
#include "onsetsds.h" |
|
| 37 |
|
|
| 38 |
// An instance of the OnsetsDS struct, declared/allocated somewhere in your code, |
|
| 39 |
// however you want to do it. |
|
| 40 |
OnsetsDS ods; |
|
| 41 |
|
|
| 42 |
|
|
| 43 |
///////// (1) INITIALISATION: ///////// |
|
| 44 |
|
|
| 45 |
// Allocate contiguous memory using malloc or whatever is reasonable. |
|
| 46 |
float* odsdata = (float*) malloc( onsetsds_memneeded(odftype, 512, 11) ); |
|
| 47 |
|
|
| 48 |
// There are various types of onset detector available, we must choose one |
|
| 49 |
odftype = ODS_ODF_RCOMPLEX; |
|
| 50 |
|
|
| 51 |
// Now initialise the OnsetsDS struct and its associated memory |
|
| 52 |
onsetsds_init(ods, odsdata, ODS_FFT_FFTW3_HC, odftype, 512, 11); |
|
| 53 |
|
|
| 54 |
|
|
| 55 |
///////// (2) EXECUTION: ///////// |
|
| 56 |
|
|
| 57 |
bool onset; |
|
| 58 |
while(running){
|
|
| 59 |
// Grab your 512-point, 50%-overlap, nicely-windowed FFT data, into "fftdata" |
|
| 60 |
|
|
| 61 |
// Then detect. "onset" will be true when there's an onset, false otherwise |
|
| 62 |
onset = onsetsds_process(ods, fftdata); |
|
| 63 |
} |
|
| 64 |
|
|
| 65 |
|
|
| 66 |
///////// (3) TIDYING UP: ///////// |
|
| 67 |
|
|
| 68 |
free(ods->data); // Or free(odsdata), they point to the same thing in this case |
|
| 69 |
|
|
| 70 |
\endcode |
|
| 71 |
|
|
| 72 |
<h2>Research background</h2> |
|
| 73 |
|
|
| 74 |
%OnsetsDS is based on research into musical onset detection |
|
| 75 |
carried out by Dan Stowell, with Dr Mark Plumbley, at |
|
| 76 |
Queen Mary University of London's |
|
| 77 |
<a href="http://www.elec.qmul.ac.uk/digitalmusic/">Centre for Digital Music</a>. |
|
| 78 |
|
|
| 79 |
Relevant publications: |
|
| 80 |
|
|
| 81 |
\li D. Stowell and M. D. Plumbley. |
|
| 82 |
<a href="http://www.elec.qmul.ac.uk/digitalmusic/papers/2007/StowellPlumbley07-icmc.pdf"> |
|
| 83 |
Adaptive whitening for improved real-time audio onset detection.</a> |
|
| 84 |
To appear in: |
|
| 85 |
Proceedings of the International Computer Music Conference (ICMC'07), |
|
| 86 |
Copenhagen, Denmark, August 2007. |
|
| 87 |
|
|
| 88 |
The research stands on the shoulders of other onset detection research, and uses |
|
| 89 |
some concepts from that research - see the ICMC'07 paper and its bibliography |
|
| 90 |
for more details. |
|
| 91 |
|
|
| 92 |
|
|
| 93 |
*/ |
|
| onsetsds/onsetsds.c | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
OnsetsDS - real time musical onset detection library. |
|
| 3 |
Copyright (c) 2007 Dan Stowell. All rights reserved. |
|
| 4 |
|
|
| 5 |
This program is free software; you can redistribute it and/or modify |
|
| 6 |
it under the terms of the GNU General Public License as published by |
|
| 7 |
the Free Software Foundation; either version 2 of the License, or |
|
| 8 |
(at your option) any later version. |
|
| 9 |
|
|
| 10 |
This program is distributed in the hope that it will be useful, |
|
| 11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 13 |
GNU General Public License for more details. |
|
| 14 |
|
|
| 15 |
You should have received a copy of the GNU General Public License |
|
| 16 |
along with this program; if not, write to the Free Software |
|
| 17 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 18 |
*/ |
|
| 19 |
|
|
| 20 |
|
|
| 21 |
#include "onsetsds.h" |
|
| 22 |
|
|
| 23 |
|
|
| 24 |
#define ODS_DEBUG_POST_CSV 0 |
|
| 25 |
|
|
| 26 |
// Inline |
|
| 27 |
inline float onsetsds_phase_rewrap(float phase); |
|
| 28 |
inline float onsetsds_phase_rewrap(float phase){
|
|
| 29 |
return (phase>MINUSPI && phase<PI) ? phase : phase + TWOPI * (1.f + floorf((MINUSPI - phase) * INV_TWOPI)); |
|
| 30 |
} |
|
| 31 |
|
|
| 32 |
|
|
| 33 |
size_t onsetsds_memneeded (int odftype, size_t fftsize, unsigned int medspan){
|
|
| 34 |
|
|
| 35 |
/* |
|
| 36 |
Need memory for: |
|
| 37 |
- median calculation (2 * medspan floats) |
|
| 38 |
- storing old values (whether as OdsPolarBuf or as weirder float lists) |
|
| 39 |
- storing the OdsPolarBuf (size is NOT sizeof(OdsPolarBuf) but is fftsize) |
|
| 40 |
- storing the PSP (numbins + 2 values) |
|
| 41 |
All these are floats. |
|
| 42 |
*/ |
|
| 43 |
|
|
| 44 |
int numbins = (fftsize >> 1) - 1; // No of bins, not counting DC/nyq |
|
| 45 |
|
|
| 46 |
switch(odftype){
|
|
| 47 |
case ODS_ODF_POWER: |
|
| 48 |
case ODS_ODF_MAGSUM: |
|
| 49 |
|
|
| 50 |
// No old FFT frames needed, easy: |
|
| 51 |
return (medspan+medspan + fftsize + numbins + 2) * sizeof(float); |
|
| 52 |
|
|
| 53 |
case ODS_ODF_COMPLEX: |
|
| 54 |
case ODS_ODF_RCOMPLEX: |
|
| 55 |
|
|
| 56 |
return (medspan+medspan + fftsize + numbins + 2 |
|
| 57 |
// For each bin (NOT dc/nyq) we store mag, phase and d_phase |
|
| 58 |
+ numbins + numbins + numbins |
|
| 59 |
) * sizeof(float); |
|
| 60 |
|
|
| 61 |
case ODS_ODF_PHASE: |
|
| 62 |
case ODS_ODF_WPHASE: |
|
| 63 |
|
|
| 64 |
return (medspan+medspan + fftsize + numbins + 2 |
|
| 65 |
// For each bin (NOT dc/nyq) we store phase and d_phase |
|
| 66 |
+ numbins + numbins |
|
| 67 |
) * sizeof(float); |
|
| 68 |
|
|
| 69 |
case ODS_ODF_MKL: |
|
| 70 |
|
|
| 71 |
return (medspan+medspan + fftsize + numbins + 2 |
|
| 72 |
// For each bin (NOT dc/nyq) we store mag |
|
| 73 |
+ numbins |
|
| 74 |
) * sizeof(float); |
|
| 75 |
|
|
| 76 |
|
|
| 77 |
break; |
|
| 78 |
|
|
| 79 |
} |
|
| 80 |
return -1; //bleh |
|
| 81 |
} |
|
| 82 |
|
|
| 83 |
|
|
| 84 |
void onsetsds_init(OnsetsDS *ods, float *odsdata, int fftformat, |
|
| 85 |
int odftype, size_t fftsize, unsigned int medspan, float srate){
|
|
| 86 |
|
|
| 87 |
// The main pointer to the processing area - other pointers will indicate areas within this |
|
| 88 |
ods->data = odsdata; |
|
| 89 |
// Set all vals in processing area to zero |
|
| 90 |
memset(odsdata, 0, onsetsds_memneeded(odftype, fftsize, medspan)); |
|
| 91 |
|
|
| 92 |
ods->srate = srate; |
|
| 93 |
|
|
| 94 |
int numbins = (fftsize >> 1) - 1; // No of bins, not counting DC/nyq |
|
| 95 |
int realnumbins = numbins + 2; |
|
| 96 |
|
|
| 97 |
// Also point the other pointers to the right places |
|
| 98 |
ods->curr = (OdsPolarBuf*) odsdata; |
|
| 99 |
ods->psp = odsdata + fftsize; |
|
| 100 |
ods->odfvals = odsdata + fftsize + realnumbins; |
|
| 101 |
ods->sortbuf = odsdata + fftsize + realnumbins + medspan; |
|
| 102 |
ods->other = odsdata + fftsize + realnumbins + medspan + medspan; |
|
| 103 |
|
|
| 104 |
// Default settings for Adaptive Whitening, user can set own values after init |
|
| 105 |
onsetsds_setrelax(ods, 1.f, fftsize>>1); |
|
| 106 |
ods->floor = 0.1; |
|
| 107 |
|
|
| 108 |
switch(odftype){
|
|
| 109 |
case ODS_ODF_POWER: |
|
| 110 |
ods->odfparam = 0.01; // "powthresh" in SC code |
|
| 111 |
ods->normfactor = 2560.f / (realnumbins * fftsize); |
|
| 112 |
break; |
|
| 113 |
case ODS_ODF_MAGSUM: |
|
| 114 |
ods->odfparam = 0.01; // "powthresh" in SC code |
|
| 115 |
ods->normfactor = 113.137085f / (realnumbins * sqrt(fftsize)); |
|
| 116 |
break; |
|
| 117 |
case ODS_ODF_COMPLEX: |
|
| 118 |
ods->odfparam = 0.01; // "powthresh" in SC code |
|
| 119 |
ods->normfactor = 231.70475f / pow(fftsize, 1.5);// / fftsize; |
|
| 120 |
break; |
|
| 121 |
case ODS_ODF_RCOMPLEX: |
|
| 122 |
ods->odfparam = 0.01; // "powthresh" in SC code |
|
| 123 |
ods->normfactor = 231.70475f / pow(fftsize, 1.5);// / fftsize; |
|
| 124 |
break; |
|
| 125 |
case ODS_ODF_PHASE: |
|
| 126 |
ods->odfparam = 0.01; // "powthresh" in SC code |
|
| 127 |
ods->normfactor = 5.12f / fftsize;// / fftsize; |
|
| 128 |
break; |
|
| 129 |
case ODS_ODF_WPHASE: |
|
| 130 |
ods->odfparam = 0.0001; // "powthresh" in SC code. For WPHASE it's kind of superfluous. |
|
| 131 |
ods->normfactor = 115.852375f / pow(fftsize, 1.5);// / fftsize; |
|
| 132 |
break; |
|
| 133 |
case ODS_ODF_MKL: |
|
| 134 |
ods->odfparam = 0.01; // EPSILON parameter. Brossier recommends 1e-6 but I (ICMC 2007) found larger vals (e.g 0.01) to work better |
|
| 135 |
ods->normfactor = 7.68f * 0.25f / fftsize; |
|
| 136 |
break; |
|
| 137 |
default: |
|
| 138 |
printf("onsetsds_init ERROR: \"odftype\" is not a recognised value\n");
|
|
| 139 |
} |
|
| 140 |
|
|
| 141 |
ods->odfvalpost = 0.f; |
|
| 142 |
ods->odfvalpostprev = 0.f; |
|
| 143 |
ods->thresh = 0.5f; |
|
| 144 |
ods->logmags = false; |
|
| 145 |
|
|
| 146 |
ods->odftype = odftype; |
|
| 147 |
ods->whtype = ODS_WH_ADAPT_MAX1; |
|
| 148 |
ods->fftformat = fftformat; |
|
| 149 |
|
|
| 150 |
ods->whiten = (odftype != ODS_ODF_MKL); // Deactivate whitening for MKL by default |
|
| 151 |
ods->detected = false; |
|
| 152 |
ods->med_odd = (medspan & 1) != 0; |
|
| 153 |
|
|
| 154 |
ods->medspan = medspan; |
|
| 155 |
|
|
| 156 |
ods->mingap = 0; |
|
| 157 |
ods->gapleft = 0; |
|
| 158 |
|
|
| 159 |
ods->fftsize = fftsize; |
|
| 160 |
ods->numbins = numbins; |
|
| 161 |
|
|
| 162 |
//printf("End of _init: normfactor is %g\n", ods->normfactor);
|
|
| 163 |
|
|
| 164 |
} |
|
| 165 |
|
|
| 166 |
bool onsetsds_process(OnsetsDS* ods, float* fftbuf){
|
|
| 167 |
onsetsds_loadframe(ods, fftbuf); |
|
| 168 |
|
|
| 169 |
onsetsds_whiten(ods); |
|
| 170 |
onsetsds_odf(ods); |
|
| 171 |
onsetsds_detect(ods); |
|
| 172 |
|
|
| 173 |
return ods->detected; |
|
| 174 |
} |
|
| 175 |
|
|
| 176 |
|
|
| 177 |
void onsetsds_setrelax(OnsetsDS* ods, float time, size_t hopsize){
|
|
| 178 |
ods->relaxtime = time; |
|
| 179 |
ods->relaxcoef = (time == 0.0f) ? 0.0f : exp((ods_log1 * hopsize)/(time * ods->srate)); |
|
| 180 |
} |
|
| 181 |
|
|
| 182 |
|
|
| 183 |
|
|
| 184 |
void onsetsds_loadframe(OnsetsDS* ods, float* fftbuf){
|
|
| 185 |
|
|
| 186 |
float *pos, *pos2, imag, real; |
|
| 187 |
int i; |
|
| 188 |
|
|
| 189 |
switch(ods->fftformat){
|
|
| 190 |
case ODS_FFT_SC3_POLAR: |
|
| 191 |
// The format is the same! dc, nyq, mag[1], phase[1], ... |
|
| 192 |
memcpy(ods->curr, fftbuf, ods->fftsize * sizeof(float)); |
|
| 193 |
break; |
|
| 194 |
|
|
| 195 |
case ODS_FFT_SC3_COMPLEX: |
|
| 196 |
|
|
| 197 |
ods->curr->dc = fftbuf[0]; |
|
| 198 |
ods->curr->nyq = fftbuf[1]; |
|
| 199 |
|
|
| 200 |
// Then convert cartesian to polar: |
|
| 201 |
pos = fftbuf + 2; |
|
| 202 |
for(i=0; i< (ods->numbins << 1); i += 2){
|
|
| 203 |
real = pos[i]; |
|
| 204 |
imag = pos[i+1]; // Plus 1 rather than increment; seems to avoid LSU reject on my PPC |
|
| 205 |
ods->curr->bin[i].mag = hypotf(imag, real); |
|
| 206 |
ods->curr->bin[i].phase = atan2f(imag, real); |
|
| 207 |
} |
|
| 208 |
break; |
|
| 209 |
|
|
| 210 |
case ODS_FFT_FFTW3_HC: |
|
| 211 |
|
|
| 212 |
ods->curr->dc = fftbuf[0]; |
|
| 213 |
ods->curr->nyq = fftbuf[ods->fftsize>>1]; |
|
| 214 |
|
|
| 215 |
// Then convert cartesian to polar: |
|
| 216 |
// (Starting positions: real and imag for bin 1) |
|
| 217 |
pos = fftbuf + 1; |
|
| 218 |
pos2 = fftbuf + ods->fftsize - 1; |
|
| 219 |
for(i=0; i<ods->numbins; i++){
|
|
| 220 |
real = *(pos++); |
|
| 221 |
imag = *(pos2--); |
|
| 222 |
ods->curr->bin[i].mag = hypotf(imag, real); |
|
| 223 |
ods->curr->bin[i].phase = atan2f(imag, real); |
|
| 224 |
} |
|
| 225 |
break; |
|
| 226 |
|
|
| 227 |
case ODS_FFT_FFTW3_R2C: |
|
| 228 |
|
|
| 229 |
ods->curr->dc = fftbuf[0]; |
|
| 230 |
ods->curr->nyq = fftbuf[ods->fftsize]; |
|
| 231 |
|
|
| 232 |
// Then convert cartesian to polar: |
|
| 233 |
pos = fftbuf + 2; |
|
| 234 |
for(i=0; i<ods->numbins; i++){
|
|
| 235 |
real = *(pos++); |
|
| 236 |
imag = *(pos++); |
|
| 237 |
ods->curr->bin[i].mag = hypotf(imag, real); |
|
| 238 |
ods->curr->bin[i].phase = atan2f(imag, real); |
|
| 239 |
} |
|
| 240 |
break; |
|
| 241 |
|
|
| 242 |
} |
|
| 243 |
|
|
| 244 |
// Conversion to log-domain magnitudes, including re-scaling to aim back at the zero-to-one range. |
|
| 245 |
// Not well tested yet. |
|
| 246 |
if(ods->logmags){
|
|
| 247 |
for(i=0; i<ods->numbins; i++){
|
|
| 248 |
ods->curr->bin[i].mag = |
|
| 249 |
(log(ods_max(ods->curr->bin[i].mag, ODS_LOG_LOWER_LIMIT)) - ODS_LOGOF_LOG_LOWER_LIMIT) * ODS_ABSINVOF_LOGOF_LOG_LOWER_LIMIT; |
|
| 250 |
} |
|
| 251 |
ods->curr->dc = |
|
| 252 |
(log(ods_max(ods_abs(ods->curr->dc ), ODS_LOG_LOWER_LIMIT)) - ODS_LOGOF_LOG_LOWER_LIMIT) * ODS_ABSINVOF_LOGOF_LOG_LOWER_LIMIT; |
|
| 253 |
ods->curr->nyq = |
|
| 254 |
(log(ods_max(ods_abs(ods->curr->nyq), ODS_LOG_LOWER_LIMIT)) - ODS_LOGOF_LOG_LOWER_LIMIT) * ODS_ABSINVOF_LOGOF_LOG_LOWER_LIMIT; |
|
| 255 |
} |
|
| 256 |
|
|
| 257 |
} |
|
| 258 |
|
|
| 259 |
void onsetsds_whiten(OnsetsDS* ods){
|
|
| 260 |
|
|
| 261 |
if(ods->whtype == ODS_WH_NONE){
|
|
| 262 |
//printf("onsetsds_whiten(): ODS_WH_NONE, skipping\n");
|
|
| 263 |
return; |
|
| 264 |
} |
|
| 265 |
|
|
| 266 |
// NB: Apart from the above, ods->whtype is currently IGNORED and only one mode is used. |
|
| 267 |
|
|
| 268 |
|
|
| 269 |
float val,oldval, relaxcoef, floor; |
|
| 270 |
int numbins, i; |
|
| 271 |
OdsPolarBuf *curr; |
|
| 272 |
float *psp; |
|
| 273 |
float *pspp1; // Offset by 1, avoids quite a lot of "+1"s in the following code |
|
| 274 |
|
|
| 275 |
relaxcoef = ods->relaxcoef; |
|
| 276 |
numbins = ods->numbins; |
|
| 277 |
curr = ods->curr; |
|
| 278 |
psp = ods->psp; |
|
| 279 |
pspp1 = psp + 1; |
|
| 280 |
floor = ods->floor; |
|
| 281 |
|
|
| 282 |
//printf("onsetsds_whiten: relaxcoef=%g, relaxtime=%g, floor=%g\n", relaxcoef, ods->relaxtime, floor);
|
|
| 283 |
|
|
| 284 |
////////////////////// For each bin, update the record of the peak value ///////////////////// |
|
| 285 |
|
|
| 286 |
val = fabs(curr->dc); // Grab current magnitude |
|
| 287 |
oldval = psp[0]; |
|
| 288 |
// If it beats the amplitude stored then that's our new amplitude; |
|
| 289 |
// otherwise our new amplitude is a decayed version of the old one |
|
| 290 |
if(val < oldval) {
|
|
| 291 |
val = val + (oldval - val) * relaxcoef; |
|
| 292 |
} |
|
| 293 |
psp[0] = val; // Store the "amplitude trace" back |
|
| 294 |
|
|
| 295 |
val = fabs(curr->nyq); |
|
| 296 |
oldval = pspp1[numbins]; |
|
| 297 |
if(val < oldval) {
|
|
| 298 |
val = val + (oldval - val) * relaxcoef; |
|
| 299 |
} |
|
| 300 |
pspp1[numbins] = val; |
|
| 301 |
|
|
| 302 |
for(i=0; i<numbins; ++i){
|
|
| 303 |
val = fabs(curr->bin[i].mag); |
|
| 304 |
oldval = pspp1[i]; |
|
| 305 |
if(val < oldval) {
|
|
| 306 |
val = val + (oldval - val) * relaxcoef; |
|
| 307 |
} |
|
| 308 |
pspp1[i] = val; |
|
| 309 |
} |
|
| 310 |
|
|
| 311 |
//////////////////////////// Now for each bin, rescale the current magnitude //////////////////////////// |
|
| 312 |
curr->dc /= ods_max(floor, psp[0]); |
|
| 313 |
curr->nyq /= ods_max(floor, pspp1[numbins]); |
|
| 314 |
for(i=0; i<numbins; ++i){
|
|
| 315 |
curr->bin[i].mag /= ods_max(floor, pspp1[i]); |
|
| 316 |
} |
|
| 317 |
} |
|
| 318 |
|
|
| 319 |
void onsetsds_odf(OnsetsDS* ods){
|
|
| 320 |
|
|
| 321 |
int numbins = ods->numbins; |
|
| 322 |
OdsPolarBuf *curr = ods->curr; |
|
| 323 |
float* val = ods->odfvals; |
|
| 324 |
int i, tbpointer; |
|
| 325 |
float deviation, diff, curmag; |
|
| 326 |
double totdev; |
|
| 327 |
|
|
| 328 |
bool rectify = true; |
|
| 329 |
|
|
| 330 |
// Here we shunt the "old" ODF values down one place |
|
| 331 |
memcpy(val + 1, val, (ods->medspan - 1)*sizeof(float)); |
|
| 332 |
|
|
| 333 |
// Now calculate a new value and store in ods->odfvals[0] |
|
| 334 |
switch(ods->odftype){
|
|
| 335 |
case ODS_ODF_POWER: |
|
| 336 |
|
|
| 337 |
*val = (curr->nyq * curr->nyq) + (curr->dc * curr->dc); |
|
| 338 |
for(i=0; i<numbins; i++){
|
|
| 339 |
*val += curr->bin[i].mag * curr->bin[i].mag; |
|
| 340 |
} |
|
| 341 |
break; |
|
| 342 |
|
|
| 343 |
case ODS_ODF_MAGSUM: |
|
| 344 |
|
|
| 345 |
*val = ods_abs(curr->nyq) + ods_abs(curr->dc); |
|
| 346 |
|
|
| 347 |
for(i=0; i<numbins; i++){
|
|
| 348 |
*val += ods_abs(curr->bin[i].mag); |
|
| 349 |
} |
|
| 350 |
break; |
|
| 351 |
|
|
| 352 |
case ODS_ODF_COMPLEX: |
|
| 353 |
rectify = false; |
|
| 354 |
// ...and then drop through to: |
|
| 355 |
case ODS_ODF_RCOMPLEX: |
|
| 356 |
|
|
| 357 |
// Note: "other" buf is stored in this format: mag[0],phase[0],d_phase[0],mag[1],phase[1],d_phase[1], ... |
|
| 358 |
|
|
| 359 |
// Iterate through, calculating the deviation from expected value. |
|
| 360 |
totdev = 0.0; |
|
| 361 |
tbpointer = 0; |
|
| 362 |
float predmag, predphase, yesterphase, yesterphasediff; |
|
| 363 |
for (i=0; i<numbins; ++i) {
|
|
| 364 |
curmag = ods_abs(curr->bin[i].mag); |
|
| 365 |
|
|
| 366 |
// Predict mag as yestermag |
|
| 367 |
predmag = ods->other[tbpointer++]; |
|
| 368 |
yesterphase = ods->other[tbpointer++]; |
|
| 369 |
yesterphasediff = ods->other[tbpointer++]; |
|
| 370 |
|
|
| 371 |
// Thresholding as Brossier did - discard (ignore) bin's deviation if bin's power is minimal |
|
| 372 |
if(curmag > ods->odfparam) {
|
|
| 373 |
// If rectifying, ignore decreasing bins |
|
| 374 |
if((!rectify) || !(curmag < predmag)){
|
|
| 375 |
|
|
| 376 |
// Predict phase as yesterval + yesterfirstdiff |
|
| 377 |
predphase = yesterphase + yesterphasediff; |
|
| 378 |
|
|
| 379 |
// Here temporarily using the "deviation" var to store the phase difference |
|
| 380 |
// so that the rewrap macro can use it more efficiently |
|
| 381 |
deviation = predphase - curr->bin[i].phase; |
|
| 382 |
|
|
| 383 |
// Deviation is Euclidean distance between predicted and actual. |
|
| 384 |
// In polar coords: sqrt(r1^2 + r2^2 - r1r2 cos (theta1 - theta2)) |
|
| 385 |
deviation = sqrtf(predmag * predmag + curmag * curmag |
|
| 386 |
- predmag * curmag * cosf(onsetsds_phase_rewrap(deviation)) |
|
| 387 |
); |
|
| 388 |
|
|
| 389 |
totdev += deviation; |
|
| 390 |
} |
|
| 391 |
} |
|
| 392 |
} |
|
| 393 |
|
|
| 394 |
// totdev will be the output, but first we need to fill tempbuf with today's values, ready for tomorrow. |
|
| 395 |
tbpointer = 0; |
|
| 396 |
for (i=0; i<numbins; ++i) {
|
|
| 397 |
ods->other[tbpointer++] = ods_abs(curr->bin[i].mag); // Storing mag |
|
| 398 |
diff = curr->bin[i].phase - ods->other[tbpointer]; // Retrieving yesterphase from buf |
|
| 399 |
ods->other[tbpointer++] = curr->bin[i].phase; // Storing phase |
|
| 400 |
// Wrap onto +-PI range |
|
| 401 |
diff = onsetsds_phase_rewrap(diff); |
|
| 402 |
|
|
| 403 |
ods->other[tbpointer++] = diff; // Storing first diff to buf |
|
| 404 |
|
|
| 405 |
} |
|
| 406 |
*val = (float)totdev; |
|
| 407 |
|
|
| 408 |
break; |
|
| 409 |
|
|
| 410 |
|
|
| 411 |
case ODS_ODF_PHASE: |
|
| 412 |
rectify = false; // So, actually, "rectify" means "useweighting" in this context |
|
| 413 |
// ...and then drop through to: |
|
| 414 |
case ODS_ODF_WPHASE: |
|
| 415 |
|
|
| 416 |
// Note: "other" buf is stored in this format: phase[0],d_phase[0],phase[1],d_phase[1], ... |
|
| 417 |
|
|
| 418 |
// Iterate through, calculating the deviation from expected value. |
|
| 419 |
totdev = 0.0; |
|
| 420 |
tbpointer = 0; |
|
| 421 |
for (i=0; i<numbins; ++i) {
|
|
| 422 |
// Thresholding as Brossier did - discard (ignore) bin's phase deviation if bin's power is low |
|
| 423 |
if(ods_abs(curr->bin[i].mag) > ods->odfparam) {
|
|
| 424 |
|
|
| 425 |
// Deviation is the *second difference* of the phase, which is calc'ed as curval - yesterval - yesterfirstdiff |
|
| 426 |
deviation = curr->bin[i].phase - ods->other[tbpointer++] - ods->other[tbpointer++]; |
|
| 427 |
// Wrap onto +-PI range |
|
| 428 |
deviation = onsetsds_phase_rewrap(deviation); |
|
| 429 |
|
|
| 430 |
if(rectify){ // "rectify" meaning "useweighting"...
|
|
| 431 |
totdev += fabs(deviation * ods_abs(curr->bin[i].mag)); |
|
| 432 |
} else {
|
|
| 433 |
totdev += fabs(deviation); |
|
| 434 |
} |
|
| 435 |
} |
|
| 436 |
} |
|
| 437 |
|
|
| 438 |
// totdev will be the output, but first we need to fill tempbuf with today's values, ready for tomorrow. |
|
| 439 |
tbpointer = 0; |
|
| 440 |
for (i=0; i<numbins; ++i) {
|
|
| 441 |
diff = curr->bin[i].phase - ods->other[tbpointer]; // Retrieving yesterphase from buf |
|
| 442 |
ods->other[tbpointer++] = curr->bin[i].phase; // Storing phase |
|
| 443 |
// Wrap onto +-PI range |
|
| 444 |
diff = onsetsds_phase_rewrap(diff); |
|
| 445 |
|
|
| 446 |
ods->other[tbpointer++] = diff; // Storing first diff to buf |
|
| 447 |
|
|
| 448 |
} |
|
| 449 |
*val = (float)totdev; |
|
| 450 |
break; |
|
| 451 |
|
|
| 452 |
|
|
| 453 |
case ODS_ODF_MKL: |
|
| 454 |
|
|
| 455 |
// Iterate through, calculating the Modified Kullback-Liebler distance |
|
| 456 |
totdev = 0.0; |
|
| 457 |
tbpointer = 0; |
|
| 458 |
float yestermag; |
|
| 459 |
for (i=0; i<numbins; ++i) {
|
|
| 460 |
curmag = ods_abs(curr->bin[i].mag); |
|
| 461 |
yestermag = ods->other[tbpointer]; |
|
| 462 |
|
|
| 463 |
// Here's the main implementation of Brossier's MKL eq'n (eqn 2.9 from his thesis): |
|
| 464 |
deviation = ods_abs(curmag) / (ods_abs(yestermag) + ods->odfparam); |
|
| 465 |
totdev += log(1.f + deviation); |
|
| 466 |
|
|
| 467 |
// Store the mag as yestermag |
|
| 468 |
ods->other[tbpointer++] = curmag; |
|
| 469 |
} |
|
| 470 |
*val = (float)totdev; |
|
| 471 |
break; |
|
| 472 |
|
|
| 473 |
} |
|
| 474 |
|
|
| 475 |
#if ODS_DEBUG_POST_CSV |
|
| 476 |
printf("%g,", *val);
|
|
| 477 |
printf("%g,", ods->odfvals[0] * ods->normfactor);
|
|
| 478 |
#endif |
|
| 479 |
|
|
| 480 |
ods->odfvals[0] *= ods->normfactor; |
|
| 481 |
} |
|
| 482 |
// End of ODF function |
|
| 483 |
|
|
| 484 |
void SelectionSort(float *array, int length); |
|
| 485 |
void SelectionSort(float *array, int length) |
|
| 486 |
{
|
|
| 487 |
// Algo is simply based on http://en.wikibooks.org/wiki/Algorithm_implementation/Sorting/Selection_sort |
|
| 488 |
int max, i; |
|
| 489 |
float temp; |
|
| 490 |
while(length > 0) |
|
| 491 |
{
|
|
| 492 |
max = 0; |
|
| 493 |
for(i = 1; i < length; i++) |
|
| 494 |
if(array[i] > array[max]) |
|
| 495 |
max = i; |
|
| 496 |
temp = array[length-1]; |
|
| 497 |
array[length-1] = array[max]; |
|
| 498 |
array[max] = temp; |
|
| 499 |
length--; |
|
| 500 |
} |
|
| 501 |
} |
|
| 502 |
|
|
| 503 |
|
|
| 504 |
void onsetsds_detect(OnsetsDS* ods){
|
|
| 505 |
|
|
| 506 |
// Shift the yesterval to its rightful place |
|
| 507 |
ods->odfvalpostprev = ods->odfvalpost; |
|
| 508 |
|
|
| 509 |
///////// MEDIAN REMOVAL //////////// |
|
| 510 |
|
|
| 511 |
float* sortbuf = ods->sortbuf; |
|
| 512 |
int medspan = ods->medspan; |
|
| 513 |
|
|
| 514 |
// Copy odfvals to sortbuf |
|
| 515 |
memcpy(sortbuf, ods->odfvals, medspan * sizeof(float)); |
|
| 516 |
|
|
| 517 |
// Sort sortbuf |
|
| 518 |
SelectionSort(sortbuf, medspan); |
|
| 519 |
|
|
| 520 |
// Subtract the middlest value === the median |
|
| 521 |
if(ods->med_odd){
|
|
| 522 |
ods->odfvalpost = ods->odfvals[0] |
|
| 523 |
- sortbuf[(medspan - 1) >> 1]; |
|
| 524 |
}else{
|
|
| 525 |
ods->odfvalpost = ods->odfvals[0] |
|
| 526 |
- ((sortbuf[medspan >> 1] |
|
| 527 |
+ sortbuf[(medspan >> 1) - 1]) * 0.5f); |
|
| 528 |
|
|
| 529 |
} |
|
| 530 |
|
|
| 531 |
// Detection not allowed if we're too close to a previous detection. |
|
| 532 |
if(ods->gapleft != 0) {
|
|
| 533 |
ods->gapleft--; |
|
| 534 |
ods->detected = false; |
|
| 535 |
} else {
|
|
| 536 |
// Now do the detection. |
|
| 537 |
ods->detected = (ods->odfvalpost > ods->thresh) && (ods->odfvalpostprev <= ods->thresh); |
|
| 538 |
if(ods->detected){
|
|
| 539 |
ods->gapleft = ods->mingap; |
|
| 540 |
} |
|
| 541 |
} |
|
| 542 |
#if ODS_DEBUG_POST_CSV |
|
| 543 |
printf("%g\n", ods->odfvalpost);
|
|
| 544 |
#endif |
|
| 545 |
} |
|
| 546 |
|
|
| 547 |
|
|
| onsetsds/onsetsds.h | ||
|---|---|---|
| 1 |
/* |
|
| 2 |
OnsetsDS - real time musical onset detection library. |
|
| 3 |
Copyright (c) 2007 Dan Stowell. All rights reserved. |
|
| 4 |
|
|
| 5 |
This program is free software; you can redistribute it and/or modify |
|
| 6 |
it under the terms of the GNU General Public License as published by |
|
| 7 |
the Free Software Foundation; either version 2 of the License, or |
|
| 8 |
(at your option) any later version. |
|
| 9 |
|
|
| 10 |
This program is distributed in the hope that it will be useful, |
|
| 11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 13 |
GNU General Public License for more details. |
|
| 14 |
|
|
| 15 |
You should have received a copy of the GNU General Public License |
|
| 16 |
along with this program; if not, write to the Free Software |
|
| 17 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 18 |
*/ |
|
| 19 |
|
|
| 20 |
/** \file */ |
|
| 21 |
|
|
| 22 |
#ifndef _OnsetsDS_ |
|
| 23 |
#define _OnsetsDS_ |
|
| 24 |
|
|
| 25 |
#ifdef __cplusplus |
|
| 26 |
extern "C" {
|
|
| 27 |
#endif |
|
| 28 |
|
|
| 29 |
#include <stdio.h> |
|
| 30 |
#include <string.h> |
|
| 31 |
#include <stdbool.h> |
|
| 32 |
#include <math.h> |
|
| 33 |
|
|
| 34 |
|
|
| 35 |
//////////////////////////////////////////////////////////////////////////////// |
|
| 36 |
// Macros and consts |
|
| 37 |
|
|
| 38 |
//log(0.1) |
|
| 39 |
#define ods_log1 -2.30258509 |
|
| 40 |
|
|
| 41 |
#define PI 3.1415926535898f |
|
| 42 |
#define MINUSPI -3.1415926535898f |
|
| 43 |
#define TWOPI 6.28318530717952646f |
|
| 44 |
#define INV_TWOPI 0.1591549430919f |
|
| 45 |
|
|
| 46 |
#define ods_abs(a) ((a)<0? -(a) : (a)) |
|
| 47 |
#define ods_max(a,b) (((a) > (b)) ? (a) : (b)) |
|
| 48 |
#define ods_min(a,b) (((a) < (b)) ? (a) : (b)) |
|
| 49 |
|
|
| 50 |
#define ODS_LOG_LOWER_LIMIT 2e-42 |
|
| 51 |
#define ODS_LOGOF_LOG_LOWER_LIMIT -96.0154267 |
|
| 52 |
#define ODS_ABSINVOF_LOGOF_LOG_LOWER_LIMIT 0.010414993 |
|
| 53 |
|
|
| 54 |
//////////////////////////////////////////////////////////////////////////////// |
|
| 55 |
// Constants |
|
| 56 |
|
|
| 57 |
/** |
|
| 58 |
* Types of incoming FFT data format. OnsetsDS needs to know where the FFT |
|
| 59 |
* data comes from in order to interpret it correctly. |
|
| 60 |
*/ |
|
| 61 |
enum onsetsds_fft_types {
|
|
| 62 |
ODS_FFT_SC3_COMPLEX, ///< SuperCollider, cartesian co-ords ("SCComplexBuf") - NB it's more efficient to provide polar data from SC
|
|
| 63 |
ODS_FFT_SC3_POLAR, ///< SuperCollider, polar co-ords ("SCPolarBuf")
|
|
| 64 |
ODS_FFT_FFTW3_HC, ///< FFTW <a href="http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html">"halfcomplex"</a> format |
|
| 65 |
ODS_FFT_FFTW3_R2C ///< FFTW regular format, typically produced using <a href="http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data">real-to-complex</a> transform |
|
| 66 |
}; |
|
| 67 |
|
|
| 68 |
/** |
|
| 69 |
* Types of onset detection function |
|
| 70 |
*/ |
|
| 71 |
enum onsetsds_odf_types {
|
|
| 72 |
ODS_ODF_POWER, ///< Power |
|
| 73 |
ODS_ODF_MAGSUM, ///< Sum of magnitudes |
|
| 74 |
ODS_ODF_COMPLEX, ///< Complex-domain deviation |
|
| 75 |
ODS_ODF_RCOMPLEX, ///< Complex-domain deviation, rectified (only increases counted) |
|
| 76 |
ODS_ODF_PHASE, ///< Phase deviation |
|
| 77 |
ODS_ODF_WPHASE, ///< Weighted phase deviation |
|
| 78 |
ODS_ODF_MKL ///< Modified Kullback-Liebler deviation |
|
| 79 |
}; |
|
| 80 |
|
|
| 81 |
/** |
|
| 82 |
* Types of whitening - may not all be implemented yet. |
|
| 83 |
*/ |
|
| 84 |
enum onsetsds_wh_types {
|
|
| 85 |
ODS_WH_NONE, ///< No whitening - onsetsds_whiten() becomes a no-op |
|
| 86 |
ODS_WH_ADAPT_MAX1, ///< Adaptive whitening - tracks recent-peak-magnitude in each bin, normalises that to 1 |
|
| 87 |
ODS_WH_NORMMAX, ///< Simple normalisation - each frame is normalised (independent of others) so largest magnitude becomes 1. Not implemented. |
|
| 88 |
ODS_WH_NORMMEAN ///< Simple normalisation - each frame is normalised (independent of others) so mean magnitude becomes 1. Not implemented. |
|
| 89 |
}; |
|
| 90 |
|
|
| 91 |
//////////////////////////////////////////////////////////////////////////////// |
|
| 92 |
// Structs |
|
| 93 |
|
|
| 94 |
typedef struct OdsPolarBin { float mag, phase; } OdsPolarBin;
|
|
| 95 |
|
|
| 96 |
typedef struct OdsPolarBuf {
|
|
| 97 |
float dc, nyq; |
|
| 98 |
OdsPolarBin bin[1]; |
|
| 99 |
} OdsPolarBuf; |
|
| 100 |
|
|
| 101 |
/// The main data structure for the onset detection routine |
|
| 102 |
typedef struct OnsetsDS {
|
|
| 103 |
/// "data" is a pointer to the memory that must be EXTERNALLY allocated. |
|
| 104 |
/// Other pointers will point to locations within this memory. |
|
| 105 |
float *data, |
|
| 106 |
*psp, ///< Peak Spectral Profile - size is numbins+2, data is stored in order dc through to nyquist |
|
| 107 |
*odfvals, // odfvals[0] will be the current val, odfvals[1] prev, etc |
|
| 108 |
*sortbuf, // Used to calculate the median |
|
| 109 |
*other; // Typically stores data about the previous frame |
|
| 110 |
OdsPolarBuf* curr; // Current FFT frame, as polar |
|
| 111 |
|
|
| 112 |
float |
|
| 113 |
srate, ///< The sampling rate of the input audio. Set by onsetsds_init() |
|
| 114 |
// Adaptive whitening params |
|
Also available in: Unified diff