Add cross-platform audio file recording, >sf, and >sfo #18
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Relates to #2 .
TLDR
Adds ability to record to file using
record
as well as>sf
or>sfo
The >sf and >sfo stuff is contained within the SndfileSoundFile and SoundFiles files changes and is more straightforward because it's fine for it to block. Everything else is for record which is more complex...
The bulk of the logic here is in implementing / testing a cross-platform alternative to ExtAudioFileWriteAsync. Using a ring buffer which itself is non-blocking, it minimizes blocking the main thread and delegates the file IO to a separate thread. I have attempted to use a similar approach. The ring buffer itself isn't implemented by me (see the attribution at the top of it) but the rest is. Using optimistic concurrency, it should minimize the need for explicit locking (but falls back to that if needed).
After building this, you should be able to call
record
instead ofplay
like so:For >sf and >sfo you can try (take 5 seconds of analog bubbles)
After you stop it, you should see the test.wav file output to your tmp folder (on windows it's in a different place then on OSX / Linux).
I've also tried to apply some things I've learned recently about writing modern C++ (I just binged the entirety of "A Tour of C++, Third Edition"), at least in new code.
Details
This is just a starting point and there's probably room for optimization. This ring buffer has a fixed total size, for example. There are some other constants I had to choose like chunk size. The size I chose was just an arbitrary guess. There is a different implementation I found elsewhere which can supposedly grow if needed which we could also consider.
It's multithreaded so I've commented a bit more heavily than usual to help explain my reasoning for why I think the implementation should be safe. But this is my first time writing multithreaded C++, so be warned.