summaryrefslogtreecommitdiff
path: root/plugins/dfsound/pulseaudio.c
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-02-07 10:33:30 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-02-07 10:33:30 +0000
commit7cf18befaa6309a60c5950b5f349204f267f88f4 (patch)
tree045b389bb8924dbf3c5fb28bb1be2e870f6cf241 /plugins/dfsound/pulseaudio.c
parent9bf85f976ca1c539788e6d1d60995434eb856812 (diff)
downloadpcsxr-7cf18befaa6309a60c5950b5f349204f267f88f4.tar.gz
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@41219 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfsound/pulseaudio.c')
-rw-r--r--plugins/dfsound/pulseaudio.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/plugins/dfsound/pulseaudio.c b/plugins/dfsound/pulseaudio.c
new file mode 100644
index 00000000..513af91c
--- /dev/null
+++ b/plugins/dfsound/pulseaudio.c
@@ -0,0 +1,242 @@
+/***************************************************************************
+ pulseaudio.c - description
+ -------------------
+begin : Thu Feb 04 2010
+copyright : (C) 2010 by Tristin Celestin
+email : cetris1@umbc.edu
+comment : Much of this was taken from pulseaudio.cpp (authored
+ by RedDwarf) in bsnes (http://byuu.org/bsnes/)
+***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#ifdef USEPULSEAUDIO
+
+#define _IN_OSS
+
+#include "externals.h"
+#include <pulse/pulseaudio.h>
+
+////////////////////////////////////////////////////////////////////////
+// declarations for pulseaudio callbacks
+////////////////////////////////////////////////////////////////////////
+void announce_connection_success (pa_context *context, const char *name, pa_proplist *property_list, void *user_data);
+
+
+////////////////////////////////////////////////////////////////////////
+// pulseaudio structs
+////////////////////////////////////////////////////////////////////////
+
+typedef struct {
+ pa_mainloop *mainloop;
+ pa_context *context;
+ pa_mainloop_api *api;
+ pa_stream *stream;
+ pa_sample_spec spec;
+ pa_buffer_attr buffer_attr;
+ int first;
+} Device;
+
+typedef struct {
+ unsigned int frequency;
+ unsigned int latency;
+} Settings;
+
+////////////////////////////////////////////////////////////////////////
+// pulseaudio globals
+////////////////////////////////////////////////////////////////////////
+
+static Device device = {
+ .mainloop = NULL,
+ .api = NULL,
+ .context = NULL,
+ .stream = NULL
+};
+
+static Settings settings = {
+ .frequency = 44100,
+ .latency = 80
+};
+
+////////////////////////////////////////////////////////////////////////
+// SETUP SOUND
+////////////////////////////////////////////////////////////////////////
+
+void SetupSound (void)
+{
+ int error_number;
+
+ // Acquire mainloop ///////////////////////////////////////////////////////
+ device.mainloop = pa_mainloop_new ();
+ if (device.mainloop == NULL)
+ {
+ fprintf (stderr, "Could not acquire PulseAudio main loop\n");
+ return;
+ }
+
+ // Acquire context ////////////////////////////////////////////////////////
+ device.api = pa_mainloop_get_api (device.mainloop);
+ device.context = pa_context_new (device.api, "PCSX");
+ if (device.context == NULL)
+ {
+ fprintf (stderr, "Could not acquire PulseAudio device context\n");
+ return;
+ }
+
+ // Connect to PulseAudio server ///////////////////////////////////////////
+ error_number = pa_context_connect (device.context, NULL, 0, NULL);
+ if (error_number < 0) {
+ fprintf (stderr, "Could not connect to PulseAudio server: %s\n", pa_strerror(error_number));
+ return;
+ }
+ else
+ {
+ fprintf (stderr, "Connected to PulseAudio synchronously.\n");
+ }
+
+ // Run mainloop until sever is ready //////////////////////////////////////
+ pa_context_state_t context_state;
+ do
+ {
+ error_number = pa_mainloop_iterate (device.mainloop, 1, NULL);
+ if (error_number < 0) {
+ fprintf (stderr, "Could not run pa_mainloop_iterate ():%s\n", pa_strerror (error_number));
+ return;
+ }
+
+ context_state = pa_context_get_state (device.context);
+ if (! PA_CONTEXT_IS_GOOD (context_state))
+ {
+ fprintf (stderr, "Context state is not good.\n");
+ return;
+ }
+ else
+ {
+ fprintf (stderr, "PulseAudio context state is %d\n", context_state);
+ }
+ } while (context_state != PA_CONTEXT_READY);
+
+ // Set sample spec ////////////////////////////////////////////////////////
+ device.spec.format = PA_SAMPLE_S16LE;
+ if (iDisStereo)
+ device.spec.channels = 1;
+ else
+ device.spec.channels = 2;
+ device.spec.rate = settings.frequency;
+
+ // Set buffer attributes //////////////////////////////////////////////////
+ int mixlen = pa_usec_to_bytes (settings.latency * PA_USEC_PER_MSEC, &device.spec);
+ device.buffer_attr.maxlength = -1;
+ device.buffer_attr.tlength = 2 * mixlen;
+ device.buffer_attr.prebuf = -1;
+ device.buffer_attr.minreq = mixlen;
+
+ // Acquire new stream using spec and buffer attributes ////////////////////
+ device.stream = pa_stream_new (device.context, "PCSX", &device.spec, NULL);
+ if (device.stream == NULL)
+ {
+ fprintf (stderr, "Could not get new PulseAudio stream.\n");
+ return;
+ }
+
+ pa_stream_flags_t flags = (pa_stream_flags_t) (PA_STREAM_ADJUST_LATENCY | PA_STREAM_VARIABLE_RATE);
+ error_number = pa_stream_connect_playback (device.stream, NULL, &device.buffer_attr, flags, NULL, NULL);
+ if (error_number < 0) {
+ fprintf (stderr, "Could not connect for playback successfully :%s\n", pa_strerror (error_number));
+ return;
+ }
+
+ // Run mainloop until stream is ready /////////////////////////////////////
+ pa_stream_state_t stream_state;
+ do {
+ error_number = pa_mainloop_iterate (device.mainloop, 1, NULL);
+ if (error_number < 0) {
+ fprintf (stderr, "Could not run pa_mainloop_iterate ():%s\n", pa_strerror (error_number));
+ return;
+ }
+
+ stream_state = pa_stream_get_state (device.stream);
+ if (! PA_STREAM_IS_GOOD (stream_state))
+ {
+ fprintf (stderr, "Could not acquire PulseAudio stream.\n");
+ return;
+ }
+ else
+ {
+ fprintf (stderr, "PulseAudio stream state is %d.\n", stream_state);
+ }
+ } while (stream_state != PA_STREAM_READY);
+
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////
+// REMOVE SOUND
+////////////////////////////////////////////////////////////////////////
+
+void RemoveSound (void)
+{
+
+ if (device.stream != NULL)
+ {
+ pa_stream_disconnect (device.stream);
+ pa_stream_unref (device.stream);
+ device.stream = NULL;
+ }
+
+ if (device.context != NULL)
+ {
+ pa_context_disconnect (device.context);
+ pa_context_unref (device.context);
+ device.context = NULL;
+ }
+
+ if (device.mainloop != NULL)
+ {
+ pa_mainloop_free (device.mainloop);
+ device.mainloop = NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// GET BYTES BUFFERED
+////////////////////////////////////////////////////////////////////////
+
+unsigned long SoundGetBytesBuffered (void)
+{
+ int size;
+
+ fprintf (stderr, "In SoundGetBytesBuffered\n");
+
+ size = pa_stream_writable_size (device.stream);
+ fprintf (stderr, "Writable size: %d\n", size);
+
+ // need to figure out length of buffer
+ if (size > TESTSIZE)
+ return size;
+ else
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// FEED SOUND DATA
+////////////////////////////////////////////////////////////////////////
+
+void SoundFeedStreamData (unsigned char *pSound, long lBytes)
+{
+ fprintf (stderr, "In SoundFeedStreamData\n");
+
+ if (pa_stream_write (device.stream, pSound, lBytes, NULL, 0LL, PA_SEEK_RELATIVE) < 0)
+ fprintf (stderr, "Error: Could not perform write with PulseAudio\n");
+}
+
+#endif