diff --git a/include/EventQueue.hpp b/include/EventQueue.hpp index 236b878..e06fbee 100644 --- a/include/EventQueue.hpp +++ b/include/EventQueue.hpp @@ -24,7 +24,7 @@ template class EventQueue { public: - EventQueue (uint8_t* startAddress, unsigned int sizeInBytes) : + EventQueue (uint8_t* startAddress, unsigned int sizeInBytes, unsigned int semNum = 0) : m_StartAddress( startAddress ), m_SizeInBytes( sizeInBytes ), m_SizeOfEvent( sizeof(T) ), @@ -32,7 +32,7 @@ class EventQueue m_ReadIndex( 0 ), m_WriteIndex( 0 ), m_NumUnread( 0 ), - m_Mutex() + m_Mutex( semNum ) { } diff --git a/include/Mutex.hpp b/include/Mutex.hpp index 13b66c2..841fb21 100644 --- a/include/Mutex.hpp +++ b/include/Mutex.hpp @@ -16,7 +16,7 @@ class Mutex { public: - Mutex() : m_Mutex() {} + Mutex (unsigned int semNum) : m_Mutex() {} ~Mutex() {} bool tryLock() { return m_Mutex.try_lock(); } @@ -32,17 +32,18 @@ class Mutex #include "LLPD.hpp" -#define SEMAPHORE_NUM 1 - class Mutex { public: - Mutex() {} + Mutex (unsigned int semNum) : m_SemaphoreNumber( semNum ) {} ~Mutex() {} - bool tryLock() { return LLPD::hsem_try_take( SEMAPHORE_NUM ); } + bool tryLock() { return LLPD::hsem_try_take( m_SemaphoreNumber ); } + + void unlock() { LLPD::hsem_release( m_SemaphoreNumber ); } - void unlock() { LLPD::hsem_release( SEMAPHORE_NUM ); } + private: + unsigned int m_SemaphoreNumber; }; #endif // #ifndef TARGET_BUILD diff --git a/src/ARMor8VoiceManager.cpp b/src/ARMor8VoiceManager.cpp index 5878e25..798d9bb 100644 --- a/src/ARMor8VoiceManager.cpp +++ b/src/ARMor8VoiceManager.cpp @@ -514,31 +514,43 @@ void ARMor8VoiceManager::onARMor8ParameterEvent (const ARMor8ParameterEvent& par break; case PARAM_CHANNEL::SELECT_OPERATOR: // refresh screen with new operator values - IARMor8PresetEventListener::PublishEvent( - ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + if ( m_PresetManager ) + { + IARMor8PresetEventListener::PublishEvent( + ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + } break; case PARAM_CHANNEL::NEXT_PRESET: { - ARMor8VoiceState preset = m_PresetManager->nextPreset(); - this->setState( preset ); - IARMor8PresetEventListener::PublishEvent( - ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + if ( m_PresetManager ) + { + ARMor8VoiceState preset = m_PresetManager->nextPreset(); + this->setState( preset ); + IARMor8PresetEventListener::PublishEvent( + ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + } } break; case PARAM_CHANNEL::PREV_PRESET: { - ARMor8VoiceState preset = m_PresetManager->prevPreset(); - this->setState( preset ); - IARMor8PresetEventListener::PublishEvent( - ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + if ( m_PresetManager ) + { + ARMor8VoiceState preset = m_PresetManager->prevPreset(); + this->setState( preset ); + IARMor8PresetEventListener::PublishEvent( + ARMor8PresetEvent(this->getState(), m_PresetManager->getCurrentPresetNum(), 0) ); + } } break; case PARAM_CHANNEL::WRITE_PRESET: { - ARMor8VoiceState presetToWrite = this->getState(); - m_PresetManager->writePreset( presetToWrite, m_PresetManager->getCurrentPresetNum() ); + if ( m_PresetManager ) + { + ARMor8VoiceState presetToWrite = this->getState(); + m_PresetManager->writePreset( presetToWrite, m_PresetManager->getCurrentPresetNum() ); + } } break; diff --git a/target/CM4/main.cpp b/target/CM4/main.cpp index c35c1c8..362a9af 100644 --- a/target/CM4/main.cpp +++ b/target/CM4/main.cpp @@ -5,6 +5,7 @@ #include "OLED_SH1106.hpp" #include "ARMor8UiManager.hpp" #include "IARMor8LCDRefreshEventListener.hpp" +#include "IARMor8ParameterEventListener.hpp" #include "FrameBuffer.hpp" #include "Font.hpp" #include "Smoll.h" @@ -99,11 +100,26 @@ class Oled_Manager : public IARMor8LCDRefreshEventListener uint8_t* m_DisplayBuffer; }; +class ARMor8ParameterEventBridge : public IARMor8ParameterEventListener +{ + public: + ARMor8ParameterEventBridge (EventQueue* eventQueuePtr) : m_EventQueuePtr( eventQueuePtr ) {} + ~ARMor8ParameterEventBridge() override {} + + void onARMor8ParameterEvent (const ARMor8ParameterEvent& paramEvent) override + { + m_EventQueuePtr->writeEvent( paramEvent ); + } + + private: + EventQueue* m_EventQueuePtr; +}; + int main(void) { LLPD::rcc_clock_start_max_cpu2(); - EventQueue* eventQueue = nullptr; + EventQueue* paramEventQueue = nullptr; // wait for setupCompleteFlag to inform that audio timer is setup while ( true ) @@ -115,7 +131,9 @@ int main(void) { uint8_t* sram4Ptr = reinterpret_cast( D3_SRAM_BASE ) + ( D3_SRAM_UNUSED_OFFSET_IN_BYTES ); - eventQueue = new ( sram4Ptr ) EventQueue( sram4Ptr + sizeof(EventQueue), sizeof(IEvent) * 100 ); + paramEventQueue = new ( sram4Ptr ) EventQueue( + sram4Ptr + sizeof(EventQueue), + sizeof(ARMor8ParameterEvent) * 1000, 1 ); *setupCompleteFlag = false; @@ -128,28 +146,6 @@ int main(void) } } - /* - // display buffer - uint8_t displayBuffer[(SH1106_LCDWIDTH * SH1106_LCDHEIGHT) / 8] = { 0 }; - - // fill display buffer - for ( unsigned int byte = 0; byte < (SH1106_LCDHEIGHT * SH1106_LCDWIDTH) / 8; byte++ ) - { - displayBuffer[byte] = 0xFF; - } - - // OLED setup - LLPD::gpio_output_setup( OLED_PORT, OLED_CS_PIN, GPIO_PUPD::NONE, GPIO_OUTPUT_TYPE::PUSH_PULL, GPIO_OUTPUT_SPEED::HIGH, false ); - LLPD::gpio_output_set( OLED_PORT, OLED_CS_PIN, true ); - LLPD::gpio_output_setup( OLED_PORT, OLED_DC_PIN, GPIO_PUPD::NONE, GPIO_OUTPUT_TYPE::PUSH_PULL, GPIO_OUTPUT_SPEED::HIGH, false ); - LLPD::gpio_output_set( OLED_PORT, OLED_DC_PIN, true ); - LLPD::gpio_output_setup( OLED_PORT, OLED_RESET_PIN, GPIO_PUPD::NONE, GPIO_OUTPUT_TYPE::PUSH_PULL, GPIO_OUTPUT_SPEED::HIGH, false ); - LLPD::gpio_output_set( OLED_PORT, OLED_RESET_PIN, true ); - Oled_SH1106 oled( OLED_SPI_NUM, OLED_PORT, OLED_CS_PIN, OLED_PORT, OLED_DC_PIN, OLED_PORT, OLED_RESET_PIN ); - oled.begin(); - oled.displayFullRowMajor( displayBuffer ); - */ - // UI manager setup Font font( Smoll_data ); ARMor8UiManager uiManager( SH1106_LCDWIDTH, SH1106_LCDHEIGHT, CP_FORMAT::MONOCHROME_1BIT ); @@ -159,6 +155,10 @@ int main(void) uiManagerPtr = &uiManager; uiManager.endLoading(); + // parameter event bridge setup + ARMor8ParameterEventBridge paramEventBride( paramEventQueue ); + paramEventBride.bindToARMor8ParameterEventSystem(); + // OLED setup Oled_Manager oled( uiManager.getFrameBuffer()->getPixels() ); @@ -183,8 +183,5 @@ int main(void) uint16_t effect3Val = LLPD::adc_get_channel_value( EFFECT_ADC_NUM, EFFECT3_ADC_CHANNEL ); float effect3Percentage = static_cast( effect3Val ) * ( 1.0f / 4095.0f ); IPotEventListener::PublishEvent( PotEvent(effect3Percentage, static_cast(POT_CHANNEL::EFFECT3)) ); - - IEvent iEvent( effect1Val ); - eventQueue->writeEvent( iEvent ); } } diff --git a/target/CM4/main_release.bin b/target/CM4/main_release.bin deleted file mode 100755 index adfaecb..0000000 Binary files a/target/CM4/main_release.bin and /dev/null differ diff --git a/target/CM4/main_release.elf b/target/CM4/main_release.elf deleted file mode 100755 index 7482f83..0000000 Binary files a/target/CM4/main_release.elf and /dev/null differ diff --git a/target/CM4/main_release.o b/target/CM4/main_release.o deleted file mode 100644 index 9a0d618..0000000 Binary files a/target/CM4/main_release.o and /dev/null differ diff --git a/target/CM7/main.cpp b/target/CM7/main.cpp index 3793fe9..e5ff85e 100644 --- a/target/CM7/main.cpp +++ b/target/CM7/main.cpp @@ -6,12 +6,14 @@ #include "EventQueue.hpp" #include "IEventListener.hpp" #include "MidiHandler.hpp" +#include "ARMor8VoiceManager.hpp" +#include "AudioBuffer.hpp" #define SYS_CLOCK_FREQUENCY = 480000000; // global variables -volatile bool adcSetupComplete = false; // should be set to true after adc has been initialized MidiHandler* volatile midiHandlerPtr = nullptr; +AudioBuffer* volatile audioBufferPtr = nullptr; // peripheral defines #define OP_AMP1_INV_OUT_PORT GPIO_PORT::C @@ -62,29 +64,27 @@ MidiHandler* volatile midiHandlerPtr = nullptr; #define SD_CARD_SPI_NUM SPI_NUM::SPI_4 #define OLED_SPI_NUM SPI_NUM::SPI_3 -// TODO delete this after testing -#include "IKeyEventListener.hpp" - -class KeyEventTester : public IKeyEventListener +class ARMor8ParameterEventBridge { public: - KeyEventTester() {} - ~KeyEventTester() override {} + ARMor8ParameterEventBridge (EventQueue* eventQueuePtr) : m_EventQueuePtr( eventQueuePtr ) {} + ~ARMor8ParameterEventBridge() {} - void onKeyEvent (const KeyEvent& keyEvent) override + void processQueuedParameterEvents() { - if ( keyEvent.pressed() == KeyPressedEnum::PRESSED ) - { - LLPD::usart_log_int( LOGGING_USART_NUM, "Key pressed: ", keyEvent.note() ); - } - else if ( keyEvent.pressed() == KeyPressedEnum::RELEASED ) + ARMor8ParameterEvent paramEvent( 0.0f, 0, 0 ); + bool readCorrectly = m_EventQueuePtr->readEvent( paramEvent ); + while ( readCorrectly ) { - LLPD::usart_log_int( LOGGING_USART_NUM, "Key released: ", keyEvent.note() ); + IARMor8ParameterEventListener::PublishEvent( paramEvent ); + + readCorrectly = m_EventQueuePtr->readEvent( paramEvent ); } } -}; - + private: + EventQueue* m_EventQueuePtr; +}; // these pins are unconnected on Ultra_FX_SYN Rev 2 development board, so we disable them as per the ST recommendations void disableUnusedPins() @@ -272,13 +272,12 @@ int main(void) LLPD::gpio_analog_setup( EFFECT_ADC_PORT, EFFECT1_ADC_PIN ); LLPD::gpio_analog_setup( EFFECT_ADC_PORT, EFFECT2_ADC_PIN ); LLPD::gpio_analog_setup( EFFECT_ADC_PORT, EFFECT3_ADC_PIN ); - LLPD::gpio_analog_setup( AUDIO_IN_PORT, AUDIO1_IN_PIN ); - LLPD::gpio_analog_setup( AUDIO_IN_PORT, AUDIO2_IN_PIN ); + // LLPD::gpio_analog_setup( AUDIO_IN_PORT, AUDIO1_IN_PIN ); + // LLPD::gpio_analog_setup( AUDIO_IN_PORT, AUDIO2_IN_PIN ); LLPD::adc_init( ADC_NUM::ADC_1_2, ADC_CYCLES_PER_SAMPLE::CPS_64p5 ); - LLPD::adc_init( ADC_NUM::ADC_3, ADC_CYCLES_PER_SAMPLE::CPS_32p5 ); + // LLPD::adc_init( ADC_NUM::ADC_3, ADC_CYCLES_PER_SAMPLE::CPS_32p5 ); LLPD::adc_set_channel_order( ADC_NUM::ADC_1_2, 3, EFFECT1_ADC_CHANNEL, EFFECT2_ADC_CHANNEL, EFFECT3_ADC_CHANNEL ); - LLPD::adc_set_channel_order( ADC_NUM::ADC_3, 2, AUDIO1_IN_ADC_CHANNEL, AUDIO2_IN_ADC_CHANNEL ); - adcSetupComplete = true; + // LLPD::adc_set_channel_order( ADC_NUM::ADC_3, 2, AUDIO1_IN_ADC_CHANNEL, AUDIO2_IN_ADC_CHANNEL ); // pushbutton setup LLPD::gpio_digital_input_setup( EFFECT_BUTTON_PORT, EFFECT1_BUTTON_PIN, GPIO_PUPD::PULL_UP ); @@ -365,25 +364,29 @@ int main(void) } } - // TODO for testing, delete later - uint8_t* eventQueueMem = reinterpret_cast( D3_SRAM_BASE ) + ( D3_SRAM_UNUSED_OFFSET_IN_BYTES ); - EventQueue* eventQueue = reinterpret_cast*>( eventQueueMem ); - KeyEventTester keyEventTester; - keyEventTester.bindToKeyEventSystem(); + uint8_t* paramEventQueueMem = reinterpret_cast( D3_SRAM_BASE ) + ( D3_SRAM_UNUSED_OFFSET_IN_BYTES ); + EventQueue* paramEventQueue = reinterpret_cast*>( paramEventQueueMem ); + ARMor8ParameterEventBridge paramEventBridge( paramEventQueue ); + + // TODO need to add preset manager + ARMor8VoiceManager voiceManager( midiHandlerPtr, nullptr ); + voiceManager.bindToKeyEventSystem(); + voiceManager.bindToPitchEventSystem(); + voiceManager.bindToARMor8ParameterEventSystem(); + + AudioBuffer audioBuffer; + audioBuffer.registerCallback( &voiceManager ); + audioBufferPtr = &audioBuffer; while ( true ) { LLPD::adc_perform_conversion_sequence( EFFECT_ADC_NUM ); - // TODO testing stuff, remove later - IEvent iEvent( 0 ); - bool readCorrectly = eventQueue->readEvent( iEvent ); - if ( readCorrectly ) - { - // LLPD::usart_log_int( LOGGING_USART_NUM, "Got event! Event Number: ", iEvent.getChannel() ); - } + paramEventBridge.processQueuedParameterEvents(); midiHandler.dispatchEvents(); + + audioBuffer.pollToFillBuffers(); } } @@ -391,12 +394,11 @@ extern "C" void TIM6_DAC_IRQHandler (void) { if ( ! LLPD::tim6_isr_handle_delay() ) // if not currently in a delay function,... { - if ( adcSetupComplete ) + if ( audioBufferPtr ) { - LLPD::adc_perform_conversion_sequence( AUDIO_IN_ADC_NUM ); - uint16_t audioIn1 = LLPD::adc_get_channel_value( AUDIO_IN_ADC_NUM, AUDIO1_IN_ADC_CHANNEL ); - uint16_t audioIn2 = LLPD::adc_get_channel_value( AUDIO_IN_ADC_NUM, AUDIO2_IN_ADC_CHANNEL ); - LLPD::dac_send( audioIn1, audioIn2 ); + uint16_t outVal = static_cast( audioBufferPtr->getNextSample(0.0f) * 4095.0f ); + + LLPD::dac_send( outVal, outVal ); } }