void AudioDriverPulseAudio::thread_func(void* p_udata) { print_line("thread"); AudioDriverPulseAudio* ad = (AudioDriverPulseAudio*)p_udata; while (!ad->exit_thread) { if (!ad->active) { for (unsigned int i=0; i < ad->buffer_size * ad->channels; i++) { ad->samples_out[i] = 0; } } else { ad->lock(); ad->audio_server_process(ad->buffer_size, ad->samples_in); ad->unlock(); for (unsigned int i=0; i < ad->buffer_size * ad->channels;i ++) { ad->samples_out[i] = ad->samples_in[i] >> 16; } } // pa_simple_write always consumes the entire buffer int error_code; int byte_size = ad->buffer_size * sizeof(int16_t) * ad->channels; if (pa_simple_write(ad->pulse, ad->samples_out, byte_size, &error_code) < 0) { // can't recover here fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code)); ad->active = false; ad->exit_thread = true; break; } } ad->thread_exited = true; }
void AudioDriverPulseAudio::thread_func(void *p_udata) { AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)p_udata; unsigned int write_ofs = 0; size_t avail_bytes = 0; while (!ad->exit_thread) { size_t read_bytes = 0; size_t written_bytes = 0; if (avail_bytes == 0) { ad->lock(); ad->start_counting_ticks(); if (!ad->active) { for (unsigned int i = 0; i < ad->pa_buffer_size; i++) { ad->samples_out.write[i] = 0; } } else { ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw()); if (ad->channels == ad->pa_map.channels) { for (unsigned int i = 0; i < ad->pa_buffer_size; i++) { ad->samples_out.write[i] = ad->samples_in[i] >> 16; } } else { // Uneven amount of channels unsigned int in_idx = 0; unsigned int out_idx = 0; for (unsigned int i = 0; i < ad->buffer_frames; i++) { for (int j = 0; j < ad->pa_map.channels - 1; j++) { ad->samples_out.write[out_idx++] = ad->samples_in[in_idx++] >> 16; } uint32_t l = ad->samples_in[in_idx++] >> 16; uint32_t r = ad->samples_in[in_idx++] >> 16; ad->samples_out.write[out_idx++] = (l + r) / 2; } } } avail_bytes = ad->pa_buffer_size * sizeof(int16_t); write_ofs = 0; ad->stop_counting_ticks(); ad->unlock(); }