[pulseaudio-commits] r1437 - /trunk/src/utils/padsp.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Wed Mar 7 01:27:35 PST 2007


Author: ossman
Date: Wed Mar  7 10:27:30 2007
New Revision: 1437

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1437&root=3Dpulseaudio&vi=
ew=3Drev
Log:
Add support for SNDCTL_DSP_SETTRIGGER. (closes #56)

Modified:
    trunk/src/utils/padsp.c

Modified: trunk/src/utils/padsp.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/utils/padsp.c?rev=3D1=
437&root=3Dpulseaudio&r1=3D1436&r2=3D1437&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/utils/padsp.c (original)
+++ trunk/src/utils/padsp.c Wed Mar  7 10:27:30 2007
@@ -4,7 +4,7 @@
   This file is part of PulseAudio.
 =

   Copyright 2006 Lennart Poettering
-  Copyright 2006 Pierre Ossman <ossman at cendio.se> for Cendio AB
+  Copyright 2006-2007 Pierre Ossman <ossman at cendio.se> for Cendio AB
 =

   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
@@ -84,6 +84,8 @@
     pa_context *context;
     pa_stream *play_stream;
     pa_stream *rec_stream;
+    int play_precork;
+    int rec_precork;
 =

     pa_io_event *io_event;
     pa_io_event_flags_t io_flags;
@@ -197,7 +199,7 @@
     debug(DEBUG_LEVEL_NORMAL, __FILE__": Not connected: %s\n", (i)->contex=
t ? pa_strerror(pa_context_errno((i)->context)) : "NULL"); \
     goto label; \
 } \
-} while(0);
+} while(0)
 =

 #define PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, label) do { \
 if (!(i)->context || pa_context_get_state((i)->context) !=3D PA_CONTEXT_RE=
ADY || \
@@ -205,7 +207,7 @@
     debug(DEBUG_LEVEL_NORMAL, __FILE__": Not connected: %s\n", (i)->contex=
t ? pa_strerror(pa_context_errno((i)->context)) : "NULL"); \
     goto label; \
 } \
-} while(0);
+} while(0)
 =

 #define RECORD_STREAM_CHECK_DEAD_GOTO(i, label) do { \
 if (!(i)->context || pa_context_get_state((i)->context) !=3D PA_CONTEXT_RE=
ADY || \
@@ -213,7 +215,7 @@
     debug(DEBUG_LEVEL_NORMAL, __FILE__": Not connected: %s\n", (i)->contex=
t ? pa_strerror(pa_context_errno((i)->context)) : "NULL"); \
     goto label; \
 } \
-} while(0);
+} while(0)
 =

 static void debug(int level, const char *format, ...) PA_GCC_PRINTF_ATTR(2=
,3);
 =

@@ -572,6 +574,8 @@
     i->context =3D NULL;
     i->play_stream =3D NULL;
     i->rec_stream =3D NULL;
+    i->play_precork =3D 0;
+    i->rec_precork =3D 0;
     i->io_event =3D NULL;
     i->io_flags =3D 0;
     pthread_mutex_init(&i->mutex, NULL);
@@ -937,7 +941,7 @@
 =

 static int create_playback_stream(fd_info *i) {
     pa_buffer_attr attr;
-    int n;
+    int n, flags;
 =

     assert(i);
 =

@@ -958,7 +962,12 @@
     attr.prebuf =3D i->fragment_size;
     attr.minreq =3D i->fragment_size;
 =

-    if (pa_stream_connect_playback(i->play_stream, NULL, &attr, PA_STREAM_=
INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL) < 0) {
+    flags =3D PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;
+    if (i->play_precork) {
+        flags |=3D PA_STREAM_START_CORKED;
+        debug(DEBUG_LEVEL_NORMAL, __FILE__": creating stream corked\n");
+    }
+    if (pa_stream_connect_playback(i->play_stream, NULL, &attr, flags, NUL=
L, NULL) < 0) {
         debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_connect_playback() =
failed: %s\n", pa_strerror(pa_context_errno(i->context)));
         goto fail;
     }
@@ -976,7 +985,7 @@
 =

 static int create_record_stream(fd_info *i) {
     pa_buffer_attr attr;
-    int n;
+    int n, flags;
 =

     assert(i);
 =

@@ -995,7 +1004,12 @@
     attr.maxlength =3D i->fragment_size * (i->n_fragments+1);
     attr.fragsize =3D i->fragment_size;
 =

-    if (pa_stream_connect_record(i->rec_stream, NULL, &attr, PA_STREAM_INT=
ERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE) < 0) {
+    flags =3D PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;
+    if (i->rec_precork) {
+        flags |=3D PA_STREAM_START_CORKED;
+        debug(DEBUG_LEVEL_NORMAL, __FILE__": creating stream corked\n");
+    }
+    if (pa_stream_connect_record(i->rec_stream, NULL, &attr, flags) < 0) {
         debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_connect_record() fa=
iled: %s\n", pa_strerror(pa_context_errno(i->context)));
         goto fail;
     }
@@ -1800,6 +1814,44 @@
     return 0;
 }
 =

+static int dsp_cork(fd_info *i, pa_stream *s, int b) {
+    pa_operation *o =3D NULL;
+    int r =3D -1;
+
+    pa_threaded_mainloop_lock(i->mainloop);
+
+    if (!(o =3D pa_stream_cork(s, b, stream_success_cb, i))) {
+        debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_cork(): %s\n", pa_s=
trerror(pa_context_errno(i->context)));
+        goto fail;
+    }
+
+    i->operation_success =3D 0;
+    while (!pa_operation_get_state(o) !=3D PA_OPERATION_DONE) {
+        if (s =3D=3D i->play_stream)
+            PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, fail);
+        else if (s =3D=3D i->rec_stream)
+            RECORD_STREAM_CHECK_DEAD_GOTO(i, fail);
+
+        pa_threaded_mainloop_wait(i->mainloop);
+    }
+
+    if (!i->operation_success) {
+        debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_cork(): %s\n", pa_s=
trerror(pa_context_errno(i->context)));
+        goto fail;
+    }
+
+    r =3D 0;
+
+fail:
+
+    if (o)
+        pa_operation_unref(o);
+
+    pa_threaded_mainloop_unlock(i->mainloop);
+
+    return 0;
+}
+
 static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_e=
rrno) {
     int ret =3D -1;
 =

@@ -1929,7 +1981,7 @@
         case SNDCTL_DSP_GETCAPS:
             debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_CAPS\n");
 =

-            *(int*)  argp =3D DSP_CAP_DUPLEX
+            *(int*)  argp =3D DSP_CAP_DUPLEX | DSP_CAP_TRIGGER
 #ifdef DSP_CAP_MULTI
 	      | DSP_CAP_MULTI
 #endif
@@ -2007,6 +2059,32 @@
 =

             if (dsp_trigger(i) < 0)
                 *_errno =3D EIO;
+            break;
+
+        case SNDCTL_DSP_SETTRIGGER:
+            debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_SETTRIGGER: 0x=
%08x\n", *(int*) argp);
+
+            if (!i->io_event) {
+                *_errno =3D EIO;
+                break;
+            }
+
+            i->play_precork =3D !((*(int*) argp) & PCM_ENABLE_OUTPUT);
+
+            if (i->play_stream) {
+                if (dsp_cork(i, i->play_stream, !((*(int*) argp) & PCM_ENA=
BLE_OUTPUT)) < 0)
+                    *_errno =3D EIO;
+                if (dsp_trigger(i) < 0)
+                    *_errno =3D EIO;
+            }
+
+            i->rec_precork =3D !((*(int*) argp) & PCM_ENABLE_INPUT);
+
+            if (i->rec_stream) {
+                if (dsp_cork(i, i->rec_stream, !((*(int*) argp) & PCM_ENAB=
LE_INPUT)) < 0)
+                    *_errno =3D EIO;
+            }
+
             break;
 =

         case SNDCTL_DSP_SYNC:




More information about the pulseaudio-commits mailing list