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