initial commit of disconnect supportteensy4-core
@@ -204,20 +204,85 @@ void AudioConnection::connect(void) | |||
{ | |||
AudioConnection *p; | |||
if (isConnected) return; | |||
if (dest_index > dst.num_inputs) return; | |||
__disable_irq(); | |||
p = src.destination_list; | |||
if (p == NULL) { | |||
src.destination_list = this; | |||
} else { | |||
while (p->next_dest) p = p->next_dest; | |||
while (p->next_dest) { | |||
if (&p->src == &this->src && &p->dst == &this->dst | |||
&& p->src_index == this->src_index && p->dest_index == this->dest_index) { | |||
//Source and destination already connected through another connection, abort | |||
__enable_irq(); | |||
return; | |||
} | |||
p = p->next_dest; | |||
} | |||
p->next_dest = this; | |||
} | |||
this->next_dest = NULL; | |||
src.numConnections++; | |||
src.active = true; | |||
dst.numConnections++; | |||
dst.active = true; | |||
isConnected = true; | |||
__enable_irq(); | |||
} | |||
void AudioConnection::disconnect(void) | |||
{ | |||
AudioConnection *p; | |||
if (!isConnected) return; | |||
if (dest_index > dst.num_inputs) return; | |||
__disable_irq(); | |||
// Remove destination from source list | |||
p = src.destination_list; | |||
if (p == NULL) { | |||
return; | |||
} else if (p == this) { | |||
if (p->next_dest) { | |||
src.destination_list = next_dest; | |||
} else { | |||
src.destination_list = NULL; | |||
} | |||
} else { | |||
while (p) { | |||
if (p == this) { | |||
if (p->next_dest) { | |||
p = next_dest; | |||
break; | |||
} else { | |||
p = NULL; | |||
break; | |||
} | |||
} | |||
p = p->next_dest; | |||
} | |||
} | |||
//Remove possible pending src block from destination | |||
dst.inputQueue[dest_index] = NULL; | |||
//Check if the disconnected AudioStream objects should still be active | |||
src.numConnections--; | |||
if (src.numConnections == 0) { | |||
src.active = false; | |||
} | |||
dst.numConnections--; | |||
if (dst.numConnections == 0) { | |||
dst.active = false; | |||
} | |||
isConnected = false; | |||
__enable_irq(); | |||
} | |||
// When an object has taken responsibility for calling update_all() |
@@ -83,21 +83,28 @@ public: | |||
AudioConnection(AudioStream &source, AudioStream &destination) : | |||
src(source), dst(destination), src_index(0), dest_index(0), | |||
next_dest(NULL) | |||
{ connect(); } | |||
{ isConnected = false; | |||
connect(); } | |||
AudioConnection(AudioStream &source, unsigned char sourceOutput, | |||
AudioStream &destination, unsigned char destinationInput) : | |||
src(source), dst(destination), | |||
src_index(sourceOutput), dest_index(destinationInput), | |||
next_dest(NULL) | |||
{ connect(); } | |||
{ isConnected = false; | |||
connect(); } | |||
friend class AudioStream; | |||
protected: | |||
~AudioConnection() { | |||
disconnect(); | |||
} | |||
void disconnect(void); | |||
void connect(void); | |||
protected: | |||
AudioStream &src; | |||
AudioStream &dst; | |||
unsigned char src_index; | |||
unsigned char dest_index; | |||
AudioConnection *next_dest; | |||
bool isConnected; | |||
}; | |||
@@ -137,11 +144,13 @@ public: | |||
next_update = NULL; | |||
cpu_cycles = 0; | |||
cpu_cycles_max = 0; | |||
numConnections = 0; | |||
} | |||
static void initialize_memory(audio_block_t *data, unsigned int num); | |||
int processorUsage(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles); } | |||
int processorUsageMax(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles_max); } | |||
void processorUsageMaxReset(void) { cpu_cycles_max = cpu_cycles; } | |||
bool isActive(void) { return active; } | |||
uint16_t cpu_cycles; | |||
uint16_t cpu_cycles_max; | |||
static uint16_t cpu_cycles_total; | |||
@@ -161,6 +170,7 @@ protected: | |||
static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); } | |||
friend void software_isr(void); | |||
friend class AudioConnection; | |||
uint8_t numConnections; | |||
private: | |||
AudioConnection *destination_list; | |||
audio_block_t **inputQueue; |