uncrustify as demanded.
[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    You should have received a copy of the GNU Affero General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
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    * Our configuration.
40    */
41   const struct GNUNET_CONFIGURATION_Handle *cfg;
42
43   /**
44    * Handle for the record helper
45    */
46   struct GNUNET_HELPER_Handle *record_helper;
47
48   /**
49    * Function to call with audio data (if we are enabled).
50    */
51   GNUNET_MICROPHONE_RecordedDataCallback rdc;
52
53   /**
54    * Closure for @e rdc.
55    */
56   void *rdc_cls;
57 };
58
59
60 /**
61  * Function to process the audio from the record helper
62  *
63  * @param cls clsoure with our `struct Microphone`
64  * @param msg the message from the helper
65  * @return #GNUNET_OK on success,
66  *    #GNUNET_NO to stop further processing (no error)
67  *    #GNUNET_SYSERR to stop further processing with error
68  */
69 static int
70 process_record_messages(void *cls,
71                         const struct GNUNET_MessageHeader *msg)
72 {
73   struct Microphone *mic = cls;
74   const struct AudioMessage *am;
75
76   if (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO)
77     {
78       GNUNET_break(0);
79       return GNUNET_SYSERR;
80     }
81   am = (const struct AudioMessage *)msg;
82   mic->rdc(mic->rdc_cls,
83            ntohs(msg->size) - sizeof(struct AudioMessage),
84            &am[1]);
85   return GNUNET_OK;
86 }
87
88
89 /**
90  * Enable a microphone.
91  *
92  * @param cls clsoure with our `struct Microphone`
93  * @param rdc function to call with recorded data
94  * @param rdc_cls closure for @a dc
95  */
96 static int
97 enable(void *cls,
98        GNUNET_MICROPHONE_RecordedDataCallback rdc,
99        void *rdc_cls)
100 {
101   struct Microphone *mic = cls;
102   static char * const record_helper_argv[] =
103   {
104     "gnunet-helper-audio-record",
105     NULL
106   };
107
108   mic->rdc = rdc;
109   mic->rdc_cls = rdc_cls;
110   mic->record_helper = GNUNET_HELPER_start(GNUNET_NO,
111                                            "gnunet-helper-audio-record",
112                                            record_helper_argv,
113                                            &process_record_messages,
114                                            NULL, mic);
115   if (NULL == mic->record_helper)
116     {
117       GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
118                  _("Could not start record audio helper\n"));
119       return GNUNET_SYSERR;
120     }
121   return GNUNET_OK;
122 }
123
124
125 /**
126  * Function that disables a microphone.
127  *
128  * @param cls clsoure
129  */
130 static void
131 disable(void *cls)
132 {
133   struct Microphone *mic = cls;
134
135   if (NULL == mic->record_helper)
136     {
137       GNUNET_break(0);
138       return;
139     }
140   GNUNET_break(GNUNET_OK ==
141                GNUNET_HELPER_kill(mic->record_helper, GNUNET_NO));
142   GNUNET_HELPER_destroy(mic->record_helper);
143   mic->record_helper = NULL;
144 }
145
146
147 /**
148  * Function to destroy a microphone.
149  *
150  * @param cls clsoure
151  */
152 static void
153 destroy(void *cls)
154 {
155   struct Microphone *mic = cls;
156
157   if (NULL != mic->record_helper)
158     disable(mic);
159 }
160
161
162 /**
163  * Create a microphone that corresponds to the microphone hardware
164  * of our system.
165  *
166  * @param cfg configuration to use
167  * @return NULL on error
168  */
169 struct GNUNET_MICROPHONE_Handle *
170 GNUNET_MICROPHONE_create_from_hardware(const struct GNUNET_CONFIGURATION_Handle *cfg)
171 {
172   struct GNUNET_MICROPHONE_Handle *microphone;
173   struct Microphone *mic;
174
175   mic = GNUNET_new(struct Microphone);
176   mic->cfg = cfg;
177   microphone = GNUNET_new(struct GNUNET_MICROPHONE_Handle);
178   microphone->cls = mic;
179   microphone->enable_microphone = &enable;
180   microphone->disable_microphone = &disable;
181   microphone->destroy_microphone = &destroy;
182   return microphone;
183 }
184
185
186 /**
187  * Destroy a microphone.
188  *
189  * @param microphone microphone to destroy
190  */
191 void
192 GNUNET_MICROPHONE_destroy(struct GNUNET_MICROPHONE_Handle *microphone)
193 {
194   microphone->destroy_microphone(microphone->cls);
195   GNUNET_free(microphone);
196 }
197
198 /* end of microphone.c */