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)
{