diff options
author | Alfred E. Heggestad <alfred.heggestad@gmail.com> | 2017-11-09 17:10:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-09 17:10:07 +0100 |
commit | a9e09b2c0a99efddfcc16f5e413e2d73aa0e1732 (patch) | |
tree | e53a738b94461189540bfe1a2c7b643b41ac488f /src/audio.c | |
parent | 4d5d9a6e4e0811b52b427602261d5e0b9bc85f21 (diff) |
add support for specifying sample format (#317)
API: ausrc and auplay
- add config items for ausrc/auplay format:
ausrc_format s16|float
auplay_format s16|float
- audio.c: convert audio samples to/from signed 16-bit
Modules:
alsa
add test for sample format FLOAT
rst: add support for FLOAT sample format
audiounit: add support for FLOAT sample format
coreaudio: check for signed 16-bit audio format
oss: check for signed 16-bit sample format
winwave: check for S16LE
pulse: add support for FLOAT sample format
sndio: check for S16 format
gst1: check sample format
aufile: check sample format
aubridge: check sample format
gst: check sample format
opensles: check for S16 sample format
jack: check sample format
alsa: remove usage of local config
test: change samples to void pointer
test: change sample type to void pointer
Diffstat (limited to 'src/audio.c')
-rw-r--r-- | src/audio.c | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/src/audio.c b/src/audio.c index 422926b..1dad716 100644 --- a/src/audio.c +++ b/src/audio.c @@ -93,6 +93,8 @@ struct autx { bool marker; /**< Marker bit for outgoing RTP */ bool muted; /**< Audio source is muted */ int cur_key; /**< Currently transmitted event */ + enum aufmt src_fmt; + bool need_conv; union { struct tmr tmr; /**< Timer for sending RTP packets */ @@ -136,6 +138,8 @@ struct aurx { int pt; /**< Payload type for incoming RTP */ double level_last; bool level_set; + enum aufmt play_fmt; + bool need_conv; }; @@ -442,7 +446,35 @@ static void poll_aubuf_tx(struct audio *a) sampc = tx->psize / 2; /* timed read from audio-buffer */ - aubuf_read_samp(tx->aubuf, tx->sampv, sampc); + + if (tx->src_fmt == AUFMT_S16LE) { + + aubuf_read(tx->aubuf, (uint8_t *)tx->sampv, + sampc * aufmt_sample_size(tx->src_fmt)); + } + else { + /* Convert from ausrc format to 16-bit format */ + + void *tmp_sampv; + size_t num_bytes = sampc * aufmt_sample_size(tx->src_fmt); + + if (!tx->need_conv) { + info("audio: NOTE: source sample conversion" + " needed: %s --> %s\n", + aufmt_name(tx->src_fmt), aufmt_name(AUFMT_S16LE)); + tx->need_conv = true; + } + + tmp_sampv = mem_zalloc(num_bytes, NULL); + if (!tmp_sampv) + return; + + aubuf_read(tx->aubuf, tmp_sampv, num_bytes); + + auconv_to_s16(sampv, tx->src_fmt, tmp_sampv, sampc); + + mem_deref(tmp_sampv); + } /* optional resampler */ if (tx->resamp.resample) { @@ -511,15 +543,18 @@ static void check_telev(struct audio *a, struct autx *tx) * * @note This function may be called from any thread * + * @note The sample format is set in rx->play_fmt + * * @param buf Buffer to fill with audio samples * @param sz Number of bytes in buffer * @param arg Handler argument */ -static void auplay_write_handler(int16_t *sampv, size_t sampc, void *arg) +static void auplay_write_handler(void *sampv, size_t sampc, void *arg) { struct aurx *rx = arg; + size_t num_bytes = sampc * aufmt_sample_size(rx->play_fmt); - aubuf_read_samp(rx->aubuf, sampv, sampc); + aubuf_read(rx->aubuf, sampv, num_bytes); } @@ -534,15 +569,16 @@ static void auplay_write_handler(int16_t *sampv, size_t sampc, void *arg) * @param sz Number of bytes in buffer * @param arg Handler argument */ -static void ausrc_read_handler(const int16_t *sampv, size_t sampc, void *arg) +static void ausrc_read_handler(const void *sampv, size_t sampc, void *arg) { struct audio *a = arg; struct autx *tx = &a->tx; + size_t num_bytes = sampc * aufmt_sample_size(tx->src_fmt); if (tx->muted) - memset((void *)sampv, 0, sampc*2); + memset((void *)sampv, 0, num_bytes); - (void)aubuf_write_samp(tx->aubuf, sampv, sampc); + (void)aubuf_write(tx->aubuf, sampv, num_bytes); if (a->cfg.txmode == AUDIO_MODE_POLL) { unsigned i; @@ -662,9 +698,39 @@ static int aurx_stream_decode(struct aurx *rx, struct mbuf *mb) sampc = sampc_rs; } - err = aubuf_write_samp(rx->aubuf, sampv, sampc); - if (err) - goto out; + if (rx->play_fmt == AUFMT_S16LE) { + err = aubuf_write_samp(rx->aubuf, sampv, sampc); + if (err) + goto out; + } + else { + + /* Convert from 16-bit to auplay format */ + + void *tmp_sampv; + size_t num_bytes = sampc * aufmt_sample_size(rx->play_fmt); + + if (!rx->need_conv) { + info("audio: NOTE: playback sample conversion" + " needed: %s --> %s\n", + aufmt_name(AUFMT_S16LE), + aufmt_name(rx->play_fmt)); + rx->need_conv = true; + } + + tmp_sampv = mem_zalloc(num_bytes, NULL); + if (!tmp_sampv) + return ENOMEM; + + auconv_from_s16(rx->play_fmt, tmp_sampv, sampv, sampc); + + err = aubuf_write(rx->aubuf, tmp_sampv, num_bytes); + + mem_deref(tmp_sampv); + + if (err) + goto out; + } out: return err; @@ -801,6 +867,9 @@ int audio_alloc(struct audio **ap, const struct stream_param *stream_prm, tx = &a->tx; rx = &a->rx; + tx->src_fmt = cfg->audio.src_fmt; + rx->play_fmt = cfg->audio.play_fmt; + err = stream_alloc(&a->strm, stream_prm, &cfg->avt, call, sdp_sess, "audio", label, mnat, mnat_sess, menc, menc_sess, @@ -845,8 +914,8 @@ int audio_alloc(struct audio **ap, const struct stream_param *stream_prm, } tx->mb = mbuf_alloc(STREAM_PRESZ + 4096); - tx->sampv = mem_zalloc(AUDIO_SAMPSZ * 2, NULL); - rx->sampv = mem_zalloc(AUDIO_SAMPSZ * 2, NULL); + tx->sampv = mem_zalloc(AUDIO_SAMPSZ * sizeof(int16_t), NULL); + rx->sampv = mem_zalloc(AUDIO_SAMPSZ * sizeof(int16_t), NULL); if (!tx->mb || !tx->sampv || !rx->sampv) { err = ENOMEM; goto out; @@ -1113,11 +1182,13 @@ static int start_player(struct aurx *rx, struct audio *a) prm.srate = srate_dsp; prm.ch = channels_dsp; prm.ptime = rx->ptime; + prm.fmt = rx->play_fmt; if (!rx->aubuf) { size_t psize; + size_t sz = aufmt_sample_size(rx->play_fmt); - psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime); + psize = sz * calc_nsamp(prm.srate, prm.ch, prm.ptime); err = aubuf_alloc(&rx->aubuf, psize * 1, psize * 8); if (err) @@ -1135,6 +1206,9 @@ static int start_player(struct aurx *rx, struct audio *a) } rx->auplay_prm = prm; + + info("audio: player started with sample format %s\n", + aufmt_name(rx->play_fmt)); } return 0; @@ -1192,6 +1266,7 @@ static int start_source(struct autx *tx, struct audio *a) prm.srate = srate_dsp; prm.ch = channels_dsp; prm.ptime = tx->ptime; + prm.fmt = tx->src_fmt; tx->psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime); @@ -1237,6 +1312,9 @@ static int start_source(struct autx *tx, struct audio *a) } tx->ausrc_prm = prm; + + info("audio: source started with sample format %s\n", + aufmt_name(tx->src_fmt)); } return 0; @@ -1627,7 +1705,9 @@ int audio_debug(struct re_printf *pf, const struct audio *a) aubuf_debug, tx->aubuf, tx->ptime); - err |= re_hprintf(pf, " rx: %H %H ptime=%ums pt=%d\n", + err |= re_hprintf(pf, + " rx: %H %H\n" + " ptime=%ums pt=%d\n", aucodec_print, rx->ac, aubuf_debug, rx->aubuf, rx->ptime, rx->pt); |