Skip to content

Latest commit

 

History

History
37 lines (28 loc) · 3.98 KB

EventResponder-TVP.md

File metadata and controls

37 lines (28 loc) · 3.98 KB

EventResponder-based Teensy Variable Playback

This document gives a brief description of the use of the EventResponder-based branch of the Teensy Variable Playback library, plus a little technical detail.

In use

Basic functionality

The functionality provided by this branch is intended to be as close as possible to the original: please see the ReadMe.md file and examples for details.

Extended functionality

In order to avoid crashes if your application tries to access the same filesystem that's being used for playback, a number of options are available:

  • Don't: wait until playback is finished, then use the filesystem. Not satisfactory for most people...
  • Mask EventResponder responses while you're accessing the filesystem
  • Perform EventResponder responses directly from your code, when you know it's safe

All the methods described below must only be called from normal foreground code, i.e. setup() or loop(). DO NOT call them from interrupt, it will almost certainly result in a crash or other misbehaviour. Eventually, if not sooner. Trust me on this.

EventResponder masking

This technique temporarily masks execution of all EventResponder responses from within the yield() function, not just those relevant to the Teensy Variable Playback and/or filesystem access. Hence you should try to minimise the time spent with responses masked. See the FileAccess example sketch for an example of how this can be used.

AudioEventResponder::disableResponse()

Call this function before your code accesses the filesystem: this includes open(), write(), read(), mkdir() etc. EVERYTHING

AudioEventResponder::enableResponse()

Call this function after you've finished accessing the filesystem. It's OK to leave a file open, so long as you don't access it...

EventResponder polled mode

This is not part of the Teensyduino library, but has been "grafted on" by the AudioEventResponder derived class.

AudioEventResponder::setForceResponse(bool)

This function must be called once, with its parameter set to true, in setup(), to prevent disableResponse() and enableResponse() from being effective (they are called internally in the library, so this is important!). The library will now use polled events only, and not mask yield-based events triggered by other libraries. If those cause crashes, it's not my fault.

You can call it with a false parameter as well, to revert to needing to use the masking functions. Dunno why you would do that, though.

AudioEventResponder::runPolled()

Call this to execute one of the pending buffer-filling events. If it returns -1, no events were pending; 0 means one was pending and has been executed, and no more remain pending; 1 means one was executed, and at least one more remains pending. It's up to you to decide how often to call this method; it will depend on how many playback objects are active, how big their buffers are, and other factors.

Technical stuff

Rather than directly accessing the filesystem from within the interrupt-based audio update() code, this library triggers events which are responded to by the EventResponder "experimental API". Originally this was done in yield(), but it turns out that lots of libraries call yield() internally, including filesystems, and there is no mechanism provided to defer execution of a response if it "would be unsafe" - you simply can't tell.

The EventResponder library provides neither a "polled" response mechanism, nor a way of masking responses while the system is in a state where it is unsafe to respond. These have been "grafted on" using the AudioEventResponder derived class. This is even more experimental, and it's entirely possible that its name and the names of its methods will change, at least in the short term.

In the longer term, this functionality, or some variant thereof, may be added into the EventResponder library itself. This is technically straightforward, but unlikely to happen any time soon.