Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio refactor #178

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 42 additions & 77 deletions inc/streams/DataStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ DEALINGS IN THE SOFTWARE.

#define DATASTREAM_SAMPLE_RATE_UNKNOWN 0.0f

#define DATASTREAM_DONT_CARE 0
#define DATASTREAM_NOT_WANTED 1
#define DATASTREAM_WANTED 2


namespace codal
{
/**
Expand All @@ -55,7 +60,6 @@ namespace codal
class DataSink
{
public:

virtual int pullRequest();
};

Expand All @@ -64,6 +68,8 @@ namespace codal
*/
class DataSource
{
int dataIsWanted;

public:
virtual ManagedBuffer pull();
virtual void connect(DataSink &sink);
Expand All @@ -72,27 +78,54 @@ namespace codal
virtual int getFormat();
virtual int setFormat(int format);
virtual float getSampleRate();
virtual float requestSampleRate(float sampleRate);
virtual void dataWanted(int wanted);
virtual int isWanted();
};

/**
* This class acts as a base class for objects that serve both the DataSource and DataSink interfaces.
* Classes anre not required to use this, but are strongly encouraged to use this as a base class, in order
* to reduce complexity, ensure consistent behaviour, and reduce duplicated code.
*/
class DataSourceSink : public DataSource, public DataSink
{

public:
DataSink *downStream;
DataSource &upStream;

/**
* Constructor.
* Creates an empty DataSourceSink.
*
* @param upstream the component that will normally feed this datastream with data.
*/
DataSourceSink(DataSource &upstream);
virtual ~DataSourceSink();

virtual void connect(DataSink &sink);
virtual bool isConnected();
virtual void disconnect();
virtual int getFormat();
virtual int setFormat(int format);
virtual float getSampleRate();
virtual void dataWanted(int wanted);
virtual int pullRequest();
};

/**
* Class definition for DataStream.
* A Datastream holds a number of ManagedBuffer references, provides basic flow control through a push/pull mechanism
* and byte level access to the datastream, even if it spans different buffers.
*/
class DataStream : public DataSource, public DataSink
class DataStream : public DataSourceSink
{
uint16_t pullRequestEventCode;
uint16_t flowEventCode;
ManagedBuffer nextBuffer;
bool hasPending;
bool isBlocking;
unsigned int missedBuffers;
int downstreamReturn;

DataSink *downStream;
DataSource *upStream;

public:

/**
Expand All @@ -109,58 +142,12 @@ namespace codal
*/
~DataStream();

/**
* Controls if this component should emit flow state events.
*
* @warning Should not be called mutliple times with `id == 0`, as it will spuriously reallocate event IDs
*
* @param id If zero, this will auto-allocate a new event ID
* @return uint16_t The new event ID for this DataStream
*/
uint16_t emitFlowEvents( uint16_t id = 0 );

/**
* Determines if any of the data currently flowing through this stream is held in non-volatile (FLASH) memory.
* @return true if one or more of the ManagedBuffers in this stream reside in FLASH memory, false otherwise.
*/
bool isReadOnly();

/**
* Attempts to determine if another component downstream of this one is _actually_ pulling data, and thus, data
* is flowing.
*
* @return true If there is a count-match between `pullRequest` and `pull` calls.
* @return false If `pullRequest` calls are not currently being matched by `pull` calls.
*/
bool isFlowing();

/**
* Define a downstream component for data stream.
*
* @sink The component that data will be delivered to, when it is available
*/
virtual void connect(DataSink &sink) override;

/**
* Determines if this source is connected to a downstream component
*
* @return true If a downstream is connected
* @return false If a downstream is not connected
*/
virtual bool isConnected();

/**
* Define a downstream component for data stream.
*
* @sink The component that data will be delivered to, when it is available
*/
virtual void disconnect() override;

/**
* Determine the data format of the buffers streamed out of this component.
*/
virtual int getFormat() override;

/**
* Determines if this stream acts in a synchronous, blocking mode or asynchronous mode. In blocking mode, writes to a full buffer
* will result int he calling fiber being blocked until space is available. Downstream DataSinks will also attempt to process data
Expand All @@ -187,29 +174,7 @@ namespace codal
*/
virtual int pullRequest();

/**
* Query the stream for its current sample rate.
*
* If the current object is unable to determine this itself, it will pass the call upstream until it reaches a component can respond.
*
* @warning The sample rate for a stream may change during its lifetime. If a component is sensitive to this, it should periodically check.
*
* @return float The current sample rate for this stream, or `DATASTREAM_SAMPLE_RATE_UNKNOWN` if none is found.
*/
virtual float getSampleRate() override;

/**
* Request a new sample rate on this stream.
*
* Most components will simply forward this call upstream, and upon reaching a data source, if possible the source should change
* the sample rate to accomodate the request.
*
* @warning Not all sample rates will be possible for all devices, so if the caller needs to know the _actual_ rate, they should check the returned value here
*
* @param sampleRate The requested sample rate, to be handled by the nearest component capable of doing so.
* @return float The actual sample rate this stream will now run at, may differ from the requested sample rate.
*/
virtual float requestSampleRate(float sampleRate) override;
virtual void connect(DataSink &sink);

private:
/**
Expand Down
15 changes: 1 addition & 14 deletions inc/streams/EffectFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@

namespace codal
{
class EffectFilter : public DataSource, public DataSink
class EffectFilter : public DataSourceSink
{
protected:

DataSink *downStream;
DataSource &upStream;
bool deepCopy;

public:
Expand All @@ -21,15 +17,6 @@ namespace codal
~EffectFilter();

virtual ManagedBuffer pull();
virtual int pullRequest();
virtual void connect( DataSink &sink );
bool isConnected();
virtual void disconnect();
virtual int getFormat();
virtual int setFormat( int format );

virtual float getSampleRate();
virtual float requestSampleRate(float sampleRate);

/**
* Defines if this filter should perform a deep copy of incoming data, or update data in place.
Expand Down
10 changes: 1 addition & 9 deletions inc/streams/FIFOStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace codal {

class FIFOStream : public DataSource, public DataSink
class FIFOStream : public DataSourceSink
{
private:

Expand All @@ -20,21 +20,13 @@ namespace codal {
bool allowInput;
bool allowOutput;

DataSink *downStream;
DataSource &upStream;

public:

FIFOStream( DataSource &source );
~FIFOStream();

virtual ManagedBuffer pull();
virtual int pullRequest();
virtual void connect( DataSink &sink );
bool isConnected();
virtual void disconnect();
virtual int getFormat();
virtual int setFormat( int format );
int length();
void dumpState();

Expand Down
37 changes: 21 additions & 16 deletions inc/streams/LevelDetectorSPL.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ DEALINGS IN THE SOFTWARE.
#define LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED 0x02
#define LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED 0x04
#define LEVEL_DETECTOR_SPL_CLAP 0x08
#define LEVEL_DETECTOR_SPL_DATA_REQUESTED 0x10


/**
Expand Down Expand Up @@ -82,6 +83,7 @@ DEALINGS IN THE SOFTWARE.
#define LEVEL_DETECTOR_SPL_CLAP_MIN_LOUD_BLOCKS 2 // ensure noise not too short to be a clap
#define LEVEL_DETECTOR_SPL_CLAP_MIN_QUIET_BLOCKS 20 // prevent very fast taps being registered as clap

#define LEVEL_DETECTOR_SPL_TIMEOUT 50 // Time in ms at which we request no further data.

namespace codal{
class LevelDetectorSPL : public CodalComponent, public DataSink
Expand All @@ -97,18 +99,18 @@ namespace codal{
int sigma; // Running total of the samples in the current window.
float gain;
float minValue;
bool activated; // Has this component been connected yet
bool enabled; // Is the component currently running
int unit; // The units to be returned from this level detector (e.g. dB or linear 8bit)
int quietBlockCount; // number of quiet blocks consecutively - used for clap detection
int noisyBlockCount; // number of noisy blocks consecutively - used for clap detection
bool inNoisyBlock; // if had noisy and waiting to lower beyond lower threshold
float maxRms; // maximum rms within a noisy block
bool enabled; // Is the component currently running.
int unit; // The units to be returned from this level detector (e.g. dB or linear 8bit).
int quietBlockCount; // number of quiet blocks consecutively - used for clap detection.
int noisyBlockCount; // number of noisy blocks consecutively - used for clap detection.
bool inNoisyBlock; // if had noisy and waiting to lower beyond lower threshold.
float maxRms; // maximum rms within a noisy block.

private:
uint64_t timeout; // The timestamp at which this component will cease actively sampling the data stream
uint8_t bufferCount; // Used to track that enough buffers have been seen since activation to output a valid value/event
FiberLock resourceLock;
uint8_t bufferCount; // Used to track that enough buffers have been seen since activation to output a valid value/event.
uint8_t listenerCount; // The total number of active listeners to this component.
FiberLock resourceLock; // Fiberlock - used purely hold fibers requesting data before it is available.
uint64_t timestamp; // Timestamp of the last time someone requesed data from this component.
public:

/**
Expand All @@ -122,9 +124,13 @@ namespace codal{
*/
LevelDetectorSPL(DataSource &source, float highThreshold, float lowThreshold, float gain,
float minValue = 52,
uint16_t id = DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL,
bool activateImmediately = true);
uint16_t id = DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL);

/**
* Periodic callback, every 6ms or so.
*/
void periodicCallback();

/**
* Callback provided when data is ready.
*/
Expand All @@ -139,11 +145,10 @@ namespace codal{
float getValue( int scale = -1 );

/**
* Keep this component active and processing buffers so that events can be produced
*
* @param state If set to true, this component will connect (if required) and start consuming buffers
* Callback when a listener to this component is added.
* n.b. we currently don't support removing listners (future work if necessary)
*/
void activateForEvents( bool state );
void listenerAdded();

/**
* Disable component
Expand Down
37 changes: 0 additions & 37 deletions inc/streams/StreamFlowTrigger.h

This file was deleted.

Loading