Added automated channel detection for speaker devices
This commit is contained in:
parent
da07595337
commit
768e9b7bbb
@ -217,7 +217,10 @@ namespace tc::audio {
|
||||
|
||||
bool AudioDeviceRecord::start(std::string &error) {
|
||||
std::lock_guard lock{this->state_lock};
|
||||
if(this->running && !this->stream_invalid) return true;
|
||||
if(this->running && !this->stream_invalid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(this->stream_invalid) {
|
||||
this->impl_stop();
|
||||
this->running = false;
|
||||
|
@ -92,8 +92,9 @@ namespace tc::audio::pa {
|
||||
}
|
||||
|
||||
std::lock_guard lock{this->io_lock};
|
||||
if(!this->_playback)
|
||||
if(!this->_playback) {
|
||||
this->_playback = std::make_shared<PortAudioPlayback>(this->_index, this->_info);
|
||||
}
|
||||
return this->_playback;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ namespace tc::audio::pa {
|
||||
PaDeviceIndex index;
|
||||
const PaDeviceInfo* info;
|
||||
PaStream* stream{nullptr};
|
||||
|
||||
size_t source_channel_count{0};
|
||||
};
|
||||
|
||||
class PortAudioRecord : public AudioDeviceRecord {
|
||||
|
@ -32,7 +32,8 @@ bool PortAudioPlayback::impl_start(std::string &error) {
|
||||
unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData) {
|
||||
void *userData
|
||||
) {
|
||||
assert(output);
|
||||
|
||||
auto player = reinterpret_cast<PortAudioPlayback*>(userData);
|
||||
@ -44,10 +45,19 @@ bool PortAudioPlayback::impl_start(std::string &error) {
|
||||
|
||||
PaStreamParameters parameters{};
|
||||
memset(¶meters, 0, sizeof(parameters));
|
||||
parameters.channelCount = (int) kChannelCount;
|
||||
parameters.device = this->index;
|
||||
parameters.sampleFormat = paFloat32;
|
||||
parameters.suggestedLatency = this->info->defaultLowInputLatency;
|
||||
|
||||
if(this->info->maxOutputChannels < kChannelCount) {
|
||||
parameters.channelCount = (int) 1;
|
||||
this->source_channel_count = 1;
|
||||
} else {
|
||||
parameters.channelCount = (int) kChannelCount;
|
||||
this->source_channel_count = kChannelCount;
|
||||
}
|
||||
log_debug(category::audio, "Opening playback device {} (MaxChannels: {}, Channels: {})", this->info->name, this->info->maxOutputChannels, this->source_channel_count);
|
||||
|
||||
auto err = Pa_OpenStream(
|
||||
&this->stream,
|
||||
nullptr,
|
||||
@ -56,7 +66,8 @@ bool PortAudioPlayback::impl_start(std::string &error) {
|
||||
(unsigned long) (kSampleRate * kTimeSpan),
|
||||
paClipOff,
|
||||
proxied_write_callback,
|
||||
this);
|
||||
this
|
||||
);
|
||||
|
||||
if(err != paNoError) {
|
||||
this->stream = nullptr;
|
||||
@ -68,20 +79,23 @@ bool PortAudioPlayback::impl_start(std::string &error) {
|
||||
if(err != paNoError) {
|
||||
error = std::string{Pa_GetErrorText(err)} + "(start stream: " + std::to_string(err) + ")";
|
||||
err = Pa_CloseStream(this->stream);
|
||||
if(err != paNoError)
|
||||
if(err != paNoError) {
|
||||
log_critical(category::audio, tr("Failed to close opened pa stream. This will cause memory leaks. Error: {}/{}"), err, Pa_GetErrorText(err));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PortAudioPlayback::impl_stop() {
|
||||
if(Pa_IsStreamActive(this->stream))
|
||||
if(Pa_IsStreamActive(this->stream)) {
|
||||
Pa_AbortStream(this->stream);
|
||||
}
|
||||
|
||||
auto error = Pa_CloseStream(this->stream);
|
||||
if(error != paNoError)
|
||||
if(error != paNoError) {
|
||||
log_error(category::audio, tr("Failed to close PA stream: {}"), error);
|
||||
}
|
||||
this->stream = nullptr;
|
||||
}
|
||||
|
||||
@ -91,5 +105,5 @@ size_t PortAudioPlayback::sample_rate() const {
|
||||
|
||||
void PortAudioPlayback::write_callback(void *output, unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) {
|
||||
this->fill_buffer(output, frameCount, kChannelCount);
|
||||
this->fill_buffer(output, frameCount, this->source_channel_count);
|
||||
}
|
@ -49,7 +49,7 @@ bool PortAudioRecord::impl_start(std::string &error) {
|
||||
parameters.channelCount = (int) kChannelCount;
|
||||
this->source_channel_count = kChannelCount;
|
||||
}
|
||||
log_debug(category::audio, "Opening device {} (MaxChannels: {}, MinChannels: {}, Channels: {})", this->info->name, this->info->maxInputChannels, this->info->maxInputChannels, this->source_channel_count);
|
||||
log_debug(category::audio, "Opening record device {} (MaxChannels: {}, Channels: {})", this->info->name, this->info->maxInputChannels, this->source_channel_count);
|
||||
|
||||
parameters.device = this->index;
|
||||
parameters.sampleFormat = paFloat32;
|
||||
|
Loading…
Reference in New Issue
Block a user