@@ -99,15 +99,15 @@ struct Device { | |||
/** Returns a list of all valid (user-selectable) sample rates. | |||
The device may accept sample rates not in this list, but it *must* accept sample rates in the list. | |||
*/ | |||
virtual std::set<int> getSampleRates() { | |||
virtual std::set<float> getSampleRates() { | |||
return {}; | |||
} | |||
/** Returns the current sample rate. */ | |||
virtual int getSampleRate() { | |||
virtual float getSampleRate() { | |||
return 0; | |||
} | |||
/** Sets the sample rate of the device, re-opening it if needed. */ | |||
virtual void setSampleRate(int sampleRate) {} | |||
virtual void setSampleRate(float sampleRate) {} | |||
/** Returns a list of all valid (user-selectable) block sizes. | |||
The device may accept block sizes not in this list, but it *must* accept block sizes in the list. | |||
@@ -169,9 +169,9 @@ struct Port { | |||
std::string getDeviceName(int deviceId); | |||
std::string getDeviceDetail(int deviceId, int offset); | |||
std::set<int> getSampleRates(); | |||
int getSampleRate(); | |||
void setSampleRate(int sampleRate); | |||
std::set<float> getSampleRates(); | |||
float getSampleRate(); | |||
void setSampleRate(float sampleRate); | |||
std::set<int> getBlockSizes(); | |||
int getBlockSize(); | |||
@@ -144,7 +144,7 @@ struct AudioDeviceItem : ui::MenuItem { | |||
struct AudioSampleRateValueItem : ui::MenuItem { | |||
audio::Port* port; | |||
int sampleRate; | |||
float sampleRate; | |||
void onAction(const event::Action& e) override { | |||
port->setSampleRate(sampleRate); | |||
} | |||
@@ -154,14 +154,14 @@ static void appendAudioSampleRateMenu(ui::Menu* menu, audio::Port* port) { | |||
if (!port) | |||
return; | |||
std::set<int> sampleRates = port->getSampleRates(); | |||
std::set<float> sampleRates = port->getSampleRates(); | |||
// Add current sample rate in case it's not in the list | |||
sampleRates.insert(port->getSampleRate()); | |||
if (sampleRates.empty()) { | |||
menu->addChild(createMenuLabel("(Locked by device)")); | |||
} | |||
for (int sampleRate : sampleRates) { | |||
for (float sampleRate : sampleRates) { | |||
if (sampleRate <= 0) | |||
continue; | |||
AudioSampleRateValueItem* item = new AudioSampleRateValueItem; | |||
@@ -184,9 +184,9 @@ struct AudioSampleRateChoice : LedDisplayChoice { | |||
text = ""; | |||
if (box.size.x >= 100.0) | |||
text += "Rate: "; | |||
int sampleRate = port ? port->getSampleRate() : 0; | |||
float sampleRate = port ? port->getSampleRate() : 0; | |||
if (sampleRate > 0) { | |||
text += string::f("%g", sampleRate / 1000.0); | |||
text += string::f("%g", sampleRate / 1000.f); | |||
color.a = 1.0; | |||
} | |||
else { | |||
@@ -242,7 +242,7 @@ std::string Port::getDeviceDetail(int deviceId, int offset) { | |||
} | |||
} | |||
std::set<int> Port::getSampleRates() { | |||
std::set<float> Port::getSampleRates() { | |||
if (!device) | |||
return {}; | |||
try { | |||
@@ -254,7 +254,7 @@ std::set<int> Port::getSampleRates() { | |||
} | |||
} | |||
int Port::getSampleRate() { | |||
float Port::getSampleRate() { | |||
if (!device) | |||
return 0; | |||
try { | |||
@@ -266,7 +266,7 @@ int Port::getSampleRate() { | |||
} | |||
} | |||
void Port::setSampleRate(int sampleRate) { | |||
void Port::setSampleRate(float sampleRate) { | |||
if (!device) | |||
return; | |||
try { | |||
@@ -345,7 +345,7 @@ json_t* Port::toJson() { | |||
json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str())); | |||
} | |||
json_object_set_new(rootJ, "sampleRate", json_integer(getSampleRate())); | |||
json_object_set_new(rootJ, "sampleRate", json_real(getSampleRate())); | |||
json_object_set_new(rootJ, "blockSize", json_integer(getBlockSize())); | |||
json_object_set_new(rootJ, "offset", json_integer(offset)); | |||
return rootJ; | |||
@@ -377,7 +377,7 @@ void Port::fromJson(json_t* rootJ) { | |||
json_t* sampleRateJ = json_object_get(rootJ, "sampleRate"); | |||
if (sampleRateJ) | |||
setSampleRate(json_integer_value(sampleRateJ)); | |||
setSampleRate(json_number_value(sampleRateJ)); | |||
json_t* blockSizeJ = json_object_get(rootJ, "blockSize"); | |||
if (blockSizeJ) | |||
@@ -205,7 +205,7 @@ struct AudioInterface : Module, audio::Port { | |||
// Initialize sample rate converters | |||
int numInputs = getNumInputs(); | |||
int engineSampleRate = (int) APP->engine->getSampleRate(); | |||
int sampleRate = getSampleRate(); | |||
float sampleRate = getSampleRate(); | |||
double sampleRateRatio = (double) engineSampleRate / sampleRate; | |||
outputSrc.setRates(sampleRate, engineSampleRate); | |||
outputSrc.setChannels(numInputs); | |||
@@ -253,7 +253,7 @@ struct AudioInterface : Module, audio::Port { | |||
bool isPrimary = (APP->engine->getPrimaryModule() == this); | |||
int numOutputs = getNumOutputs(); | |||
int engineSampleRate = (int) APP->engine->getSampleRate(); | |||
int sampleRate = getSampleRate(); | |||
float sampleRate = getSampleRate(); | |||
inputSrc.setRates(engineSampleRate, sampleRate); | |||
inputSrc.setChannels(numOutputs); | |||
@@ -19,14 +19,14 @@ namespace rack { | |||
struct RtAudioDevice : audio::Device { | |||
RtAudio *rtAudio; | |||
RtAudio* rtAudio; | |||
int deviceId; | |||
RtAudio::DeviceInfo deviceInfo; | |||
RtAudio::StreamParameters inputParameters; | |||
RtAudio::StreamParameters outputParameters; | |||
RtAudio::StreamOptions options; | |||
int blockSize = 0; | |||
int sampleRate = 44100; | |||
float sampleRate = 44100; | |||
RtAudioDevice(RtAudio::Api api, int deviceId) { | |||
rtAudio = new RtAudio(api); | |||
@@ -73,11 +73,11 @@ struct RtAudioDevice : audio::Device { | |||
options.numberOfBuffers = 2; | |||
options.streamName = "VCV Rack"; | |||
int closestSampleRate = deviceInfo.preferredSampleRate; | |||
float closestSampleRate = deviceInfo.preferredSampleRate; | |||
if (sampleRate > 0) { | |||
// Find the closest sample rate to the requested one. | |||
for (int sr : deviceInfo.sampleRates) { | |||
if (std::abs(sr - sampleRate) < std::abs(closestSampleRate - sampleRate)) { | |||
for (float sr : deviceInfo.sampleRates) { | |||
if (std::fabs(sr - sampleRate) < std::fabs(closestSampleRate - sampleRate)) { | |||
closestSampleRate = sr; | |||
} | |||
} | |||
@@ -87,7 +87,7 @@ struct RtAudioDevice : audio::Device { | |||
blockSize = 256; | |||
} | |||
INFO("Opening audio RtAudio device %d with %d in %d out, %d sample rate %d block size", deviceId, inputParameters.nChannels, outputParameters.nChannels, closestSampleRate, blockSize); | |||
INFO("Opening audio RtAudio device %d with %d in %d out, %f sample rate %d block size", deviceId, inputParameters.nChannels, outputParameters.nChannels, closestSampleRate, blockSize); | |||
try { | |||
rtAudio->openStream( | |||
outputParameters.nChannels > 0 ? &outputParameters : NULL, | |||
@@ -146,14 +146,14 @@ struct RtAudioDevice : audio::Device { | |||
return outputParameters.nChannels; | |||
} | |||
std::set<int> getSampleRates() override { | |||
std::set<int> sampleRates(deviceInfo.sampleRates.begin(), deviceInfo.sampleRates.end()); | |||
std::set<float> getSampleRates() override { | |||
std::set<float> sampleRates(deviceInfo.sampleRates.begin(), deviceInfo.sampleRates.end()); | |||
return sampleRates; | |||
} | |||
int getSampleRate() override { | |||
float getSampleRate() override { | |||
return sampleRate; | |||
} | |||
void setSampleRate(int sampleRate) override { | |||
void setSampleRate(float sampleRate) override { | |||
closeStream(); | |||
this->sampleRate = sampleRate; | |||
openStream(); | |||
@@ -190,7 +190,7 @@ struct RtAudioDevice : audio::Device { | |||
struct RtAudioDriver : audio::Driver { | |||
// Just for querying device IDs names | |||
RtAudio *rtAudio; | |||
RtAudio* rtAudio; | |||
// deviceId -> Device | |||
std::map<int, RtAudioDevice*> devices; | |||