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