aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/conversation/Makefile.am19
-rw-r--r--src/conversation/conversation.h6
-rw-r--r--src/conversation/gnunet-helper-audio-record.c110
-rw-r--r--src/conversation/microphone.c199
-rw-r--r--src/include/gnunet_helper_lib.h30
-rw-r--r--src/include/gnunet_microphone_lib.h9
-rw-r--r--src/include/gnunet_speaker_lib.h3
-rw-r--r--src/util/server_mst.c2
8 files changed, 296 insertions, 82 deletions
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am
index 895e1136e..ac2f47612 100644
--- a/src/conversation/Makefile.am
+++ b/src/conversation/Makefile.am
@@ -14,17 +14,32 @@ AM_CPPFLAGS = \
14# $(WINFLAGS) \ 14# $(WINFLAGS) \
15# -export-dynamic 15# -export-dynamic
16 16
17lib_LTLIBRARIES = libgnunetconversation.la 17lib_LTLIBRARIES = \
18 libgnunetmicrophone.la \
19 libgnunetconversation.la
18 20
19pkgcfgdir= $(prefix)/share/gnunet/config.d/ 21pkgcfgdir= $(prefix)/share/gnunet/config.d/
20 22
21libexecdir= $(prefix)/lib/gnunet/libexec/ 23libexecdir= $(prefix)/lib/gnunet/libexec/
22 24
25libgnunetmicrophone_la_SOURCES = \
26 microphone.c
27libgnunetmicrophone_la_LIBADD = \
28 -lgnunetutil
29libgnunetmicrophone_la_LDFLAGS = \
30 $(GNUNET_LDFLAGS) $(WINFLAGS) \
31 -version-info 0:0:0
32
33
23libgnunetconversation_la_SOURCES = \ 34libgnunetconversation_la_SOURCES = \
24 conversation_api.c \ 35 conversation_api.c \
25 conversation_api2.c 36 conversation_api2.c
26libgnunetconversation_la_LIBADD = \ 37libgnunetconversation_la_LIBADD = \
27 -lgnunetutil -lgnunetnamestore -lgnunetgns 38 libgnunetmicrophone.la \
39 $(top_builddir)/src/gns/libgnunetgns.la \
40 $(top_builddir)/src/namestore/libgnunetnamestore.la \
41 $(top_builddir)/src/util/libgnunetutil.la
42
28libgnunetconversation_la_LDFLAGS = \ 43libgnunetconversation_la_LDFLAGS = \
29 $(GNUNET_LDFLAGS) $(WINFLAGS) \ 44 $(GNUNET_LDFLAGS) $(WINFLAGS) \
30 -version-info 0:0:0 45 -version-info 0:0:0
diff --git a/src/conversation/conversation.h b/src/conversation/conversation.h
index cc36ca739..91630d8c2 100644
--- a/src/conversation/conversation.h
+++ b/src/conversation/conversation.h
@@ -396,10 +396,10 @@ struct AudioMessage
396 * Type is #GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO 396 * Type is #GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO
397 */ 397 */
398 struct GNUNET_MessageHeader header; 398 struct GNUNET_MessageHeader header;
399 int SequenceNumber; 399 int32_t SequenceNumber;
400 struct GNUNET_TIME_Absolute time; 400 struct GNUNET_TIME_Absolute time;
401 int length; 401 int32_t length;
402 int encrypted; 402 int32_t encrypted;
403 uint8_t audio[200]; 403 uint8_t audio[200];
404 404
405}; 405};
diff --git a/src/conversation/gnunet-helper-audio-record.c b/src/conversation/gnunet-helper-audio-record.c
index a6b97278b..5d4c0399a 100644
--- a/src/conversation/gnunet-helper-audio-record.c
+++ b/src/conversation/gnunet-helper-audio-record.c
@@ -38,9 +38,10 @@
38#include <opus/opus.h> 38#include <opus/opus.h>
39#include <opus/opus_types.h> 39#include <opus/opus_types.h>
40 40
41
41/** 42/**
42* Specification for recording. May change in the future to spec negotiation. 43 * Specification for recording. May change in the future to spec negotiation.
43*/ 44 */
44static pa_sample_spec sample_spec = { 45static pa_sample_spec sample_spec = {
45 .format = PA_SAMPLE_FLOAT32LE, 46 .format = PA_SAMPLE_FLOAT32LE,
46 .rate = 48000, 47 .rate = 48000,
@@ -48,90 +49,89 @@ static pa_sample_spec sample_spec = {
48}; 49};
49 50
50/** 51/**
51* Pulseaudio mainloop api 52 * Pulseaudio mainloop api
52*/ 53 */
53static pa_mainloop_api *mainloop_api = NULL; 54static pa_mainloop_api *mainloop_api;
54 55
55/** 56/**
56* Pulseaudio mainloop 57 * Pulseaudio mainloop
57*/ 58 */
58static pa_mainloop *m = NULL; 59static pa_mainloop *m;
59 60
60/** 61/**
61* Pulseaudio context 62 * Pulseaudio context
62*/ 63 */
63static pa_context *context = NULL; 64static pa_context *context;
64 65
65/** 66/**
66* Pulseaudio recording stream 67 * Pulseaudio recording stream
67*/ 68 */
68static pa_stream *stream_in = NULL; 69static pa_stream *stream_in;
69 70
70/** 71/**
71* Pulseaudio io events 72 * Pulseaudio io events
72*/ 73 */
73static pa_io_event *stdio_event = NULL; 74static pa_io_event *stdio_event;
74 75
75/** 76/**
76* Message tokenizer 77 * Message tokenizer
77*/ 78 */
78struct MessageStreamTokenizer *stdin_mst; 79static struct MessageStreamTokenizer *stdin_mst;
79 80
80/** 81/**
81* OPUS encoder 82 * OPUS encoder
82*/ 83 */
83OpusEncoder *enc = NULL; 84static OpusEncoder *enc;
84 85
85/** 86/**
86* 87 *
87*/ 88 */
88unsigned char *opus_data; 89static unsigned char *opus_data;
89 90
90/** 91/**
91* PCM data buffer for one OPUS frame 92 * PCM data buffer for one OPUS frame
92*/ 93 */
93float *pcm_buffer; 94static float *pcm_buffer;
94 95
95/** 96/**
96 * Length of the pcm data needed for one OPUS frame 97 * Length of the pcm data needed for one OPUS frame
97 */ 98 */
98int pcm_length; 99static int pcm_length;
99 100
100/** 101/**
101* Number of samples for one frame 102 * Number of samples for one frame
102*/ 103 */
103int frame_size; 104static int frame_size;
104 105
105/** 106/**
106* Maximum length of opus payload 107* Maximum length of opus payload
107*/ 108*/
108int max_payload_bytes = 1500; 109static int max_payload_bytes = 1500;
109 110
110/** 111/**
111* Audio buffer 112 * Audio buffer
112*/ 113 */
113static void *transmit_buffer = NULL; 114static void *transmit_buffer;
114 115
115/** 116/**
116* Length of audio buffer 117 * Length of audio buffer
117*/ 118 */
118static size_t transmit_buffer_length = 0; 119static size_t transmit_buffer_length;
119 120
120/** 121/**
121* Read index for transmit buffer 122 * Read index for transmit buffer
122*/ 123 */
123static size_t transmit_buffer_index = 0; 124static size_t transmit_buffer_index;
124 125
125/** 126/**
126* Audio message skeleton 127 * Audio message skeleton
127*/ 128 */
128struct AudioMessage *audio_message; 129static struct AudioMessage *audio_message;
129
130 130
131 131
132/** 132/**
133* Pulseaudio shutdown task 133 * Pulseaudio shutdown task
134*/ 134 */
135static void 135static void
136quit (int ret) 136quit (int ret)
137{ 137{
@@ -140,18 +140,14 @@ quit (int ret)
140} 140}
141 141
142 142
143
144/** 143/**
145* Creates OPUS packets from PCM data 144 * Creates OPUS packets from PCM data
146*/ 145 */
147static void 146static void
148packetizer () 147packetizer ()
149{ 148{
150
151
152 while (transmit_buffer_length >= transmit_buffer_index + pcm_length) 149 while (transmit_buffer_length >= transmit_buffer_index + pcm_length)
153 { 150 {
154
155 int ret; 151 int ret;
156 int len; 152 int len;
157 153
@@ -450,11 +446,11 @@ opus_init ()
450 opus_data = (unsigned char *) calloc (max_payload_bytes, sizeof (char)); 446 opus_data = (unsigned char *) calloc (max_payload_bytes, sizeof (char));
451 447
452 audio_message = pa_xmalloc (sizeof (struct AudioMessage)); 448 audio_message = pa_xmalloc (sizeof (struct AudioMessage));
453
454 audio_message->header.size = htons (sizeof (struct AudioMessage)); 449 audio_message->header.size = htons (sizeof (struct AudioMessage));
455 audio_message->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO); 450 audio_message->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
456} 451}
457 452
453
458/** 454/**
459 * The main function for the record helper. 455 * The main function for the record helper.
460 * 456 *
diff --git a/src/conversation/microphone.c b/src/conversation/microphone.c
new file mode 100644
index 000000000..8e9b9e241
--- /dev/null
+++ b/src/conversation/microphone.c
@@ -0,0 +1,199 @@
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 */
37struct 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 */
71static int
72process_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 */
98static int
99enable (void *cls,
100 GNUNET_MICROPHONE_RecordedDataCallback rdc,
101 void *rdc_cls)
102{
103 struct Microphone *mic = cls;
104 char * const record_helper_argv[] =
105 {
106 "gnunet-helper-audio-record",
107 NULL
108 };
109 mic->rdc = rdc;
110 mic->rdc_cls = rdc_cls;
111 mic->record_helper = GNUNET_HELPER_start (GNUNET_NO,
112 "gnunet-helper-audio-record",
113 record_helper_argv,
114 &process_record_messages,
115 NULL, mic);
116 if (NULL == mic->record_helper)
117 {
118 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
119 _("Could not start record audio helper\n"));
120 return GNUNET_SYSERR;
121 }
122 return GNUNET_OK;
123}
124
125
126/**
127 * Function that disables a microphone.
128 *
129 * @param cls clsoure
130 */
131static void
132disable (void *cls)
133{
134 struct Microphone *mic = cls;
135
136 if (NULL == mic->record_helper)
137 {
138 GNUNET_break (0);
139 return;
140 }
141 GNUNET_break (GNUNET_OK ==
142 GNUNET_HELPER_kill (mic->record_helper, GNUNET_NO));
143 GNUNET_HELPER_destroy (mic->record_helper);
144 mic->record_helper = NULL;
145}
146
147
148/**
149 * Function to destroy a microphone.
150 *
151 * @param cls clsoure
152 */
153static void
154destroy (void *cls)
155{
156 struct Microphone *mic = cls;
157
158 if (NULL != mic->record_helper)
159 disable (mic);
160}
161
162
163/**
164 * Create a microphone that corresponds to the microphone hardware
165 * of our system.
166 *
167 * @param cfg configuration to use
168 * @return NULL on error
169 */
170struct GNUNET_MICROPHONE_Handle *
171GNUNET_MICROPHONE_create_from_hardware (const struct GNUNET_CONFIGURATION_Handle *cfg)
172{
173 struct GNUNET_MICROPHONE_Handle *microphone;
174 struct Microphone *mic;
175
176 mic = GNUNET_new (struct Microphone);
177 mic->cfg = cfg;
178 microphone = GNUNET_new (struct GNUNET_MICROPHONE_Handle);
179 microphone->cls = mic;
180 microphone->enable_microphone = &enable;
181 microphone->disable_microphone = &disable;
182 microphone->destroy_microphone = &destroy;
183 return microphone;
184}
185
186
187/**
188 * Destroy a microphone.
189 *
190 * @param microphone microphone to destroy
191 */
192void
193GNUNET_MICROPHONE_destroy (struct GNUNET_MICROPHONE_Handle *microphone)
194{
195 microphone->destroy_microphone (microphone->cls);
196 GNUNET_free (microphone);
197}
198
199/* end of microphone.c */
diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h
index 06d65b360..281ee9ba6 100644
--- a/src/include/gnunet_helper_lib.h
+++ b/src/include/gnunet_helper_lib.h
@@ -77,21 +77,21 @@ GNUNET_HELPER_start (int with_control_pipe,
77 * reaped; call GNUNET_HELPER_wait() for reaping the dead helper process. 77 * reaped; call GNUNET_HELPER_wait() for reaping the dead helper process.
78 * 78 *
79 * @param h the helper handle 79 * @param h the helper handle
80 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's 80 * @param soft_kill if #GNUNET_YES, signals termination by closing the helper's
81 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper 81 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
82 * @return GNUNET_OK on success; GNUNET_SYSERR on error 82 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
83 */ 83 */
84int 84int
85GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill); 85GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill);
86 86
87 87
88/** 88/**
89 * Reap the helper process. This call is blocking(!). The helper process 89 * Reap the helper process. This call is blocking (!). The helper process
90 * should either be sent a termination signal before or should be dead before 90 * should either be sent a termination signal before or should be dead before
91 * calling this function 91 * calling this function
92 * 92 *
93 * @param h the helper handle 93 * @param h the helper handle
94 * @return GNUNET_OK on success; GNUNET_SYSERR on error 94 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
95 */ 95 */
96int 96int
97GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h); 97GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h);
@@ -111,8 +111,8 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h);
111 * helper process 111 * helper process
112 * 112 *
113 * @param h handle to helper to stop 113 * @param h handle to helper to stop
114 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's 114 * @param soft_kill if #GNUNET_YES, signals termination by closing the helper's
115 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper 115 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
116 */ 116 */
117void 117void
118GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill); 118GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill);
@@ -122,9 +122,9 @@ GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill);
122 * Continuation function. 122 * Continuation function.
123 * 123 *
124 * @param cls closure 124 * @param cls closure
125 * @param result GNUNET_OK on success, 125 * @param result #GNUNET_OK on success,
126 * GNUNET_NO if helper process died 126 * #GNUNET_NO if helper process died
127 * GNUNET_SYSERR during GNUNET_HELPER_stop 127 * #GNUNET_SYSERR during GNUNET_HELPER_stop
128 */ 128 */
129typedef void (*GNUNET_HELPER_Continuation)(void *cls, 129typedef void (*GNUNET_HELPER_Continuation)(void *cls,
130 int result); 130 int result);
@@ -143,7 +143,7 @@ struct GNUNET_HELPER_SendHandle;
143 * @param msg message to send 143 * @param msg message to send
144 * @param can_drop can the message be dropped if there is already one in the queue? 144 * @param can_drop can the message be dropped if there is already one in the queue?
145 * @param cont continuation to run once the message is out 145 * @param cont continuation to run once the message is out
146 * @param cont_cls closure for 'cont' 146 * @param cont_cls closure for @a cont
147 * @return NULL if the message was dropped, 147 * @return NULL if the message was dropped,
148 * otherwise handle to cancel *cont* (actual transmission may 148 * otherwise handle to cancel *cont* (actual transmission may
149 * not be abortable) 149 * not be abortable)
@@ -157,13 +157,13 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
157 157
158 158
159/** 159/**
160 * Cancel a 'send' operation. If possible, transmitting the 160 * Cancel a #GNUNET_HELPER_send operation. If possible, transmitting
161 * message is also aborted, but at least 'cont' won't be 161 * the message is also aborted, but at least 'cont' won't be called.
162 * called.
163 * 162 *
164 * @param sh operation to cancel 163 * @param sh operation to cancel
165 */ 164 */
166void 165void
167GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh); 166GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh);
168 167
169#endif /* end of include guard: GNUNET_HELPER_LIB_H */ 168#endif
169/* end of include guard: GNUNET_HELPER_LIB_H */
diff --git a/src/include/gnunet_microphone_lib.h b/src/include/gnunet_microphone_lib.h
index c99777d0c..1ba97cdf6 100644
--- a/src/include/gnunet_microphone_lib.h
+++ b/src/include/gnunet_microphone_lib.h
@@ -36,6 +36,8 @@ extern "C"
36#endif 36#endif
37#endif 37#endif
38 38
39#include "gnunet_util_lib.h"
40
39/** 41/**
40 * Process recorded audio data. 42 * Process recorded audio data.
41 * 43 *
@@ -53,10 +55,11 @@ typedef void (*GNUNET_MICROPHONE_RecordedDataCallback)(void *cls,
53 * @param cls clsoure 55 * @param cls clsoure
54 * @param rdc function to call with recorded data 56 * @param rdc function to call with recorded data
55 * @param rdc_cls closure for @a dc 57 * @param rdc_cls closure for @a dc
58 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
56 */ 59 */
57typedef void (*GNUNET_MICROPHONE_EnableCallback)(void *cls, 60typedef int (*GNUNET_MICROPHONE_EnableCallback)(void *cls,
58 GNUNET_MICROPHONE_RecordedDataCallback rdc, 61 GNUNET_MICROPHONE_RecordedDataCallback rdc,
59 void *rdc_cls); 62 void *rdc_cls);
60 63
61/** 64/**
62 * Function that disables a microphone. 65 * Function that disables a microphone.
diff --git a/src/include/gnunet_speaker_lib.h b/src/include/gnunet_speaker_lib.h
index 567b984e0..7a6eb028b 100644
--- a/src/include/gnunet_speaker_lib.h
+++ b/src/include/gnunet_speaker_lib.h
@@ -40,8 +40,9 @@ extern "C"
40 * Function that enables a speaker. 40 * Function that enables a speaker.
41 * 41 *
42 * @param cls clsoure 42 * @param cls clsoure
43 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
43 */ 44 */
44typedef void (*GNUNET_SPEAKER_EnableCallback)(void *cls); 45typedef int (*GNUNET_SPEAKER_EnableCallback)(void *cls);
45 46
46/** 47/**
47 * Function that disables a speaker. 48 * Function that disables a speaker.
diff --git a/src/util/server_mst.c b/src/util/server_mst.c
index 34ffc6da7..4e96653dc 100644
--- a/src/util/server_mst.c
+++ b/src/util/server_mst.c
@@ -90,7 +90,7 @@ GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
90{ 90{
91 struct GNUNET_SERVER_MessageStreamTokenizer *ret; 91 struct GNUNET_SERVER_MessageStreamTokenizer *ret;
92 92
93 ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_MessageStreamTokenizer)); 93 ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer);
94 ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE); 94 ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE);
95 ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE; 95 ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE;
96 ret->cb = cb; 96 ret->cb = cb;