SphinxBase 0.6

src/libsphinxad/ad_pulse.c

00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 1999-2011 Carnegie Mellon University.  All rights
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  */
00037 
00038 /* Input for Pulseaudio */
00039 
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <config.h>
00043 
00044 #include <pulse/pulseaudio.h>
00045 #include <pulse/simple.h>
00046 
00047 #include "prim_type.h"
00048 #include "ad.h"
00049 
00050 ad_rec_t *
00051 ad_open_dev(const char *dev, int32 samples_per_sec)
00052 {
00053     ad_rec_t *handle;
00054     pa_simple *pa;
00055     pa_sample_spec ss;
00056     int error;
00057 
00058     ss.format = PA_SAMPLE_S16LE;
00059     ss.channels = 1;
00060     ss.rate = 16000; //samples_per_sec;
00061     
00062     pa = pa_simple_new(NULL, "ASR", PA_STREAM_RECORD, dev, "Speech", &ss, NULL, NULL, &error);
00063     if (pa == NULL) {
00064         fprintf(stderr, "Error opening audio device %s for capture: %s\n", dev, pa_strerror(error));
00065         return NULL;
00066     }
00067 
00068     if ((handle = (ad_rec_t *) calloc(1, sizeof(ad_rec_t))) == NULL) {
00069         fprintf(stderr, "Failed to allocate memory for ad device\n");
00070         return NULL;
00071     }
00072 
00073     handle->pa = pa;
00074     handle->recording = 0;
00075     handle->sps = samples_per_sec;
00076     handle->bps = sizeof(int16);
00077 
00078     return handle;
00079 }
00080 
00081 
00082 ad_rec_t *
00083 ad_open_sps(int32 samples_per_sec)
00084 {
00085     return ad_open_dev(DEFAULT_DEVICE, samples_per_sec);
00086 }
00087 
00088 ad_rec_t *
00089 ad_open(void)
00090 {
00091     return ad_open_sps(DEFAULT_SAMPLES_PER_SEC);
00092 }
00093 
00094 
00095 int32
00096 ad_start_rec(ad_rec_t * r)
00097 {
00098     if (r->recording)
00099         return AD_ERR_GEN;
00100 
00101     r->recording = 1;
00102 
00103     return 0;
00104 }
00105 
00106 
00107 int32
00108 ad_stop_rec(ad_rec_t * r)
00109 {
00110     if (!r->recording)
00111         return AD_ERR_GEN;
00112 
00113     r->recording = 0;
00114 
00115     return 0;
00116 }
00117 
00118 
00119 int32
00120 ad_read(ad_rec_t * r, int16 * buf, int32 max)
00121 {
00122     int error;
00123 
00124     if (!r->recording)
00125         return AD_EOF;
00126         
00127     if (pa_simple_read(r->pa, (void*)buf, max * 2, &error) < 0) {
00128         fprintf(stderr, "Failed to read speech: %s\n", pa_strerror(error));
00129     }
00130     
00131     return max;
00132 }
00133 
00134 
00135 int32
00136 ad_close(ad_rec_t * r)
00137 {
00138     if (r->pa == NULL)
00139         return AD_ERR_NOT_OPEN;
00140 
00141     if (r->recording) {
00142         if (ad_stop_rec(r) < 0)
00143             return AD_ERR_GEN;
00144     }
00145     pa_simple_free(r->pa);
00146     free(r);
00147 
00148     return 0;
00149 }