| 330 | } |
| 331 | |
| 332 | void PulseAudioInput::InputThread() { |
| 333 | try { |
| 334 | |
| 335 | Logger::LogInfo("[PulseAudioInput::InputThread] " + Logger::tr("Input thread started.")); |
| 336 | |
| 337 | std::vector<uint8_t> buffer; |
| 338 | bool has_first_samples = false; |
| 339 | int64_t first_timestamp = 0; // value won't be used, but GCC gives a warning otherwise |
| 340 | |
| 341 | while(!m_should_stop) { |
| 342 | |
| 343 | PulseAudioIterate(m_pa_mainloop); |
| 344 | |
| 345 | // try to read samples |
| 346 | const void *data; |
| 347 | size_t bytes; |
| 348 | if(pa_stream_peek(m_pa_stream, &data, &bytes) < 0) { |
| 349 | Logger::LogError("[PulseAudioInput::InputThread] " + Logger::tr("Error: pa_stream_peek failed!", "Don't translate 'pa_stream_peek'")); |
| 350 | throw PulseAudioException(); |
| 351 | } |
| 352 | if(data == NULL) { |
| 353 | if(bytes > 0) { |
| 354 | // skip hole |
| 355 | PushAudioHole(); |
| 356 | pa_stream_drop(m_pa_stream); |
| 357 | } |
| 358 | } else { |
| 359 | |
| 360 | // deal with half samples from the last peek (I don't think this will ever happen, but just in case ...) |
| 361 | unsigned int samples = (buffer.size() + bytes) / (m_channels * 2); |
| 362 | unsigned int bytes_left = (buffer.size() + bytes) % (m_channels * 2); |
| 363 | uint8_t *push_data; |
| 364 | if(buffer.size() > 0) { |
| 365 | size_t p = buffer.size(); |
| 366 | buffer.resize(p + bytes - bytes_left); |
| 367 | memcpy(buffer.data() + p, data, bytes - bytes_left); |
| 368 | push_data = buffer.data(); |
| 369 | } else { |
| 370 | push_data = (uint8_t*) data; |
| 371 | } |
| 372 | |
| 373 | int64_t timestamp = hrt_time_micro(); |
| 374 | |
| 375 | // skip the first samples |
| 376 | if(has_first_samples) { |
| 377 | if(timestamp > first_timestamp + START_DELAY) { |
| 378 | |
| 379 | // get the latency |
| 380 | // The latency can be negative for monitors, this means that we got the samples before they were actually played. |
| 381 | // But for some reason, PulseAudio doesn't like signed integers ... |
| 382 | /*pa_usec_t latency_magnitude; |
| 383 | int latency_negative; |
| 384 | pa_stream_get_latency(m_pa_stream, &latency_magnitude, &latency_negative); |
| 385 | int64_t latency = (latency_negative)? -(int64_t) latency_magnitude : latency_magnitude;*/ |
| 386 | |
| 387 | // push the samples |
| 388 | /*int64_t time = timestamp - latency;*/ |
| 389 | int64_t time = timestamp; |
nothing calls this directly
no test coverage detected