00001 #include "audio.h"
00002 #include "helper.h"
00003
00004 #include <iostream>
00005
00006 #include <sys/ioctl.h>
00007 #include <arpa/inet.h>
00008 #include <asm/elphel/hist.h>
00009
00010 #include <asm/elphel/c313a.h>
00011 #include <asm/elphel/hist.h>
00012 #include <asm/elphel/ext353.h>
00013 #undef AUDIO_DEBUG
00014
00015
00016 #ifdef AUDIO_DEBUG
00017 #define D(a) a
00018 #else
00019 #define D(a)
00020 #endif
00021
00022 using namespace std;
00023
00024
00025
00026 Audio::Audio(bool enable, int sample_rate, int channels) {
00027 snd_pcm_hw_params_t *hw_params;
00028 _present = false;
00029 rtc_fd = 0;
00030 stream_name = "audio";
00031
00032
00033 if(sample_rate == 0)
00034 sample_rate = SAMPLE_RATE;
00035 if(sample_rate > 48000)
00036 sample_rate = 48000;
00037 if(sample_rate < 11025)
00038 sample_rate = 11025;
00039 if(channels == 0)
00040 channels = SAMPLE_CHANNELS;
00041 if(channels < 1)
00042 channels = 1;
00043 if(channels > 2)
00044 channels = 2;
00045
00046 SSRC = 10;
00047 _sample_rate = sample_rate;
00048 _channels = channels;
00049
00050
00051
00052 long sample_time = 20;
00053 sbuffer_len = _sample_rate * 2 * _channels * sample_time;
00054 sbuffer_len /= 1000;
00055 sbuffer_len -= sbuffer_len % 2;
00056 D(cerr << "sbuffer_len == " << sbuffer_len << endl;)
00057 _ptype = 97;
00058
00059 if(enable) {
00060
00061 int err;
00062 sbuffer = (short *)malloc(sbuffer_len * sizeof(short) * 8);
00063 if((err = snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0)
00064 return;
00065 if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
00066 return;
00067 if((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0)
00068 return;
00069 if((err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
00070 return;
00071 if((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_BE)) < 0)
00072 return;
00073 unsigned int t = _sample_rate;
00074 if((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &t, 0)) < 0)
00075 return;
00076 _sample_rate = t;
00077 if((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, _channels)) < 0)
00078 return;
00079 if((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0)
00080 return;
00081 snd_pcm_hw_params_free (hw_params);
00082 if((err = snd_pcm_prepare(capture_handle)) < 0)
00083 return;
00084
00085 D( cerr << endl << "Audio init: ok; with sample rate: " << _sample_rate << "; and channels: " << _channels << endl;)
00086 _present = true;
00087
00088 _play = false;
00089
00090 init_pthread((void *)this);
00091 }
00092 }
00093
00094 Audio::~Audio(void) {
00095 if(_present)
00096 snd_pcm_close(capture_handle);
00097 if(rtc_fd)
00098 close(rtc_fd);
00099 }
00100
00101 void Audio::Start(string ip, long port) {
00102 if(!_present)
00103 return;
00104 D(cerr << "Audio ---> Start !!!" << endl;)
00105
00106
00107
00108
00109
00110 unsigned long rtc[4];
00111 ioctl(fd_stream, _IO(IOC_STREAM_GET_TIME, 0x00), (void *)&rtc[0]);
00112 f_tv.tv_sec = rtc[2];
00113 f_tv.tv_usec = rtc[3];
00114 RTP_Stream::Start(ip, port);
00115 }
00116
00117 void Audio::Stop(void) {
00118 if(!_present)
00119 return;
00120 D(cerr << "Audio ---> Stop !!!" << endl;)
00121 RTP_Stream::Stop();
00122 f_tv.tv_sec = 0;
00123 f_tv.tv_usec = 0;
00124
00125 }
00126
00127 long Audio::capture(void) {
00128
00129 long slen = sbuffer_len;
00130
00131 if((slen = snd_pcm_readi(capture_handle, sbuffer, sbuffer_len)) <= 0)
00132
00133 snd_pcm_prepare(capture_handle);
00134 else {
00135 if(f_tv.tv_sec == 0) {
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 }
00167 }
00168
00169 return slen;
00170 }
00171
00172
00173 long Audio::process(void) {
00174
00175 long sample_len;
00176 if((sample_len = capture()) <= 0) {
00177 D( cerr << "nothing to send" << endl;)
00178
00179 return sample_len;
00180 }
00181
00182
00183 static unsigned short packet_num = 0;
00184 unsigned short pnum;
00185
00186
00187
00188
00189
00190 struct timeval t;
00191 t.tv_sec = 0;
00192 long long usec = sample_len;
00193 usec *= 1000000;
00194 usec /= _sample_rate;
00195
00196
00197 t.tv_usec = usec;
00198 f_tv = time_plus(f_tv, t);
00199
00200
00201
00202
00203
00204 unsigned long ts;
00205 float f = f_tv.tv_usec;
00206 f /= 1000000;
00207 f += f_tv.tv_sec;
00208 f *= _sample_rate;
00209 timestamp = (unsigned long)f;
00210
00211 ts = htonl(timestamp);
00212
00213
00214
00215
00216
00217
00218 void *m = (void *)sbuffer;
00219
00220
00221 int i;
00222 long offset = 0;
00223 #define LEN 1200
00224 unsigned char d[LEN + 20];
00225 int chunk = LEN;
00226 int to_send = sample_len * 2 * _channels;
00227 int size = to_send;
00228 long count = 0;
00229 for(;;) {
00230 if(to_send == 0)
00231 break;
00232 if(to_send > chunk) {
00233 i = chunk;
00234 to_send -= i;
00235 } else {
00236 i = to_send;
00237 to_send = 0;
00238 }
00239 packet_num++;
00240 pnum = htons(packet_num);
00241 count += i;
00242
00243 d[0] = 0x80;
00244 if(count >= size)
00245 d[1] = _ptype + 0x80;
00246 else
00247 d[1] = _ptype;
00248 memcpy((void *)&d[2], (void *)&pnum, 2);
00249 memcpy((void *)&d[4], (void *)&ts, 4);
00250 memcpy((void *)&d[8], (void *)&SSRC, 4);
00251
00252 memcpy((void *)&d[12], (void *)((char *)m + offset), i);
00253 offset += i;
00254
00255 rtp_packets++;
00256 rtp_octets += i;
00257 rtp_socket->send((void *)d, i + 12);
00258 }
00259
00260 return true;
00261 }