diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp index 3a50c82f0d..b763502fa8 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp @@ -2480,348 +2480,6 @@ int gsmopen_senddigit(private_t *tech_pvt, char digit) return 0; } -#ifdef GSMOPEN_ALSA -/*! \brief Write audio frames to interface */ -int alsa_write(private_t *tech_pvt, short *data, int datalen) -{ - static char sizbuf[8000]; - static char sizbuf2[16000]; - static char silencebuf[8000]; - static int sizpos = 0; - int len = sizpos; - int pos; - int res = 0; - time_t now_timestamp; - /* size_t frames = 0; */ - snd_pcm_state_t state; - snd_pcm_sframes_t delayp1 = 0; - snd_pcm_sframes_t delayp2 = 0; - - if (tech_pvt->no_sound == 1) { - return res; - } - - memset(sizbuf, 255, sizeof(sizbuf)); - memset(sizbuf2, 255, sizeof(sizbuf)); - memset(silencebuf, 255, sizeof(sizbuf)); - - //ERRORA("data=%p, datalen=%d\n", GSMOPEN_P_LOG, (void *)data, datalen); - /* We have to digest the frame in 160-byte portions */ - if (datalen > sizeof(sizbuf) - sizpos) { - ERRORA("Frame too large\n", GSMOPEN_P_LOG); - res = -1; - } else { - memcpy(sizbuf + sizpos, data, datalen); - memset(data, 255, datalen); - len += datalen; - pos = 0; - -#ifdef ALSA_MONITOR - alsa_monitor_write(sizbuf, len); -#endif - state = snd_pcm_state(tech_pvt->alsap); - if (state == SND_PCM_STATE_XRUN) { - int i; - - DEBUGA_GSMOPEN - ("You've got an ALSA write XRUN in the past (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } else { - res = snd_pcm_format_set_silence(gsmopen_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Silence error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - for (i = 0; i < (tech_pvt->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_writei(tech_pvt->alsap, silencebuf, len / 2); - if (res != len / 2) { - DEBUGA_GSMOPEN("Write returned a different quantity: %d\n", GSMOPEN_P_LOG, res); - res = -1; - } else if (res < 0) { - DEBUGA_GSMOPEN("Write error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - } - } - - } - - res = snd_pcm_delay(tech_pvt->alsap, &delayp1); - if (res < 0) { - DEBUGA_GSMOPEN("Error %d on snd_pcm_delay: \"%s\"\n", GSMOPEN_P_LOG, res, snd_strerror(res)); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN("snd_pcm_prepare failed: '%s'\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_delay(tech_pvt->alsap, &delayp1); - } - - delayp2 = snd_pcm_avail_update(tech_pvt->alsap); - if (delayp2 < 0) { - DEBUGA_GSMOPEN("Error %d on snd_pcm_avail_update: \"%s\"\n", GSMOPEN_P_LOG, (int) delayp2, snd_strerror(delayp2)); - - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN("snd_pcm_prepare failed: '%s'\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - delayp2 = snd_pcm_avail_update(tech_pvt->alsap); - } - - if ( /* delayp1 != 0 && delayp1 != 160 */ - delayp1 < 160 || delayp2 > tech_pvt->alsa_buffer_size) { - - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - DEBUGA_GSMOPEN - ("snd_pcm_prepare failed while trying to prevent an ALSA write XRUN: %s, delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, snd_strerror(res), (int) delayp1, (int) delayp2); - } else { - - int i; - for (i = 0; i < (tech_pvt->alsa_periods_in_buffer - 1); i++) { - res = snd_pcm_format_set_silence(gsmopen_format, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Silence error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } - res = snd_pcm_writei(tech_pvt->alsap, silencebuf, len / 2); - if (res < 0) { - DEBUGA_GSMOPEN("Write error %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - res = -1; - } else if (res != len / 2) { - DEBUGA_GSMOPEN("Write returned a different quantity: %d\n", GSMOPEN_P_LOG, res); - res = -1; - } - } - - DEBUGA_GSMOPEN - ("PREVENTING an ALSA write XRUN (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - } - - } - - memset(sizbuf2, 0, sizeof(sizbuf2)); - if (tech_pvt->alsa_play_is_mono) { - res = snd_pcm_writei(tech_pvt->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - sizbuf2[a] = sizbuf[i]; // comment out this line to use only left - a++; - i++; - } - res = snd_pcm_writei(tech_pvt->alsap, sizbuf2, len); - } - if (res == -EPIPE) { - DEBUGA_GSMOPEN - ("ALSA write EPIPE (XRUN) (gsmopen can't fill the soundcard buffer fast enough). If this happens often (not after silence or after a pause in the speech, that's OK), and appear to damage the sound quality, first check if you have some IRQ problem, maybe sharing the soundcard IRQ with a broken or heavy loaded ethernet or graphic card. Then consider to increase the alsa_periods_in_buffer (now is set to %d) for this interface in the config file. delayp1=%d, delayp2=%d\n", - GSMOPEN_P_LOG, tech_pvt->alsa_periods_in_buffer, (int) delayp1, (int) delayp2); - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } else { - - if (tech_pvt->alsa_play_is_mono) { - res = snd_pcm_writei(tech_pvt->alsap, sizbuf, len / 2); - } else { - int a = 0; - int i = 0; - for (i = 0; i < 8000;) { - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i--; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - sizbuf2[a] = sizbuf[i]; - a++; - i++; - } - res = snd_pcm_writei(tech_pvt->alsap, sizbuf2, len); - } - - } - - } else { - if (res == -ESTRPIPE) { - ERRORA("You've got some big problems\n", GSMOPEN_P_LOG); - } else if (res == -EAGAIN) { - DEBUGA_GSMOPEN("Momentarily busy\n", GSMOPEN_P_LOG); - res = 0; - } else if (res < 0) { - ERRORA("Error %d on audio write: \"%s\"\n", GSMOPEN_P_LOG, res, snd_strerror(res)); - } - } - } - - if (tech_pvt->audio_play_reset_period) { - time(&now_timestamp); - if ((now_timestamp - tech_pvt->audio_play_reset_timestamp) > tech_pvt->audio_play_reset_period) { - if (option_debug) - DEBUGA_GSMOPEN("reset audio play\n", GSMOPEN_P_LOG); - res = snd_pcm_wait(tech_pvt->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_drop(tech_pvt->alsap); - if (res) { - ERRORA("audio play drop failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_prepare(tech_pvt->alsap); - if (res) { - ERRORA("audio play prepare failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - res = snd_pcm_wait(tech_pvt->alsap, 1000); - if (res < 0) { - ERRORA("audio play wait failed: %s\n", GSMOPEN_P_LOG, snd_strerror(res)); - } - time(&tech_pvt->audio_play_reset_timestamp); - } - } - //res = 0; - //if (res > 0) - //res = 0; - return res; -} - -#define AST_FRIENDLY_OFFSET 0 -int alsa_read(private_t *tech_pvt, short *data, int datalen) -{ - //static struct ast_frame f; - static short __buf[GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2]; - static short __buf2[(GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2]; - short *buf; - short *buf2; - static int readpos = 0; - //static int left = GSMOPEN_FRAME_SIZE; - static int left; - snd_pcm_state_t state; - int r = 0; - int off = 0; - int error = 0; - //time_t now_timestamp; - - //DEBUGA_GSMOPEN("buf=%p, datalen=%d, left=%d\n", GSMOPEN_P_LOG, (void *)buf, datalen, left); - //memset(&f, 0, sizeof(struct ast_frame)); //giova - - if (tech_pvt->no_sound == 1) { - return r; - } - - left = datalen; - - state = snd_pcm_state(tech_pvt->alsac); - if (state != SND_PCM_STATE_RUNNING) { - DEBUGA_GSMOPEN("ALSA read state is not SND_PCM_STATE_RUNNING\n", GSMOPEN_P_LOG); - - if (state != SND_PCM_STATE_PREPARED) { - error = snd_pcm_prepare(tech_pvt->alsac); - if (error) { - ERRORA("snd_pcm_prepare failed, %s\n", GSMOPEN_P_LOG, snd_strerror(error)); - return r; - } - DEBUGA_GSMOPEN("prepared!\n", GSMOPEN_P_LOG); - } - gsmopen_sleep(1000); - error = snd_pcm_start(tech_pvt->alsac); - if (error) { - ERRORA("snd_pcm_start failed, %s\n", GSMOPEN_P_LOG, snd_strerror(error)); - return r; - } - DEBUGA_GSMOPEN("started!\n", GSMOPEN_P_LOG); - gsmopen_sleep(1000); - } - - buf = __buf + AST_FRIENDLY_OFFSET / 2; - buf2 = __buf2 + ((AST_FRIENDLY_OFFSET / 2) * 2); - - if (tech_pvt->alsa_capture_is_mono) { - r = snd_pcm_readi(tech_pvt->alsac, buf + readpos, left); - //DEBUGA_GSMOPEN("r=%d, buf=%p, buf+readpos=%p, datalen=%d, left=%d\n", GSMOPEN_P_LOG, r, (void *)buf, (void *)(buf + readpos), datalen, left); - } else { - int a = 0; - int i = 0; - r = snd_pcm_readi(tech_pvt->alsac, buf2 + (readpos * 2), left); - - for (i = 0; i < (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; //comment out this line to use only left - //__buf[a] = __buf2[i]; // enable this line to use only left - a++; - i++; - i++; - } - } - - if (r == -EPIPE) { - DEBUGA_GSMOPEN("ALSA XRUN on read\n", GSMOPEN_P_LOG); - return r; - } else if (r == -ESTRPIPE) { - ERRORA("-ESTRPIPE\n", GSMOPEN_P_LOG); - return r; - - } else if (r == -EAGAIN) { - int count = 0; - while (r == -EAGAIN) { - gsmopen_sleep(10000); - DEBUGA_GSMOPEN("%d ALSA read -EAGAIN, the soundcard is not ready to be read by gsmopen\n", GSMOPEN_P_LOG, count); - count++; - - if (tech_pvt->alsa_capture_is_mono) { - r = snd_pcm_readi(tech_pvt->alsac, buf + readpos, left); - } else { - int a = 0; - int i = 0; - r = snd_pcm_readi(tech_pvt->alsac, buf2 + (readpos * 2), left); - - for (i = 0; i < (GSMOPEN_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2) * 2;) { - __buf[a] = (__buf2[i] + __buf2[i + 1]) / 2; - a++; - i++; - i++; - } - } - - } - } else if (r < 0) { - WARNINGA("ALSA Read error: %s\n", GSMOPEN_P_LOG, snd_strerror(r)); - } else if (r >= 0) { - //DEBUGA_GSMOPEN("read: r=%d, readpos=%d, left=%d, off=%d\n", GSMOPEN_P_LOG, r, readpos, left, off); - off -= r; //what is the meaning of this? a leftover, probably - } - /* Update positions */ - readpos += r; - left -= r; - - if (readpos >= GSMOPEN_FRAME_SIZE) { - int i; - /* A real frame */ - readpos = 0; - left = GSMOPEN_FRAME_SIZE; - for (i = 0; i < r; i++) - data[i] = buf[i]; - - } - return r; -} - -#endif // GSMOPEN_ALSA int gsmopen_sendsms(private_t *tech_pvt, char *dest, char *text) {