| @@ -1 +1 @@ | |||||
| Subproject commit b7066201022a757cbcbd986d8c91d565e4daef90 | |||||
| Subproject commit 383f24f6ed41facf25eda0d32b0f6bc9aee96e53 | |||||
| @@ -1,13 +1,11 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "bridgeprotocol.hpp" | |||||
| #include "audio.hpp" | #include "audio.hpp" | ||||
| namespace rack { | namespace rack { | ||||
| static const int BRIDGE_NUM_PORTS = 16; | |||||
| void bridgeInit(); | void bridgeInit(); | ||||
| void bridgeDestroy(); | void bridgeDestroy(); | ||||
| void bridgeAudioSubscribe(int channel, AudioIO *audio); | void bridgeAudioSubscribe(int channel, AudioIO *audio); | ||||
| @@ -0,0 +1,62 @@ | |||||
| #pragma once | |||||
| namespace rack { | |||||
| static const int BRIDGE_NUM_PORTS = 16; | |||||
| // A random number which prevents connection from other protocols and old Bridge versions | |||||
| const int BRIDGE_HELLO = 0xff00fefd; | |||||
| /** All commands are called from the client and served by the server | |||||
| send | |||||
| - uint8_t cmd | |||||
| */ | |||||
| enum BridgeCommand { | |||||
| NO_COMMAND = 0, | |||||
| /** Initial state of the state machine. The client should not send the command number itself, just its arguments. | |||||
| send | |||||
| - uint32_t hello | |||||
| */ | |||||
| START_COMMAND, | |||||
| /** Requests the server to shut down the client */ | |||||
| QUIT_COMMAND, | |||||
| /** Sets the port | |||||
| send | |||||
| - uint8_t port | |||||
| */ | |||||
| PORT_SET_COMMAND, | |||||
| /** Sends a 3-byte MIDI command | |||||
| send | |||||
| - uint8_t msg[3] | |||||
| */ | |||||
| MIDI_MESSAGE_SEND_COMMAND, | |||||
| /** Sets the audio sample rate | |||||
| send | |||||
| - uint32_t sampleRate | |||||
| */ | |||||
| AUDIO_SAMPLE_RATE_SET_COMMAND, | |||||
| /** Sets the number of audio channels | |||||
| Currently not supported, hard-coded at 2. | |||||
| send | |||||
| - uint8_t channels | |||||
| */ | |||||
| AUDIO_CHANNELS_SET_COMMAND, | |||||
| /** Sends and receives an audio buffer | |||||
| send | |||||
| - uint32_t length | |||||
| - float input[n] | |||||
| recv | |||||
| - float output[n] | |||||
| */ | |||||
| AUDIO_PROCESS_COMMAND, | |||||
| /** Resumes the audio buffer, forcing Rack to wait on an audio buffer */ | |||||
| AUDIO_ACTIVATE, | |||||
| /** Pauses the audio buffer, allowing Rack to not wait on an audio buffer */ | |||||
| AUDIO_DEACTIVATE, | |||||
| NUM_COMMANDS | |||||
| }; | |||||
| } // namespace rack | |||||
| @@ -206,7 +206,7 @@ void AudioIO::openStream() { | |||||
| setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | ||||
| if (numOutputs == 0 && numInputs == 0) { | if (numOutputs == 0 && numInputs == 0) { | ||||
| warn("RtAudio device %d has 0 inputs and 0 outputs"); | |||||
| warn("RtAudio device %d has 0 inputs and 0 outputs", device); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -21,21 +21,6 @@ | |||||
| namespace rack { | namespace rack { | ||||
| enum BridgeCommand { | |||||
| NO_COMMAND = 0, | |||||
| START_COMMAND, | |||||
| QUIT_COMMAND, | |||||
| PORT_SET_COMMAND, | |||||
| MIDI_MESSAGE_SEND_COMMAND, | |||||
| AUDIO_SAMPLE_RATE_SET_COMMAND, | |||||
| AUDIO_CHANNELS_SET_COMMAND, | |||||
| AUDIO_BUFFER_SEND_COMMAND, | |||||
| AUDIO_ACTIVATE, | |||||
| AUDIO_DEACTIVATE, | |||||
| NUM_COMMANDS | |||||
| }; | |||||
| static const int RECV_BUFFER_SIZE = (1<<13); | static const int RECV_BUFFER_SIZE = (1<<13); | ||||
| static const int RECV_QUEUE_SIZE = (1<<17); | static const int RECV_QUEUE_SIZE = (1<<17); | ||||
| @@ -192,7 +177,7 @@ struct BridgeClientConnection { | |||||
| } | } | ||||
| } break; | } break; | ||||
| case AUDIO_BUFFER_SEND_COMMAND: { | |||||
| case AUDIO_PROCESS_COMMAND: { | |||||
| if (audioBufferLength < 0) { | if (audioBufferLength < 0) { | ||||
| // Get audio buffer size | // Get audio buffer size | ||||
| if (recvQueue.size() >= 4) { | if (recvQueue.size() >= 4) { | ||||
| @@ -216,8 +201,6 @@ struct BridgeClientConnection { | |||||
| float output[audioBufferLength]; | float output[audioBufferLength]; | ||||
| processStream(input, output, frames); | processStream(input, output, frames); | ||||
| // Send output buffer | // Send output buffer | ||||
| send<uint8_t>(AUDIO_BUFFER_SEND_COMMAND); | |||||
| send<uint32_t>(audioBufferLength); | |||||
| send((uint8_t*) output, audioBufferLength * sizeof(float)); | send((uint8_t*) output, audioBufferLength * sizeof(float)); | ||||
| audioBufferLength = -1; | audioBufferLength = -1; | ||||
| @@ -268,7 +268,7 @@ static bool syncPlugin(json_t *pluginJ, bool dryRun) { | |||||
| std::string zipPath = pluginPath + ".zip"; | std::string zipPath = pluginPath + ".zip"; | ||||
| bool success = requestDownload(download, zipPath, &downloadProgress); | bool success = requestDownload(download, zipPath, &downloadProgress); | ||||
| if (!success) { | if (!success) { | ||||
| warn("Plugin %s download was unsuccessful"); | |||||
| warn("Plugin %s download was unsuccessful", slug.c_str()); | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -547,9 +547,9 @@ void windowSetTheme(NVGcolor bg, NVGcolor fg) { | |||||
| // Assume dark background and light foreground | // Assume dark background and light foreground | ||||
| BNDwidgetTheme w; | BNDwidgetTheme w; | ||||
| w.outlineColor = bg; | |||||
| w.outlineColor = colorMinus(bg, nvgRGB(0x10, 0x10, 0x10)); | |||||
| w.itemColor = fg; | w.itemColor = fg; | ||||
| w.innerColor = bg; | |||||
| w.innerColor = colorMinus(bg, nvgRGB(0x10, 0x10, 0x10)); | |||||
| w.innerSelectedColor = colorPlus(bg, nvgRGB(0x30, 0x30, 0x30)); | w.innerSelectedColor = colorPlus(bg, nvgRGB(0x30, 0x30, 0x30)); | ||||
| w.textColor = fg; | w.textColor = fg; | ||||
| w.textSelectedColor = fg; | w.textSelectedColor = fg; | ||||
| @@ -571,7 +571,7 @@ void windowSetTheme(NVGcolor bg, NVGcolor fg) { | |||||
| t.menuTheme = w; | t.menuTheme = w; | ||||
| t.menuItemTheme = w; | t.menuItemTheme = w; | ||||
| t.sliderTheme.itemColor = bg; | |||||
| t.sliderTheme.itemColor = colorMinus(bg, nvgRGB(0x10, 0x10, 0x10)); | |||||
| t.sliderTheme.innerColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | t.sliderTheme.innerColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | ||||
| t.sliderTheme.innerSelectedColor = colorPlus(bg, nvgRGB(0x60, 0x60, 0x60)); | t.sliderTheme.innerSelectedColor = colorPlus(bg, nvgRGB(0x60, 0x60, 0x60)); | ||||