summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-10 23:05:51 +0100
committerwm4 <wm4@nowhere>2013-11-10 23:05:59 +0100
commit3cb4116243e54b0452d88c70a7acd4af17cf8d02 (patch)
treef1e97c8d9f630e81c3e7e7c4022b87952bcfcc15
parent6ec1f317654ae1e1424ec7c519cf307aae7c3efe (diff)
downloadmpv-3cb4116243e54b0452d88c70a7acd4af17cf8d02.tar.bz2
mpv-3cb4116243e54b0452d88c70a7acd4af17cf8d02.tar.xz
ao: add ao_play_silence, use for ao_alsa and ao_oss
Also add a corresponding function to audio/format.c, which fills an audio block with silence.
-rw-r--r--audio/format.c6
-rw-r--r--audio/format.h5
-rw-r--r--audio/out/ao.c12
-rw-r--r--audio/out/ao.h2
-rw-r--r--audio/out/ao_alsa.c8
-rw-r--r--audio/out/ao_oss.c11
6 files changed, 31 insertions, 13 deletions
diff --git a/audio/format.c b/audio/format.c
index b933d07e16..448b670671 100644
--- a/audio/format.c
+++ b/audio/format.c
@@ -127,3 +127,9 @@ int af_str2fmt_short(bstr str)
}
return 0;
}
+
+void af_fill_silence(void *dst, size_t bytes, int format)
+{
+ bool us = (format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_US;
+ memset(dst, us ? 0x80 : 0, bytes);
+}
diff --git a/audio/format.h b/audio/format.h
index 3a80a601c5..95e792340c 100644
--- a/audio/format.h
+++ b/audio/format.h
@@ -134,6 +134,9 @@ enum af_format {
(AF_FORMAT_IS_AC3(fmt) || \
((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_S_IEC61937)
+#define AF_FORMAT_IS_SPECIAL(fmt) \
+ ((fmt & AF_FORMAT_SPECIAL_MASK) != 0)
+
struct af_fmt_entry {
const char *name;
int format;
@@ -152,4 +155,6 @@ int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int sampler
bool af_fmt_is_valid(int format);
+void af_fill_silence(void *dst, size_t bytes, int format);
+
#endif /* MPLAYER_AF_FORMAT_H */
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 88f0b2223d..55db34becb 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -250,6 +250,18 @@ void ao_resume(struct ao *ao)
ao->driver->resume(ao);
}
+int ao_play_silence(struct ao *ao, int samples)
+{
+ if (samples <= 0 || AF_FORMAT_IS_SPECIAL(ao->format))
+ return 0;
+ int s = ao->channels.num * (af_fmt2bits(ao->format) / 8);
+ char *p = talloc_size(NULL, samples * s);
+ af_fill_silence(p, samples * s, ao->format);
+ int r = ao_play(ao, p, samples * s, 0);
+ talloc_free(p);
+ return r;
+}
+
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map)
{
diff --git a/audio/out/ao.h b/audio/out/ao.h
index c6ad5455d2..159a6adc0f 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -103,6 +103,8 @@ void ao_reset(struct ao *ao);
void ao_pause(struct ao *ao);
void ao_resume(struct ao *ao);
+int ao_play_silence(struct ao *ao, int samples);
+
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map);
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index bdfd8fae76..5816ee5f5f 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -78,7 +78,6 @@ struct priv {
} while (0)
static float get_delay(struct ao *ao);
-static int play(struct ao *ao, void *data, int len, int flags);
static void uninit(struct ao *ao, bool immed);
static void alsa_error_handler(const char *file, int line, const char *function,
@@ -612,11 +611,8 @@ static void audio_resume(struct ao *ao)
MP_VERBOSE(ao, "resume not supported by hardware\n");
err = snd_pcm_prepare(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
- if (p->prepause_frames) {
- void *silence = calloc(p->prepause_frames, p->bytes_per_sample);
- play(ao, silence, p->prepause_frames * p->bytes_per_sample, 0);
- free(silence);
- }
+ if (p->prepause_frames)
+ ao_play_silence(ao, p->prepause_frames);
}
alsa_error: ;
diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c
index 556f3c25c9..db9847851d 100644
--- a/audio/out/ao_oss.c
+++ b/audio/out/ao_oss.c
@@ -508,16 +508,13 @@ static int play(struct ao *ao, void *data, int len, int flags)
static void audio_resume(struct ao *ao)
{
struct priv *p = ao->priv;
- int fillcnt;
#ifndef SNDCTL_DSP_RESET
reset(ao);
#endif
- fillcnt = get_space(ao) - p->prepause_space;
- if (fillcnt > 0 && !(ao->format & AF_FORMAT_SPECIAL_MASK)) {
- void *silence = calloc(fillcnt, 1);
- play(ao, silence, fillcnt, 0);
- free(silence);
- }
+ int fillframes = (get_space(ao) - p->prepause_space) /
+ (af_fmt2bits(ao->format) / 8 * ao->channels.num);
+ if (fillframes > 0)
+ ao_play_silence(ao, fillframes);
}
// return: delay in seconds between first and last sample in buffer