root/rat/trunk/transmit.c @ 1939

Revision 1939, 17.7 KB (checked in by ucaccsp, 16 years ago)

Rearrange time.c and rat_time.h to be timers.[ch], 'coz it's neater.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:    transmit.c
3 * PROGRAM: RAT
4 * AUTHOR:  Orion Hodson / Isidor Kouvelas
5 *
6 * $Revision$
7 * $Date$
8 *
9 * Copyright (c) 1995-98 University College London
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, is permitted, for non-commercial use only, provided
14 * that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *      This product includes software developed by the Computer Science
23 *      Department at University College London
24 * 4. Neither the name of the University nor of the Department may be used
25 *    to endorse or promote products derived from this software without
26 *    specific prior written permission.
27 * Use of this software for commercial purposes is explicitly forbidden
28 * unless prior written permission is obtained from the authors.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 */
42
43#include "config_unix.h"
44#include "config_win32.h"
45#include "assert.h"
46#include "codec.h"
47#include "channel.h"
48#include "session.h"
49#include "audio.h"
50#include "parameters.h"
51#include "ui.h"
52#include "util.h"
53#include "rtcp_pckt.h"
54#include "rtcp_db.h"
55#include "net.h"
56#include "timers.h"
57#include "transmit.h"
58
59typedef struct s_tx_unit {
60        struct s_tx_unit *next;
61        struct s_tx_unit *prev;
62        sample  *data;             /* pointer to raw data in read_buf */
63        u_int32  dur_used;         /* number of time intervals filled */
64        u_int16  energy;
65        u_char   silence;          /* First pass */
66        u_char   send;             /* Silence second pass */
67        u_int32  time;             /* timestamp */
68} tx_unit;
69
70typedef struct s_tx_buffer {
71        struct s_sd   *sd_info;
72        struct s_vad  *vad;
73        struct s_agc  *agc;
74        struct s_time *clock;
75        u_int32        channels;
76        u_int32        unit_dur; /* duration in sampling intervals (excludes channels) */
77        /* These are pointers into same chain of tx_units */
78        tx_unit        *head_ptr;
79        tx_unit        *tx_ptr;             /* Where transmission is */
80        tx_unit        *silence_ptr;        /* Where rules based silence is */
81        tx_unit        *last_ptr;           /* Where reading is */
82        /* Separate chain for spares */
83        tx_unit        *spare_ptr;     
84        u_int32         spare_cnt;
85        u_int32         alloc_cnt;
86} tx_buffer;
87
88static sample dummy_buf[DEVICE_REC_BUF];
89
90/* read buffer does own recycling of data so that if we change device
91 * unit size we do not tie up unnecessary memory as would happen with
92 * block_alloc.
93 */
94
95static tx_unit *
96tx_unit_get(tx_buffer *tb)
97{
98        tx_unit *u;
99
100        if (tb->spare_ptr) {
101                u = tb->spare_ptr;
102                tb->spare_ptr = tb->spare_ptr->next;
103                if (tb->spare_ptr) tb->spare_ptr->prev = NULL;
104                assert(u->prev == NULL);
105                u->next = NULL;
106                tb->spare_cnt--;
107        } else {
108                u       = (tx_unit*) xmalloc (sizeof(tx_unit));
109                u->data = (sample*)  xmalloc (sizeof(sample) * tb->channels *tb->unit_dur);
110                tb->alloc_cnt++;
111        }
112
113        u->time   = get_time(tb->clock);
114        u->next = u->prev = NULL;
115        u->dur_used = 0;
116
117        return u;
118}
119
120static void
121tx_unit_release(tx_buffer *tb, tx_unit *u)
122{
123        assert(u);
124
125        if (u->next) u->next->prev = u->prev;
126        if (u->prev) u->prev->next = u->next;
127
128        u->prev = NULL;
129        u->next = tb->spare_ptr;
130
131        if (tb->spare_ptr) tb->spare_ptr->prev = u;
132        tb->spare_ptr = u;
133
134        tb->spare_cnt++;
135}
136
137static void
138tx_unit_destroy(tx_unit *u)
139{
140        assert(u != NULL);
141        assert(u != u->next);
142        assert(u != u->prev);
143       
144        if (u->next != NULL) u->next->prev = u->prev;
145        if (u->prev != NULL) u->prev->next = u->next;
146        xfree(u->data);
147        xfree(u);
148}
149
150/* Clear and reset buffer to a starting position */
151static void
152transmit_audit(tx_buffer *tb)
153{
154        tx_unit *u, *u_next;
155
156        u = tb->head_ptr;
157        while(u) {
158                u_next = u->next;
159                tx_unit_release(tb, u);
160                u = u_next;
161        }
162        tb->head_ptr = tb->tx_ptr = tb->silence_ptr = tb->last_ptr = NULL;
163        vad_reset(tb->vad);
164}
165
166static void
167tx_buffer_trim(tx_buffer *tb)
168{
169        tx_unit *u, *end;
170        int safety;
171
172        safety = vad_max_could_get(tb->vad);
173
174        end = tb->tx_ptr;
175        while(end != NULL && safety != 0) {
176                end = end->prev;
177                safety --;
178        }
179       
180        if (end) {
181                for(u = tb->head_ptr; u != end; u = tb->head_ptr) {
182                        tb->head_ptr = u->next;
183                        tx_unit_release(tb, u);
184                }
185        }
186}
187
188/* These routines are called when the button on the interface is toggled */
189void
190tx_start(session_struct *sp)
191{
192        tx_buffer *tb;
193        if (sp->sending_audio == TRUE || sp->have_device == FALSE)
194                return;
195
196        tb = sp->tb;
197
198        if (sp->transmit_audit_required == TRUE) {
199                transmit_audit(tb);
200                sp->transmit_audit_required = FALSE;
201        }
202
203        tb->head_ptr = tb->last_ptr = tx_unit_get(tb);
204
205        sp->sending_audio = TRUE;
206        sp->auto_lecture = 1;                /* Turn off */
207        sd_reset(tb->sd_info);
208        agc_reset(tb->agc);
209}
210
211void
212tx_stop(session_struct *sp)
213{
214        struct timeval tv;
215
216        if (sp->sending_audio == FALSE || sp->have_device == FALSE)
217                return;
218        sp->sending_audio              = FALSE;
219        sp->last_tx_service_productive = 0;
220        sp->transmit_audit_required    = TRUE;
221        gettimeofday(&tv, NULL);
222        sp->auto_lecture               = tv.tv_sec;
223        channel_encoder_reset(sp,sp->cc_encoding);
224        ui_input_level(0);
225        ui_info_deactivate(sp->db->my_dbe);
226}
227
228tx_buffer *
229tx_create(session_struct *sp, u_int16 unit_dur, u_int16 channels)
230{
231        tx_buffer *tb;
232
233        tb = (tx_buffer*)xmalloc(sizeof(tx_buffer));
234        memset(tb, 0, sizeof(tx_buffer));
235
236        tb->clock    = sp->device_clock;
237        tb->sd_info  = sd_init    (unit_dur, (u_int16)get_freq(tb->clock));
238        tb->vad      = vad_create (unit_dur, (u_int16)get_freq(tb->clock));
239        tb->agc      = agc_create(sp);
240        tb->unit_dur = unit_dur;
241        tb->channels = channels;
242
243        if (sp->mode != TRANSCODER) {
244                audio_drain(sp->audio_fd);
245                audio_read(sp->audio_fd, dummy_buf, DEVICE_REC_BUF);
246        }
247
248        return (tb);
249}
250
251void
252tx_destroy(session_struct *sp)
253{
254        tx_buffer *tb;
255        tx_unit *u, *u_next;
256
257        tb = sp->tb;
258
259        sd_destroy(tb->sd_info);
260        vad_destroy(tb->vad);
261        agc_destroy(tb->agc);
262
263        u = tb->head_ptr;
264        while(u) {
265                u_next = u->next;
266                tx_unit_destroy(u);
267                u = u_next;
268        }
269
270        u = tb->spare_ptr;
271        while(u) {
272                u_next = u->next;
273                tx_unit_destroy(u);
274                u = u_next;
275        }
276
277        xfree(tb);
278        sp->tb = NULL;
279
280        clear_encoder_states    (&sp->state_list);
281        clear_cc_encoder_states (&sp->cc_state_list);
282}
283
284int
285tx_read_audio(session_struct *sp)
286{
287        tx_unit         *u;
288        unsigned int     read_dur = 0;
289
290        if (sp->sending_audio) {
291                do {
292                        u = sp->tb->last_ptr;
293                        assert(u);
294                        u->dur_used += audio_device_read(sp, u->data + u->dur_used * sp->tb->channels,
295                                                         (sp->tb->unit_dur - u->dur_used) * sp->tb->channels) / sp->tb->channels;
296                        if (u->dur_used == sp->tb->unit_dur) {
297                                read_dur += sp->tb->unit_dur;
298                                time_advance(sp->clock, get_freq(sp->tb->clock), sp->tb->unit_dur);
299                                sp->tb->last_ptr = tx_unit_get(sp->tb);
300                                u->next = sp->tb->last_ptr;
301                                u->next->prev = u;
302                        }
303                } while (u->dur_used == sp->tb->unit_dur);
304        } else {
305                if (sp->have_device) {
306                        /* We're not sending, but have access to the audio device. Read the audio anyway. */
307                        /* to get exact timing values, and then throw the data we've just read away...    */
308                        read_dur = audio_device_read(sp, dummy_buf, DEVICE_REC_BUF) / sp->tb->channels;
309                        time_advance(sp->clock, get_freq(sp->tb->clock), read_dur);
310                } else {
311                        /* Fake the timing using gettimeofday... We don't have the audio device, so this */
312                        /* can't rely on any of the values in sp->tb                                     */
313                        /* This is hard-coded to 8kHz right now! */
314                        struct timeval  curr_time;
315
316                        gettimeofday(&curr_time, NULL);
317                        read_dur = ((u_int32)((curr_time.tv_sec - sp->device_time.tv_sec) * 1e6)
318                                + (curr_time.tv_usec - sp->device_time.tv_usec)) / 125;
319                        sp->device_time = curr_time;
320                        if (read_dur > DEVICE_REC_BUF) {
321                                read_dur = DEVICE_REC_BUF;
322                        }
323                        memset(dummy_buf, 0, DEVICE_REC_BUF * BYTES_PER_SAMPLE);
324                        time_advance(sp->clock, 8000, read_dur);
325                }
326        }
327        return read_dur;
328}
329
330int
331tx_process_audio(session_struct *sp)
332{
333        tx_unit *u, *u_mark;
334        int to_send;
335
336        tx_buffer *tb = sp->tb;
337
338        if (tb->silence_ptr == NULL) {
339                tb->silence_ptr = tb->head_ptr;
340        }
341
342        for(u = tb->silence_ptr; u != tb->last_ptr; u = u->next) {
343                audio_unbias(sp->bc, u->data, u->dur_used * tb->channels);
344                u->energy = avg_audio_energy(u->data, u->dur_used * tb->channels, tb->channels);
345                u->send   = FALSE;
346               
347                /* we do silence detection and voice activity detection
348                 * all the time.  agc depends on them and they are all
349                 * cheap.
350                 */
351                u->silence = sd(tb->sd_info, (u_int16)u->energy);
352                to_send    = vad_to_get(tb->vad, (u_char)u->silence, (u_char)((sp->lecture) ? VAD_MODE_LECT : VAD_MODE_CONF));           
353                agc_update(tb->agc, (u_int16)u->energy, vad_talkspurt_no(tb->vad));
354
355                if (sp->detect_silence) {
356                        u_mark = u;
357                        while(u_mark != NULL && to_send > 0) {
358                                u_mark->send = TRUE;
359                                u_mark = u_mark->prev;
360                                to_send --;
361                        }
362                } else {
363                        u->silence = FALSE;
364                        u->send    = TRUE;
365                }
366        }
367        tb->silence_ptr = u;
368
369        if (sp->agc_on == TRUE &&
370            agc_apply_changes(tb->agc) == TRUE) {
371                ui_update_input_gain(sp);
372        }
373
374        if (tb->tx_ptr != NULL) {
375                tx_buffer_trim(tb);
376        }
377
378        return TRUE;
379}
380
381void
382tx_send(session_struct *sp)
383{
384        int                units, i, n, ready, send, num_encodings;
385        tx_unit               *u;
386        rtp_hdr_t       rtp_header;
387        cc_unit        *out;
388        cc_unit        *collated[MAX_ENCODINGS];
389        coded_unit      coded[MAX_ENCODINGS+1];
390        tx_buffer      *tb = sp->tb;
391        struct iovec    ovec[CC_UNITS];
392        int             ovec_elem;
393
394        if (tb->silence_ptr == NULL) {
395                /* Don't you just hate fn's that do this! */
396                return;
397        }
398
399        if (tb->tx_ptr == NULL) {
400                tb->tx_ptr = tb->head_ptr;
401        }
402
403        assert(tb->silence_ptr != NULL);
404        n = (tb->silence_ptr->time - tb->tx_ptr->time) / tb->unit_dur;
405
406        rtp_header.cc = 0;
407
408/*
409        if (sp->mode == TRANSCODER) {
410                speaker_table        *cs;
411                for (cs = sa; cs && rtp_header.cc < 16; cs = cs->next) {
412                        if (cs->state == 2)
413                                rtp_header.csrc[rtp_header.cc++] = htonl(cs->dbe->ssrc);
414                }
415        }
416        */
417        sp->last_tx_service_productive = 0;   
418        units = collator_get_units(sp->collator);
419       
420        while(n > units) {
421                send = FALSE;
422                for (i = 0, u = tb->tx_ptr; i < units; i++, u = u->next) {
423                        if (u->send) {
424                                send = TRUE;
425                                break;
426                        }
427                }
428               
429                num_encodings = 0;
430                if (send == TRUE) {
431                        for (i = 0, u = tb->tx_ptr; i < units; i++, u=u->next) {
432                                num_encodings = 0;
433                                assert(u != tb->silence_ptr);
434                                while(num_encodings != sp->num_encodings) {
435                                        encoder(sp, u->data, sp->encodings[num_encodings], &coded[num_encodings]);
436                                        collated[num_encodings] = collate_coded_units(sp->collator, &coded[num_encodings], num_encodings);
437                                        num_encodings++;
438                                }
439                        }
440                } else {
441                        for(i=0, u = tb->tx_ptr; i < units; i++, u = u->next)
442                                assert(u != tb->silence_ptr);
443                        /* if silence we pass dummy to encoder. 
444                         * If the encoder has latency, like an
445                         * interleaver, it may need a pulse in
446                         * order to sync behaviour.
447                         */
448                        num_encodings = 0;
449                        collated[0]   = NULL;
450                }
451
452                for(i = 0; i< num_encodings; i++) assert(collated[i]->pt == sp->encodings[i]);
453                ready = channel_encode(sp, sp->cc_encoding, collated, num_encodings, &out);
454
455                if (ready && out) {
456
457                        assert(out->iovc > 0);
458
459                        /* through everything into iovec */
460                        ovec[0].iov_base = (caddr_t)&rtp_header;
461                        ovec[0].iov_len  = 12 + rtp_header.cc*4;
462                        ovec_elem        = 1 + out->iovc;
463                        assert(ovec_elem < 20);
464                        memcpy(ovec + 1, out->iov, sizeof(struct iovec) * out->iovc);
465                        rtp_header.type = 2;
466                        rtp_header.seq  = (u_int16)htons(sp->rtp_seq++);
467                        rtp_header.ts   = htonl(u->time);
468                        rtp_header.p    = rtp_header.x = 0;
469                        rtp_header.ssrc = htonl(rtcp_myssrc(sp));
470                        rtp_header.pt   = out->pt;
471                        if (ready & CC_NEW_TS) {
472                                rtp_header.m = 1;
473                                debug_msg("new talkspurt\n");
474                        } else {
475                                rtp_header.m = 0;
476                        }   
477                        sp->last_depart_ts = u->time;
478                        sp->db->pkt_count  += 1;
479                        sp->db->byte_count += get_bytes(out);
480                        sp->db->sending     = TRUE;
481                        sp->last_tx_service_productive = 1;
482                               
483                        if (sp->drop == 0.0 || drand48() >= sp->drop) {
484                                net_write_iov(sp->rtp_fd, sp->net_maddress, sp->rtp_port, ovec, ovec_elem, PACKET_RTP);
485                        }
486                }
487               
488                /* hook goes here to check for asynchonous channel coder data */
489                n -= units;
490                tb->tx_ptr = u;
491        }
492}
493
494void
495tx_update_ui(session_struct *sp)
496{
497        static int active = FALSE;
498
499        if (sp->meter && sp->tb->silence_ptr && sp->tb->silence_ptr->prev) {
500                if (vad_in_talkspurt(sp->tb->vad) == TRUE || sp->detect_silence == FALSE) {
501                        ui_input_level(lin2vu(sp->tb->silence_ptr->prev->energy, 100, VU_INPUT));
502                } else {
503                        if (active == TRUE) ui_input_level(0);
504                }
505        }
506
507        if (vad_in_talkspurt(sp->tb->vad) == TRUE || sp->detect_silence == FALSE) {
508                if (active == FALSE) {
509                        ui_info_activate(sp->db->my_dbe);
510                        sp->lecture = FALSE;
511                        ui_update_lecture_mode(sp);
512                        active = TRUE;
513                }
514        } else {
515                if (active == TRUE) {
516                        ui_info_deactivate(sp->db->my_dbe);
517                        active = FALSE;
518                }
519        }
520}
521
522void
523tx_igain_update(session_struct *sp)
524{
525        sd_reset(sp->tb->sd_info);
526        agc_reset(sp->tb->agc);
527}
Note: See TracBrowser for help on using the browser.