#include <esd.h>
#include "qemu-common.h"
#include "audio.h"
-#include <signal.h>
#define AUDIO_CAP "esd"
#include "audio_int.h"
char *dac_host;
char *adc_host;
} conf = {
- 1024,
- 2,
- NULL,
- NULL
+ .samples = 1024,
+ .divisor = 2,
};
static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
while (to_mix) {
ssize_t written;
int chunk = audio_MIN (to_mix, hw->samples - rpos);
- st_sample_t *src = hw->mix_buf + rpos;
+ struct st_sample *src = hw->mix_buf + rpos;
hw->clip (esd->pcm_buf, src, chunk);
int wsamples = written >> hw->info.shift;
int wbytes = wsamples << hw->info.shift;
if (wbytes != written) {
- dolog ("warning: Misaligned write %d (requested %d), "
+ dolog ("warning: Misaligned write %d (requested %zd), "
"alignment %d\n",
wbytes, written, hw->info.align + 1);
}
return NULL;
}
-static int qesd_run_out (HWVoiceOut *hw)
+static int qesd_run_out (HWVoiceOut *hw, int live)
{
- int live, decr;
+ int decr;
ESDVoiceOut *esd = (ESDVoiceOut *) hw;
if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
return 0;
}
- live = audio_pcm_hw_get_live_out (hw);
decr = audio_MIN (live, esd->decr);
esd->decr -= decr;
esd->live = live - decr;
return audio_pcm_sw_write (sw, buf, len);
}
-static int qesd_init_out (HWVoiceOut *hw, audsettings_t *as)
+static int qesd_init_out (HWVoiceOut *hw, struct audsettings *as)
{
ESDVoiceOut *esd = (ESDVoiceOut *) hw;
- audsettings_t obt_as = *as;
+ struct audsettings obt_as = *as;
int esdfmt = ESD_STREAM | ESD_PLAY;
- int err;
- sigset_t set, old_set;
-
- sigfillset (&set);
esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
switch (as->fmt) {
case AUD_FMT_S32:
case AUD_FMT_U32:
dolog ("Will use 16 instead of 32 bit samples\n");
-
+ /* fall through */
case AUD_FMT_S16:
case AUD_FMT_U16:
deffmt:
return -1;
}
- esd->fd = -1;
- err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
- if (err) {
- qesd_logerr (err, "pthread_sigmask failed\n");
- goto fail1;
- }
-
esd->fd = esd_play_stream (esdfmt, as->freq, conf.dac_host, NULL);
if (esd->fd < 0) {
qesd_logerr (errno, "esd_play_stream failed\n");
- goto fail2;
+ goto fail1;
}
if (audio_pt_init (&esd->pt, qesd_thread_out, esd, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err) {
- qesd_logerr (err, "pthread_sigmask(restore) failed\n");
+ goto fail2;
}
return 0;
- fail3:
+ fail2:
if (close (esd->fd)) {
qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
AUDIO_FUNC, esd->fd);
}
esd->fd = -1;
- fail2:
- err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err) {
- qesd_logerr (err, "pthread_sigmask(restore) failed\n");
- }
-
fail1:
- qemu_free (esd->pcm_buf);
+ g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
return -1;
}
audio_pt_fini (&esd->pt, AUDIO_FUNC);
- qemu_free (esd->pcm_buf);
+ g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
}
int rsamples = nread >> hw->info.shift;
int rbytes = rsamples << hw->info.shift;
if (rbytes != nread) {
- dolog ("warning: Misaligned write %d (requested %d), "
+ dolog ("warning: Misaligned write %d (requested %zd), "
"alignment %d\n",
rbytes, nread, hw->info.align + 1);
}
break;
}
- hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift,
- &nominal_volume);
+ hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift);
wpos = (wpos + chunk) % hw->samples;
to_grab -= chunk;
}
return audio_pcm_sw_read (sw, buf, len);
}
-static int qesd_init_in (HWVoiceIn *hw, audsettings_t *as)
+static int qesd_init_in (HWVoiceIn *hw, struct audsettings *as)
{
ESDVoiceIn *esd = (ESDVoiceIn *) hw;
- audsettings_t obt_as = *as;
+ struct audsettings obt_as = *as;
int esdfmt = ESD_STREAM | ESD_RECORD;
- int err;
- sigset_t set, old_set;
-
- sigfillset (&set);
esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
switch (as->fmt) {
return -1;
}
- esd->fd = -1;
-
- err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
- if (err) {
- qesd_logerr (err, "pthread_sigmask failed\n");
- goto fail1;
- }
-
esd->fd = esd_record_stream (esdfmt, as->freq, conf.adc_host, NULL);
if (esd->fd < 0) {
qesd_logerr (errno, "esd_record_stream failed\n");
- goto fail2;
+ goto fail1;
}
if (audio_pt_init (&esd->pt, qesd_thread_in, esd, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err) {
- qesd_logerr (err, "pthread_sigmask(restore) failed\n");
+ goto fail2;
}
return 0;
- fail3:
+ fail2:
if (close (esd->fd)) {
qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
AUDIO_FUNC, esd->fd);
}
esd->fd = -1;
- fail2:
- err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
- if (err) {
- qesd_logerr (err, "pthread_sigmask(restore) failed\n");
- }
-
fail1:
- qemu_free (esd->pcm_buf);
+ g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
return -1;
}
audio_pt_fini (&esd->pt, AUDIO_FUNC);
- qemu_free (esd->pcm_buf);
+ g_free (esd->pcm_buf);
esd->pcm_buf = NULL;
}
}
struct audio_option qesd_options[] = {
- {"SAMPLES", AUD_OPT_INT, &conf.samples,
- "buffer size in samples", NULL, 0},
-
- {"DIVISOR", AUD_OPT_INT, &conf.divisor,
- "threshold divisor", NULL, 0},
-
- {"DAC_HOST", AUD_OPT_STR, &conf.dac_host,
- "playback host", NULL, 0},
-
- {"ADC_HOST", AUD_OPT_STR, &conf.adc_host,
- "capture host", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
+ {
+ .name = "SAMPLES",
+ .tag = AUD_OPT_INT,
+ .valp = &conf.samples,
+ .descr = "buffer size in samples"
+ },
+ {
+ .name = "DIVISOR",
+ .tag = AUD_OPT_INT,
+ .valp = &conf.divisor,
+ .descr = "threshold divisor"
+ },
+ {
+ .name = "DAC_HOST",
+ .tag = AUD_OPT_STR,
+ .valp = &conf.dac_host,
+ .descr = "playback host"
+ },
+ {
+ .name = "ADC_HOST",
+ .tag = AUD_OPT_STR,
+ .valp = &conf.adc_host,
+ .descr = "capture host"
+ },
+ { /* End of list */ }
};
static struct audio_pcm_ops qesd_pcm_ops = {
- qesd_init_out,
- qesd_fini_out,
- qesd_run_out,
- qesd_write,
- qesd_ctl_out,
-
- qesd_init_in,
- qesd_fini_in,
- qesd_run_in,
- qesd_read,
- qesd_ctl_in,
+ .init_out = qesd_init_out,
+ .fini_out = qesd_fini_out,
+ .run_out = qesd_run_out,
+ .write = qesd_write,
+ .ctl_out = qesd_ctl_out,
+
+ .init_in = qesd_init_in,
+ .fini_in = qesd_fini_in,
+ .run_in = qesd_run_in,
+ .read = qesd_read,
+ .ctl_in = qesd_ctl_in,
};
struct audio_driver esd_audio_driver = {
- INIT_FIELD (name = ) "esd",
- INIT_FIELD (descr = )
- "http://en.wikipedia.org/wiki/Esound",
- INIT_FIELD (options = ) qesd_options,
- INIT_FIELD (init = ) qesd_audio_init,
- INIT_FIELD (fini = ) qesd_audio_fini,
- INIT_FIELD (pcm_ops = ) &qesd_pcm_ops,
- INIT_FIELD (can_be_default = ) 0,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (ESDVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (ESDVoiceIn)
+ .name = "esd",
+ .descr = "http://en.wikipedia.org/wiki/Esound",
+ .options = qesd_options,
+ .init = qesd_audio_init,
+ .fini = qesd_audio_fini,
+ .pcm_ops = &qesd_pcm_ops,
+ .can_be_default = 0,
+ .max_voices_out = INT_MAX,
+ .max_voices_in = INT_MAX,
+ .voice_size_out = sizeof (ESDVoiceOut),
+ .voice_size_in = sizeof (ESDVoiceIn)
};