File: transcoder.c

package info (click to toggle)
rat 4.2.22-2.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,896 kB
  • ctags: 3,717
  • sloc: ansic: 36,542; tcl: 2,740; sh: 2,675; makefile: 295
file content (139 lines) | stat: -rw-r--r-- 3,816 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * FILE:     transcoder.c
 * PROGRAM:  Rat
 * AUTHOR:   Colin Perkins
 *
 * Based on auddev_mux.c, revision 1.11
 *
 * Copyright (C) 1996-2001 University College London
 * All rights reserved.
 */
 
#ifndef HIDE_SOURCE_STRINGS
static const char cvsid[] = 
	"$Id: transcoder.c,v 1.13 2001/01/08 20:30:11 ucaccsp Exp $";
#endif /* HIDE_SOURCE_STRINGS */

#include "config_unix.h"
#include "config_win32.h"
#include "memory.h"
#include "audio_types.h"
#include "transcoder.h"

#define CHANNEL_SIZE  	8192
#define NUM_CHANNELS 	2

static int             num_open_channels = 0;
static sample         *channel[NUM_CHANNELS+1];
static int             head[NUM_CHANNELS+1];
static int             tail[NUM_CHANNELS+1];
static struct timeval  last_time[NUM_CHANNELS+1];
static struct timeval  curr_time[NUM_CHANNELS+1];
static int             first_time[NUM_CHANNELS+1];

int
transcoder_open(void)
{
  /* Open a fake audio channel. The value we return is used to identify the */
  /* channel for the other routines in this module. The #ifdefs in net.c    */
  /* prevent it being used in a select().                                   */
  /* Note: We must open EXACTLY two channels, before the other routines in  */
  /*       this module function correctly.                                  */
  int id, i;

  assert((num_open_channels >= 0) && (num_open_channels < NUM_CHANNELS));
  id = ++num_open_channels;
  head[id]       = 0;
  tail[id]       = 0;
  first_time[id] = 0;
  channel[id] = (sample *) xmalloc(CHANNEL_SIZE * sizeof(sample));
  for (i=0; i<CHANNEL_SIZE; i++) {
    channel[id][i] = L16_AUDIO_ZERO;
  }
  return id;
}

void
transcoder_close(int id)
{
  assert(num_open_channels > 0);
  assert(id > 0 && id <= num_open_channels);
  xfree(channel[id]);
  num_open_channels--;
}

int
transcoder_read(int id, sample *buf, int buf_size)
{
  int i, read_size, copy_size;

  assert(buf != 0);
  assert(buf_size > 0);
  assert(id > 0 && id <= num_open_channels);
  assert(head[id] <= CHANNEL_SIZE);
  assert(tail[id] <= CHANNEL_SIZE);
  assert(head[id] <= tail[id]);
  
  if (first_time[id] == 0) {
    gettimeofday(&last_time[id], NULL);
    first_time[id] = 1;
  }
  gettimeofday(&curr_time[id], NULL);
  read_size = (((curr_time[id].tv_sec - last_time[id].tv_sec) * 1000000) + (curr_time[id].tv_usec - last_time[id].tv_usec)) / 125;
  if (read_size > buf_size) read_size = buf_size;
  for (i=0; i<read_size; i++) {
    buf[i] = L16_AUDIO_ZERO;
  }
  last_time[id] = curr_time[id];

  copy_size = tail[id] - head[id];	/* The amount of data available in this module... */
  if (copy_size >= read_size) {
    copy_size = read_size;
  } else {
#ifdef DEBUG_TRANSCODER
    printf("transcoder_read: underflow, silence substituted -- want %d got %d channel %d\n", read_size, copy_size, id);
#endif
  }
  assert((head[id] + copy_size) <= tail[id]);
  for (i=0; i<copy_size; i++) {
    buf[i] = channel[id][head[id] + i];
  }
  head[id] += copy_size;

  assert(head[id] <= CHANNEL_SIZE);
  assert(tail[id] <= CHANNEL_SIZE);
  assert(head[id] <= tail[id]);
  return read_size;
}

int
transcoder_write(int id, sample *buf, int buf_size)
{
  int i;

  assert(buf != 0);
  assert(buf_size > 0);
  assert(id > 0 && id <= num_open_channels);
  assert(head[id] <= CHANNEL_SIZE);
  assert(tail[id] <= CHANNEL_SIZE);
  assert(head[id] <= tail[id]);

  if ((tail[id] + buf_size) > CHANNEL_SIZE) {
    for (i=0; i < (CHANNEL_SIZE - head[id]); i++) {
      channel[id][i] = channel[id][i + head[id]];
    }
    tail[id] -= head[id];
    head[id]  = 0;
  }
  assert((tail[id] + buf_size) <= CHANNEL_SIZE);

  for (i=0; i<buf_size; i++) {
    channel[id][tail[id] + i] = buf[i];
  }
  tail[id] += buf_size;
  assert(head[id] <= CHANNEL_SIZE);
  assert(tail[id] <= CHANNEL_SIZE);
  assert(head[id] <= tail[id]);
  return buf_size;
}