-implement speaker library
[oweals/gnunet.git] / src / conversation / microphone.c
1 /*
2   This file is part of GNUnet
3   (C) 2013 Christian Grothoff (and other contributing authors)
4   
5   GNUnet is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published
7   by the Free Software Foundation; either version 3, or (at your
8   option) any later version.
9   
10   GNUnet is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   General Public License for more details.
14   
15   You should have received a copy of the GNU General Public License
16   along with GNUnet; see the file COPYING.  If not, write to the
17   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18   Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file conversation/microphone.c
23  * @brief API to access an audio microphone; provides access to hardware microphones;
24  *        actually just wraps the gnunet-helper-audio-record
25  * @author Simon Dieterle
26  * @author Andreas Fuchs
27  * @author Christian Grothoff
28  */
29 #include "platform.h"
30 #include "gnunet_microphone_lib.h"
31 #include "conversation.h"
32
33
34 /**
35  * Internal data structures for the microphone.
36  */
37 struct Microphone
38 {
39
40   /**
41    * Our configuration.
42    */
43   const struct GNUNET_CONFIGURATION_Handle *cfg;
44
45   /**
46    * Handle for the record helper
47    */
48   struct GNUNET_HELPER_Handle *record_helper;
49
50   /**
51    * Function to call with audio data (if we are enabled).
52    */
53   GNUNET_MICROPHONE_RecordedDataCallback rdc;
54
55   /**
56    * Closure for @e rdc.
57    */
58   void *rdc_cls;
59
60 };
61
62
63 /**
64  * Function to process the audio from the record helper
65  *
66  * @param cls clsoure with our `struct Microphone`
67  * @param client NULL
68  * @param msg the message from the helper
69  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
70  */
71 static int
72 process_record_messages (void *cls,
73                          void *client,
74                          const struct GNUNET_MessageHeader *msg)
75 {
76   struct Microphone *mic = cls;
77
78   if ( (ntohs (msg->size) != sizeof (struct AudioMessage)) ||
79        (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO) )
80   {
81     GNUNET_break (0);
82     return GNUNET_SYSERR;
83   }
84   mic->rdc (mic->rdc_cls,
85             sizeof (struct AudioMessage),
86             (const char *) msg);
87   return GNUNET_OK;
88 }
89
90
91 /**
92  * Enable a microphone.
93  *
94  * @param cls clsoure with our `struct Microphone`
95  * @param rdc function to call with recorded data
96  * @param rdc_cls closure for @a dc
97  */
98 static int
99 enable (void *cls,
100         GNUNET_MICROPHONE_RecordedDataCallback rdc,
101         void *rdc_cls)
102 {
103   struct Microphone *mic = cls;  
104   static char * const record_helper_argv[] = 
105   {
106     "gnunet-helper-audio-record",
107     NULL
108   };
109
110   mic->rdc = rdc;
111   mic->rdc_cls = rdc_cls;
112   mic->record_helper = GNUNET_HELPER_start (GNUNET_NO,
113                                             "gnunet-helper-audio-record",
114                                             record_helper_argv,
115                                             &process_record_messages, 
116                                             NULL, mic);  
117   if (NULL == mic->record_helper)
118   {
119     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
120                 _("Could not start record audio helper\n"));
121     return GNUNET_SYSERR;
122   }  
123   return GNUNET_OK;
124 }
125
126
127 /**
128  * Function that disables a microphone.
129  *
130  * @param cls clsoure
131  */
132 static void
133 disable (void *cls)
134 {
135   struct Microphone *mic = cls;
136
137   if (NULL == mic->record_helper)
138   {
139     GNUNET_break (0);
140     return;
141   }
142   GNUNET_break (GNUNET_OK ==
143                 GNUNET_HELPER_kill (mic->record_helper, GNUNET_NO));
144   GNUNET_HELPER_destroy (mic->record_helper);
145   mic->record_helper = NULL;
146 }
147
148
149 /**
150  * Function to destroy a microphone.
151  *
152  * @param cls clsoure
153  */
154 static void
155 destroy (void *cls)
156 {
157   struct Microphone *mic = cls;
158
159   if (NULL != mic->record_helper)
160     disable (mic);
161 }
162
163
164 /**
165  * Create a microphone that corresponds to the microphone hardware
166  * of our system.
167  *
168  * @param cfg configuration to use
169  * @return NULL on error
170  */
171 struct GNUNET_MICROPHONE_Handle *
172 GNUNET_MICROPHONE_create_from_hardware (const struct GNUNET_CONFIGURATION_Handle *cfg)
173 {
174   struct GNUNET_MICROPHONE_Handle *microphone;
175   struct Microphone *mic;
176
177   mic = GNUNET_new (struct Microphone);
178   mic->cfg = cfg;
179   microphone = GNUNET_new (struct GNUNET_MICROPHONE_Handle);
180   microphone->cls = mic;
181   microphone->enable_microphone = &enable;
182   microphone->disable_microphone = &disable;
183   microphone->destroy_microphone = &destroy;
184   return microphone;
185 }
186
187
188 /**
189  * Destroy a microphone.
190  *
191  * @param microphone microphone to destroy
192  */
193 void
194 GNUNET_MICROPHONE_destroy (struct GNUNET_MICROPHONE_Handle *microphone)
195 {
196   microphone->destroy_microphone (microphone->cls);
197   GNUNET_free (microphone);
198 }
199
200 /* end of microphone.c */