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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user