aboutsummaryrefslogtreecommitdiff
path: root/src/conversation
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-02 19:29:22 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-02 19:29:22 +0000
commit0834bf4d6fdf19ab410c01c02e65fcda8a5e5ebc (patch)
tree2410199dfb90c0ef4d12fc749f30f88e9bfda9b8 /src/conversation
parentec9740ca2ca84525842e6743b45ceb9cb2a3ea95 (diff)
downloadgnunet-0834bf4d6fdf19ab410c01c02e65fcda8a5e5ebc.tar.gz
gnunet-0834bf4d6fdf19ab410c01c02e65fcda8a5e5ebc.zip
-implement microphone library
Diffstat (limited to 'src/conversation')
-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
4 files changed, 272 insertions, 62 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 */