static guint gst_esdsink_delay (GstAudioSink * asink) { GstEsdSink *esdsink = GST_ESDSINK (asink); guint latency; latency = esd_get_latency (esdsink->ctrl_fd); if (latency == (guint) - 1) { GST_WARNING_OBJECT (asink, "couldn't get latency"); return 0; } /* latency is measured in samples at a rate of 44100, this * cannot overflow. */ latency = latency * G_GINT64_CONSTANT (44100) / esdsink->rate; GST_DEBUG_OBJECT (asink, "got latency: %u", latency); return latency; }
int AudioESound::open_output() { esd_format_t format = ESD_STREAM | ESD_PLAY; device->out_channels = 2; device->out_bits = 16; format |= get_channels_flag(device->out_channels); format |= get_bit_flag(device->out_bits); if((esd_out = esd_open_sound(translate_device_string(device->out_config->esound_out_server, device->out_config->esound_out_port))) <= 0) { fprintf(stderr, "AudioESound::open_output: open failed\n"); return 1; }; esd_out_fd = esd_play_stream_fallback(format, device->out_samplerate, translate_device_string(device->out_config->esound_out_server, device->out_config->esound_out_port), "Cinelerra"); device->device_buffer = esd_get_latency(esd_out); device->device_buffer *= device->out_bits / 8 * device->out_channels; return 0; }
/* * open & setup audio device * return: 1=success 0=fail */ static int init(int rate_hz, int channels, int format, int flags) { esd_format_t esd_fmt; int bytes_per_sample; int fl; char *server = ao_subdevice; /* NULL for localhost */ float lag_seconds, lag_net, lag_serv; struct timeval proto_start, proto_end; esd_fd = esd_open_sound(server); if (esd_fd < 0) { mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenSound, strerror(errno)); return 0; } /* get server info, and measure network latency */ gettimeofday(&proto_start, NULL); esd_svinfo = esd_get_server_info(esd_fd); if(server) { gettimeofday(&proto_end, NULL); lag_net = (proto_end.tv_sec - proto_start.tv_sec) + (proto_end.tv_usec - proto_start.tv_usec) / 1000000.0; lag_net /= 2.0; /* round trip -> one way */ } else lag_net = 0.0; /* no network lag */ /* if (esd_svinfo) { mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n"); esd_print_server_info(esd_svinfo); } */ esd_fmt = ESD_STREAM | ESD_PLAY; #if ESD_RESAMPLES /* let the esd daemon convert sample rate */ #else /* let mplayer's audio filter convert the sample rate */ if (esd_svinfo != NULL) rate_hz = esd_svinfo->rate; #endif ao_data.samplerate = rate_hz; /* EsounD can play mono or stereo */ switch (channels) { case 1: esd_fmt |= ESD_MONO; ao_data.channels = bytes_per_sample = 1; break; default: esd_fmt |= ESD_STEREO; ao_data.channels = bytes_per_sample = 2; break; } /* EsounD can play 8bit unsigned and 16bit signed native */ switch (format) { case AF_FORMAT_S8: case AF_FORMAT_U8: esd_fmt |= ESD_BITS8; ao_data.format = AF_FORMAT_U8; break; default: esd_fmt |= ESD_BITS16; ao_data.format = AF_FORMAT_S16_NE; bytes_per_sample *= 2; break; } /* modify audio_delay depending on esd_latency * latency is number of samples @ 44.1khz stereo 16 bit * adjust according to rate_hz & bytes_per_sample */ #ifdef CONFIG_ESD_LATENCY esd_latency = esd_get_latency(esd_fd); #else esd_latency = ((channels == 1 ? 2 : 1) * ESD_DEFAULT_RATE * (ESD_BUF_SIZE + 64 * (4.0f / bytes_per_sample)) ) / rate_hz; esd_latency += ESD_BUF_SIZE * 2; #endif if(esd_latency > 0) { lag_serv = (esd_latency * 4.0f) / (bytes_per_sample * rate_hz); lag_seconds = lag_net + lag_serv; audio_delay += lag_seconds; mp_msg(MSGT_AO, MSGL_INFO,MSGTR_AO_ESD_LatencyInfo, lag_serv, lag_net, lag_seconds); } esd_play_fd = esd_play_stream_fallback(esd_fmt, rate_hz, server, ESD_CLIENT_NAME); if (esd_play_fd < 0) { mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ESD_CantOpenPBStream, strerror(errno)); return 0; } /* enable non-blocking i/o on the socket connection to the esd server */ if ((fl = fcntl(esd_play_fd, F_GETFL)) >= 0) fcntl(esd_play_fd, F_SETFL, O_NDELAY|fl); #if ESD_DEBUG { int sbuf, rbuf, len; len = sizeof(sbuf); getsockopt(esd_play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len); len = sizeof(rbuf); getsockopt(esd_play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len); dprintf("esd: send/receive socket buffer space %d/%d bytes\n", sbuf, rbuf); } #endif ao_data.bps = bytes_per_sample * rate_hz; ao_data.outburst = ao_data.bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE; esd_play_start.tv_sec = 0; esd_samples_written = 0; esd_bytes_per_sample = bytes_per_sample; return 1; }