25#if defined(H2CORE_HAVE_PULSEAUDIO) || _DOXYGEN_
44 pthread_mutex_init(&
m_mutex,
nullptr);
45 pthread_cond_init(&
m_cond,
nullptr);
51 pthread_cond_destroy(&
m_cond);
52 pthread_mutex_destroy(&
m_mutex);
82 fcntl(
m_pipe[0], F_SETFL, fcntl(
m_pipe[0], F_GETFL) | O_NONBLOCK);
89 ERRORLOG(
"unable to start thread." );
104 ERRORLOG( QString(
"unable to run driver. Main loop returned %1" ).arg(
m_ready ) );
118 while (write(
m_pipe[1], &junk, 1) != 1) {
157 pthread_mutex_lock(&self->
m_mutex);
159 pthread_cond_signal(&self->
m_cond);
160 pthread_mutex_unlock(&self->
m_mutex);
170 pa_mainloop_api* api = pa_mainloop_get_api(
m_main_loop);
171 pa_io_event* ioev = api->io_new(api,
m_pipe[0], PA_IO_EVENT_INPUT,
173 m_ctx = pa_context_new(api,
"Hydrogen");
175 pa_context_connect(
m_ctx,
nullptr, pa_context_flags_t(0),
nullptr);
182 pa_stream_set_state_callback(
m_stream,
nullptr,
nullptr);
183 pa_stream_set_write_callback(
m_stream,
nullptr,
nullptr);
189 pa_context_unref(
m_ctx);
199 pa_context_state s = pa_context_get_state(ctx);
201 if (s == PA_CONTEXT_READY) {
203 spec.format = PA_SAMPLE_S16LE;
206 self->
m_stream = pa_stream_new(ctx,
"Hydrogen", &spec,
nullptr);
209 pa_buffer_attr bufattr;
210 bufattr.fragsize = (uint32_t)-1;
213 bufattr.prebuf = (uint32_t)-1;
215 pa_stream_connect_playback(self->
m_stream,
nullptr, &bufattr, pa_stream_flags_t(0),
nullptr,
nullptr);
217 else if (s == PA_CONTEXT_FAILED) {
226 pa_stream_state s = pa_stream_get_state(stream);
228 if ( s == PA_STREAM_FAILED ) {
230 }
else if ( s == PA_STREAM_READY ) {
231 pthread_mutex_lock(&self->
m_mutex);
233 pthread_cond_signal(&self->
m_cond);
234 pthread_mutex_unlock(&self->
m_mutex);
238#define FLOAT_TO_SHORT(x) short(round((std::min(std::max((x), -1.0f), 1.0f)) * 32767.0f))
245 pa_stream_begin_write(stream, &vdata, &bytes);
248 short* out = (
short*)vdata;
250 unsigned num_samples = bytes / 4;
256 for (
int i = 0; i < n; ++i)
265 pa_stream_write(stream, vdata, (bytes / 4) * 4,
nullptr, 0, PA_SEEK_RELATIVE);
270 pa_io_event_flags_t events,
void *udata)
272 if (!(events & PA_IO_EVENT_INPUT)) {
277 int bytes = read(fd, buf, 16);
#define FLOAT_TO_SHORT(x)
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
unsigned m_nSampleRate
Sample rate of the audio.
virtual void disconnect() override
virtual float * getOut_L() override
pa_mainloop * m_main_loop
virtual int init(unsigned nBufferSize) override
static void ctx_state_callback(pa_context *ctx, void *udata)
static void stream_write_callback(pa_stream *stream, size_t bytes, void *udata)
static void pipe_callback(pa_mainloop_api *, pa_io_event *, int fd, pa_io_event_flags_t events, void *udata)
audioProcessCallback m_callback
static void stream_state_callback(pa_stream *stream, void *udata)
static void * s_thread_body(void *)
virtual float * getOut_R() override
virtual unsigned getBufferSize() override
virtual int connect() override
PulseAudioDriver(audioProcessCallback processCallback)
int m_pipe[2]
File descriptors used to write data to (m_pipe[1]) and read data from (m_pipe[0]) the pipe.
virtual unsigned getSampleRate() override
int(* audioProcessCallback)(uint32_t, void *)