| @@ -179,20 +179,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() | |||
| @@ -76,21 +76,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; | |||
| }; | |||
| @@ -130,11 +137,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; | |||
| @@ -154,6 +163,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; | |||