Some utility externals: - rubberband~, noteid~, chordid~
rubberband~ is an external that implements a pitch shifter using the open source rubberband time-stretch and pitch shift library. This pitch shifter uses a phase vocoder, and has been tuned to preserve formants (most specifically, vocal formants).
noteid~ implements the open source dywapitchtracker library - this Dynamic Wavelet pitch tracker includes several features to enhance pitch tracking stability. This tool provides output at 512 samples.
chordid~ implements a chord identification tool - Chromagram/ChordDetector by Adam Stark.
This can identify chords in an audio stream (such as from a guitar) and provide detailed information such as midi notes, chord name, etc. This can provide output at 512 samples
The combination of these tools allows a number of capabilities -
chord display, pitch correction, intelligent vocal harmonisation
Currently these Externals are only available for Windows (32-bit and 64-bit). The source is available for anyone who wishes to attempt to compile these for Mac.
The URL is as follows :
https://www.dropbox.com/sh/a28ykhhmdiifenz/AADnZLrBcNdAmAt_6z-XmtbGa?dl=0
Future developments include a highly efficient single-source multiple pitch shifter that will allow a single source stream to be shifted by multiple simultaneous pitch shifts and combined into a single output stream. This will cut the CPU cost of multiple shifts. I also want to modify these externals to use FFTW for additional performance improvements.
I do have some M4L devices that need additional tuning and design to get them working really well.
I'll add them to the folder once they are ready.
Simon
Hi Simon
thanks for these; could you recommend some audio settings for rubberband please? I like the sound of this but I'm getting some crackling during shifting, probably cuz I'm just using my laptop soundchip/driver. Win 7 64bit, Max 6.1.10 32bit, ASIO4ALL available
Thx
Brendan
Thanks, this seems very interesting ! But...
there seems to be a problem wiht your dropbox link. Maybe consider hosting it on this website with the "tool" pages ?
and why did you not port it to osx - are there some windows specific library used ? Or is it just that you don't know how to make osx external from windows ? maybe both...
All the code should be portable to OSX. I don't believe VS2013 allows cross-compilation to OSX, but I'm happy to be educated.
I'll check the drop box link from another PC - it did work when I first tested it...
VICHUG,
I tested the dropbox link from a bunch of browsers - it may not work with IE8. Chrome and Firefox were fine.
Simon
Great work, Simon, thanks for sharing.
@Vichug: I'm very interested in this cross-platform compilation. Is it also possible targeting Windws externals from OSX?
waitwaitwait i don't know :D i was asking that because i may give it a shot (compiling for OSX) a little later this week if it's not too complicated (hence my questions about dependencies...) because my knowledge is very limited in the domain, but it *should* be straightforward to compile from sources from OSX to OSX. However, i'm aware that compiling form Windows for OSX *is* really complicated. The same goes for targetting Windows from OSX... a priori...
The dropbox seems fine for me now too, by the way.
As far as I know there's no cross-compiler from Windows to OSX. I got the mingw cross-compiler for OSX to build at one point, to compile for Windows from OSX. But it was a huge pain, and then testing is a problem because there's no (official nor fully working) wine64 on OSX.
I highly recommend using virtual machines to get a full working environment. VirtualBox is free and version 5 isn't bad.
If no one gets this compiled this week, I can take a look.
Cool, as I said, the source is all pretty portable, so please have a go. I'll help as much as I can.
Simon
And today, Ableton releases a free M4L pack including pitch tracking, retuning and multiharmonizor. The only thing they have not got in the new pack is audio chord recognition. I can shoehorn it in, I guess.
Mildly pissed. But I will get some ideas about how to wrap rubberband~ into a poly~.
@Simon Blakely: This free pack is composed of the amxd's which are in Max 7 already.
Oh, OK. So just packaging stuff that is already there.
I'm going home to play and edit - I can hopefully get (steal) some ideas for nicer interfaces and control structures. I don't really have a handle on Max programming yet - I'd prefer to use js patchers for control, as I understand procedural languages, but it isn't realy practical.
I have a prototype harmony effect, but the interface is crap and I need to use more threads/cores, so if I can get that sorted I'll be happy.
Simon
re : compiling those externals for maxOSX -
I think i'll pass, because when i try to compile, XCode tells me :
in sysutils.h : 'malloc.h' file not found
in sysutils.h : 'process.h' file not found
and i don't know what to do with that,
after a quick googling it says 'malloc.h' can be replaced on OSX with stdlib.h or tha tit can be found somewhere else on osx (you have to specify the path specifically) so malloc.h might not be such a big deal ; but process.h seems another level of problem. I have no clue how to solve this. Maybe i'm wrong somewher else.
@VICHUG: the way I got started in development on Windows was to get the Max SDK installed first.
Then I downloaded the https://github.com/grrrwaaa/maxcpp Maxcpp library.
> The example projects should work 'out of the box' if this repo is placed inside your MaxSDK folder (next to the c74support folder)
So test that you can compile the MaxCPP examples. Once that is working, my external folders (noteid, chordid, rubberband) go into the maxcpp/examples/msp/ folder. Copy a XCode project from the working example, rename it and add the .cpp and header files.
chordid and rubberband need preprocessor directives to select the FFT (KissFFT is included in both), and rubberband needs to include speex resampler.
I hope this helps. But it took me a week or so to get my first external compiled and loaded into Max 7
process.h seems to be a low-level windows only OS library, that's why i said that
i'm not 100% certain that i did not something wrong tho, because it should have detected that i'm not using Windows and hence used other dependencies ? but i did what you said and have this result, unfortunately.
great stuff!
thanks!
@VICHUG:
I have found the probable source of the issue - in rubberband\src\system\sysutils.h there is an errant
#define __MSVC__
line 27.
Delete this line and things should work better - I was fighting with the VC++ project system, took a shortcut and forgot to go and clean this up.
Simon
ookay
we might be going somewhere :)
in rubberband~.cpp, line 603 there is a : if (m_bufferoffset[0] = 64)
.
It gives me just a warning, since the if will always be true (m_bufferoffset[0] is set to 64 so it will always be 64 which is ≠ 0)
Did you mean : if (m_bufferoffset[0] == 64)
?
SImilarly line 611 there is if (m_bufferfull = 1)
. Did you mean if (m_bufferfull == 1)
?
Then build fails because i have a lot of these :
Undefined symbols for architecture x86_64:
"RubberBand::RubberBandStretcher::setTimeRatio(double)", referenced from:
RubberBandExt::runImpl(unsigned long, unsigned long) in rubberband~.o
. I'm not sure what happens there.
Also, line 41 in rubberband~.cpp, i changed #include ".\rubberband\RubberBandStretcher.h"
to #include "./rubberband/RubberBandStretcher.h"
, because otherwise it gave me a '.\rubberband\RubberBandStretcher.h' file not found
(you can't have filepaths with \ in osx, i thought they were windows only, is there a reason you also have paths with / ?)
@VICHUG:
Thanks for your persistence, even if it exposes my incompetence.
The m_bufferoffset/m_bufferfull code was in place because I had issues with very small vector sizes (when vs =1). So I decided to buffer 64 samples by default and got it very wrong. But at least the compiled behavior was valid (but it never solved the vs = 1 problem). I'll correct and test later.
Sorry about the "\" - I work on Linux all day but often support Windows users, and I get excessively cautious about path delimiters, and I wasn't quite thinking about cross platform compilation at first. Compiling at all was the primary goal.
The undefined symbols probably indicate that other files need to be added to the compilation list. My project file includes:
Allocators. CPP
AudioCurveCalculator.CPP
commonsyms.C
CompoundAudioCurve.CPP
ConstantAudioCurve.CPP
FFT.CPP
getopt.C
hash.C
HighFrequencyAudioCurve.CPP
Kiss_FFT.C
minmax.C
PercussiveAudioCurve.CPP
Profiler.CPP
Resample.C
Resample.CPP
Resource.h
Ringbuffer.hh
RubberBandPitchShifter.CPP
RubberBandPitchShifter.h
RubberBandStretcher.CPP
SilentAudioCurve.CPP
SpectralDifferenceAudioCurve.CPP
StretchCalculator.CPP
StretcherChannelData.CPP
StretcherImpl.CPP
Sysutils.CPP
Thread.CPP
VectorOpsComplex.CPP
Note the C files - you may need to change compile options for these (C rather than C++)
Thanks again for your patience.
"Compiling at all was the primary goal" Well understandable :D
-I don't seem to be able to find commonsyms.c in the sources folder
-I included in project the files you mentionned. It seems indeed to work better. I do'tn really understand when a file should be included in project or when it is automatically referenced by another file in the project... well. I also added the coressponding .h files when there was one for a .cpp file.
-It seems the c/c++ is set automatically by xcode, i don't know how/if i need to do anything more here.
-Only 3 errors left !In thread.h : line 62, semantic issue : Unknown type name 'Id'In thread.h : User-Defined Issue : No thread implementation selectedIn FFT.cpp : User-Defined Issue : No FFT implementation selected !
I suppose the undefinition issues should be solved if i knew how to add compilation variants (it seems to be what is missing ?) but i don't. For the unknown type, i might miss another file ? Or it is not installed in a right relative path ? Or something ?
commonsyms.c is in "c74support/max-includes/common/"
You need to set at least the following preprocessor directives - probably in the XCode project options.
USE_SPEEX
USE_KISSFFT
For the Threading implementation, either define
NO_THREADING
or
USE_PTHREADS
I don't know if PTHREADS () is suitable for MacOS or if it is a posix threading library for linux.
I'd try USE_PTHREADS first.
Simon
PTHREADS is suitable i think. But i don't know where to set preprocessor directives in Xcode (yeah, i know nothing), or i tried the right place and it didn't work ; i tried to pass the options under Build Options ->Build Variants and i tried in Packaging -> Info.plist Preprocessor Flags ; also Packaging -> Info.plist Preprocessor Defintions ; to no avail.
ok, found it (under preprocessing - Preprocessor Macros)
now it says it doesn't know some files in folder "system/". But i already imported those files at the root of the project, after removing "system" from the path of the files it seems to work.
now in sysutils.cpp line 254 : Use of undeclared identifier 'getpid'
it's inside a section that runs only if _WIN32 is not defined
You may need to ensure that __APPLE__ is defined as a preprocessor directive.
just did, no change
Sadly, that is library code, and I didn't have anything to do with it. I have seen references to "getpid" and causing issues, but this is now beyond what I can figure out. Any Mac programmers with an idea?
Just have a minute to mention that I found this thread also trying to get anything to compile using Max7 SDK and Windows 7 64... using Cygwin. I'll report what I discover here in the forums.
@M Miller : are you trying to target osx from Windows with this compilation ?
I have 2 out of 3 externals building on OSX after some amount of effort. rubberband~ still won't build, though, because there's some source code missing:
Undefined symbols for architecture i386:
"_rubberband_resampler_destroy", referenced from:
RubberBand::Resamplers::D_Speex::~D_Speex() in Resampler.o
"_rubberband_resampler_get_ratio", referenced from:
RubberBand::Resamplers::D_Speex::setRatio(float) in Resampler.o
"_rubberband_resampler_init_frac", referenced from:
RubberBand::Resamplers::D_Speex::D_Speex(RubberBand::Resampler::Quality, int, int, int) in Resampler.o
"_rubberband_resampler_process_interleaved_float", referenced from:
RubberBand::Resamplers::D_Speex::resample(float const* const restrict*, float* const restrict*, int, float, bool) in Resampler.o
RubberBand::Resamplers::D_Speex::resampleInterleaved(float const*, float*, int, float, bool) in Resampler.o
"_rubberband_resampler_reset_mem", referenced from:
RubberBand::Resamplers::D_Speex::reset() in Resampler.o
"_rubberband_resampler_set_rate_frac", referenced from:
RubberBand::Resamplers::D_Speex::setRatio(float) in Resampler.o
"_rubberband_resampler_skip_zeros", referenced from:
RubberBand::Resamplers::D_Speex::setRatio(float) in Resampler.o
These C-linkage functions are not in the source code supplied. If the OP can provide them, I can post the projects + binaries later today.
Thanks Jeremy, that'd be awesome. However it's strange, because i don't have the same errors when trying to build here. Comparison between my attempts and your projects (are you talking XCode projects ?) should help me :)
Hmm, I wonder if this is a linker problem.
Those functions appear to be references to speex_resampler_get_ratio/speex_resampler_destroy/speex_resampler_process_interleaved_float which should be in src/speex/resample.c
This should be linked in via the preprocessor directive USE_SPEEX
is resampler.c added to the project?
is it compiled as C or C++? In my Visual C++ project, it is set as C++, but that may not mean much in XCode (it does impact calling conventions in Visual C++).
Beyond that, I'm not sure.
Simon
And Jeremy/Vichug - I really do appreciate your assistance and efforts.
I have just started looking at using FFTW as opposed to KISSFFT - primarily for performance reasons.
I'm having a few issues at this stage, but this may be VisualC++ issues.
Simon
OK, weird. My linker was apparently giving me incorrect symbols. Yes, adding that file to the project solved the issue, thanks!
https://app.box.com/s/k0rcdtdhhdcybjncd3gwtnyccwush69k Xcode projects + sources (some minor modifications were necessary)
The binaries load in Max, haven't tested their functionality, though.
jb
Thanks a lot !
@VICHUG Not primarily targeting OS X, mostly for my own use in Windows. The Max 5 docs mention Cygwin. I don't really want to install Visual Studio. If there is a Ruby script included which can compile all the examples I might start there. This thread was the only recent one I could seem to find discussing compiling externals. Is there somewhere else I could look? Thanks.
I'm hanging here ...
Do they work?
:D Sorry i was in a rush today... i will try that first hour tomorrow !
@VICHUG: no worries, in your own time.
rubberband~ is working (although you have to change the float input to a my_float in the helpfile). noteid~ appears to be working, as well.
chordid~.maxhelp hangs Max, but I haven't had a chance to look in the debugger to see where.
Hmm, I'm not sure I understand
>> (although you have to change the float input to a my_float in the helpfile)
Actually, maybe I do. There was a bug in the MaxCPP library I had to change around FLOAT ...
Check that out ...
This was almost certainly the issue - yesterday I used my work PC to recompile chordid~ and rubberband~ using FFTW3 (from the original sources), and rubberband~ stopped working when I loaded it up in Max. Once I threw the fftw3 libs back on my laptop (my laptop install of VC++ 2013 Express cannot compile FFTW) and relinked everything, the updated externals now work.
I'll add my fixed copy of MaxCPP to the dropbox tonight. I need to rebuild the 32-bit Windows externals to use FFTW - I think rubberband~ actually sounds better with FFTW3, from a very quick test. This should be finished tomorrow, and everything uploaded.
I am somewhat tempted to redevelop the rubberband~ interface semantics to make it drop-in compatible with pitchshift~.
Anybody got any thoughts?
(rubberband, noteid wrork ; chordid drops.rubberband sounds nice)
(about the semantics ; that sounds like a good idea ?)
@VICHUG - Thanks for the feedback. I'm glad you like rubberband - I spent several days tuning the Formant Preservation to get it sounding right (in my impression, anyhow). The quality of the pitch shift itself I cannot take any credit for - that comes from the original source.
As for chordid - I hope that can be sorted. The code seems pretty straightforward and does not have a lot of options, so I don't think there should be too many difficulties fixing it. Hopefully someone can get in with a debugger to find the issue.
@Jeremy, @VICHUG,
I have been testing my version of Rubberband~ compiled with FFTW3 as compared with KISSFFT: the performance difference is significant.
According to the FFTW benchmarks, it should be ~4x faster on a single core. However, I think KISSFFT is single-threaded and FFTW3 is multithreaded, so the overall speedup is massive on a multiprocessor system. I could only just have 3 single channel rubberband~ instances in a single M4L device using KISSFFT, with FFTW3 I could have several more. So it does take a bit of work to compile FFTW3 into a library (particularly on Windows), but it is worth the effort for the performance gains.
I've used static linking to avoid DLL issues, for OSX, you guys can make the choice. It makes the externals bigger, but it is easier to manage for users.
I'll try to tune up the M4L vocal harmonizor I have been building, make a demonstration video and upload it to showcase the toolset.
Simon
I am not well-versed in how MaxCpp works, but... I think the problem in chordid~ is that you are using a std::vector object as a member of the Chordid class, which is going to mess with the sizeof() calculation of MaxCpp and probably cause memory corruption. Try using a std::vector* instead and new/delete it. However, there's something else going on in my debugger right now, so I can't be 100% sure if that's the full extent of the problem.
@Jeremy: Good spot. I'll rework the code tomorrow. I dislike C/C++ pointers, but I think I know how to rework it.
Simon
@Jeremy:
I had a look at this today, and I'm now I am not so sure.
std::vector seems to be a fixed size object (20 or 24 bytes), and allocates storage data for the actual data array on the heap.
And I wrote chordid~ first, and used it for the template for both noteid~ and rubberband~, so if there was an issue with that approach, I'd expect problems with all of them.
I'll keep looking at the code.
Simon
Hi all, it seems that I'm getting late into the game as a number of problems have been fixed already. I'm trying to compile chordid~ on the Mac, and of course I'm using versions of Max (7.2.2 with 7.1 SDK) and XCode (7.3) that are a bit newer. I've assured that I can compile the maxcpp example~ and I've also amended the cloned project definition for the chordid project, but now I have compilation errors that I cannot resolve.
There are three template instantiation problems related to std::string and two type mismatches related to type Chordid, see below.
Do you have any suggestions?
/Users/bertramd/Documents/Max 7/Packages/max-sdk-7.1.0/source/maxcpp/examples/chordid/Chord-Detector-and-Chromagram-master/src/ChordDetector.h:74:14: Implicit instantiation of undefined template 'std::basic_string, std::allocator >'
/Users/bertramd/Documents/Max 7/Packages/max-sdk-7.1.0/source/maxcpp/examples/chordid/Chord-Detector-and-Chromagram-master/src/ChordDetector.h:94:14: Implicit instantiation of undefined template 'std::basic_string, std::allocator >'
/Users/bertramd/Documents/Max 7/Packages/max-sdk-7.1.0/source/maxcpp/examples/chordid/chordid~.cpp:60:14: Implicit instantiation of undefined template 'std::basic_string, std::allocator >'
/Users/bertramd/Documents/Max 7/Packages/max-sdk-7.1.0/source/maxcpp/examples/chordid/chordid~.cpp:78:3: Cannot initialize object parameter of type 'MspCpp6' with an expression of type 'Chordid'
/Users/bertramd/Documents/Max 7/Packages/max-sdk-7.1.0/source/maxcpp/maxcpp/maxcpp6.h:346:3: Cannot initialize object parameter of type 'MspCpp6' with an expression of type 'Chordid'
Bertram,
Thanks for having a go - I have no idea about XCode but this indicates
http://stackoverflow.com/questions/19223360/implicit-instantiation-of-undefined-template-stdbasic-stringchar-stdchar
add
#include
#include
#include
Simon
Wow, that worked indeed. Many thanks for your quick reply. I should have tried Dr. Google. Now I just need to figure out how to the get the Chromagram object linked into the binary, as the linker is throwing out undefined symbols regarding it.
Ok, I got the code to link and after a few hours also managed to the the XCode configuration into a shape where it produces the right binary type (I'm no expert, my C++ skills haven't been used for almost 20 years).
Now, I've put the chordid~ into a patcher with a signal (music or sinus) feeding to its input. From the description, it's not quite clear to me how it's supposed to be connected, so I've also tried attaching a metro->bang to the input in order to trigger the output of the chord details.
The sound flows through the object alright.
However, I get no data output, and the 1/0 indicator for signal quality is constantly at 0.
Do you have any more advice?
Bertram,
You should set the rms value to something like 0.05. You don't need to bang the inlet, it should automatically fire out the data.
I'll provide some more details tomorrow, as it has got late here. Also, use chordal input - strummed guitar or piano chords.
Do you not have the demo patch I provided with the source?
No, I don't think so. I found some older patches using chorddetect~
Where can I find them? I got the sourcefiles from GitHub and Dropbox, but the examples aren't there, I think.
Bertram : you connected the outlets of chordid to the left inlets of the message boxes. You have to connect the right inlet of those, or put a [prepend set] between chordid~ and message boxes, if you want their content to be updated by chordid~'s output
@Vichug: You're a star. How stupid is that! *facepalm*
Ok, I got it all to work now, playing around with RMS and rate values to get better results. It seems that gain control is actually quite important. If I turn up the signal to be louder, the detection is better (I'm routing the sounds from my other apps to Max via Soundflower).
I think I need an automatic gain control element in there.
You're very much wlecome ! Expecially if you compiled chordid for osx ! Then you'd be the star if you share your results :D
Sure, I have it all under GitHub control, so once I'm done with all the checks, I can request a pull to integrate the changes (add'l include statements) and the Xcode config and project files.
Seems to work well in 64-bit but crashes 32-bit Max.... Anyone manage to get a working compilation?
I'll retry to compile the 32-bit objects - I don't have 32-bit Max so I can't really test them, though.
Hi everyone, I just stumbled on this thread and I'm so glad that I did! I'm wondering if there has been any progress on compiling for Mac, or if that goal has been scrapped?
Hi Simon
Any luck with recompling chordID~ so that it will work on 32bit Win7?
I can help test if you need to! In win 8/64 - no problem you just copy the whole folder to the max externals and it works. i'm guessing that in 32/win7 the different elements need to be filed manually in different folders? - in particular the library? I've tried different locations for things but ..no luck
cheers Pete
Sorry it has taken me way too long to get back to this thread.
In terms of Mac - I think the latest Visual Studio allows me to target MacOS, so I'll give that a crack, and I'll regenerate the 32-bit Windows objects as well.
I'll try to get all that done this weekend
Simon
Hi Simon,
Thank you so much for coming back to this project! I'd love to know whether you had any success building this for MacOS?
-Hugh
Seems a few people interested in a Mac version here and, since it was easy for me to do, I created an Xcode project and compiled the binary for 32/64-bit Mac.
You can grab it on this branch here:-
https://github.com/carthach/chordid/tree/mac_support
Simon - I submitted a pull request if you want to merge it at some stage, I also pulled the changes you made for the archive you have on the dropbox.
Enjoy!
Thanks so much Carthach! I'm looking forward to testing this out today on my Mac build. I'll let you know if I come across any issues!
I just compiled it and opened it with Max to check if it didn't blow up, after that you're on your own I'm afraid!
Is there a Mac version of rubberband~ that I can download?
Nope, but you can build it using the fork I have included above.