summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2013-09-28 18:01:12 +0200
committerwm4 <wm4@nowhere>2013-10-03 23:14:03 +0200
commit32894736780ea63e5fea456de27650fc27ec57c6 (patch)
treea72fe21baacc223136b313c66717069172400722 /stream
parentbdc56771eb8fa06f47599d90370017a6791e631b (diff)
downloadmpv-32894736780ea63e5fea456de27650fc27ec57c6.tar.bz2
mpv-32894736780ea63e5fea456de27650fc27ec57c6.tar.xz
audio/out: add sndio support
Based on an earlier patch for mplayer by Alexandre Ratchov <alex@caoua.org>
Diffstat (limited to 'stream')
-rw-r--r--stream/ai_sndio.c49
-rw-r--r--stream/audio_in.c59
-rw-r--r--stream/audio_in.h19
3 files changed, 127 insertions, 0 deletions
diff --git a/stream/ai_sndio.c b/stream/ai_sndio.c
new file mode 100644
index 0000000000..b486bb9210
--- /dev/null
+++ b/stream/ai_sndio.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#include <sndio.h>
+#include "audio_in.h"
+#include "mpvcore/mp_msg.h"
+
+int ai_sndio_setup(audio_in_t *ai)
+{
+ struct sio_par par;
+
+ sio_initpar(&par);
+
+ par.bits = 16;
+ par.sig = 1;
+ par.le = 1;
+ par.rchan = ai->req_channels;
+ par.rate = ai->req_samplerate;
+ par.appbufsz = ai->req_samplerate; /* 1 sec */
+
+ if (!sio_setpar(ai->sndio.hdl, &par) || !sio_getpar(ai->sndio.hdl, &par)) {
+ mp_msg(MSGT_TV, MSGL_ERR, "could not configure sndio audio");
+ return -1;
+ }
+
+ ai->channels = par.rchan;
+ ai->samplerate = par.rate;
+ ai->samplesize = par.bits;
+ ai->bytes_per_sample = par.bps;
+ ai->blocksize = par.round * par.bps;
+
+ return 0;
+}
+
+int ai_sndio_init(audio_in_t *ai)
+{
+ int err;
+
+ if ((ai->sndio.hdl = sio_open(ai->sndio.device, SIO_REC, 0)) == NULL) {
+ mp_msg(MSGT_TV, MSGL_ERR, "could not open sndio audio");
+ return -1;
+ }
+
+ err = ai_sndio_setup(ai);
+
+ return err;
+}
diff --git a/stream/audio_in.c b/stream/audio_in.c
index cc54e87800..420311e848 100644
--- a/stream/audio_in.c
+++ b/stream/audio_in.c
@@ -53,6 +53,12 @@ int audio_in_init(audio_in_t *ai, int type)
ai->oss.device = strdup("/dev/dsp");
return 0;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ ai->sndio.hdl = NULL;
+ ai->sndio.device = strdup("default");
+ return 0;
+#endif
default:
return -1;
}
@@ -74,6 +80,12 @@ int audio_in_setup(audio_in_t *ai)
ai->setup = 1;
return 0;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ if (ai_sndio_init(ai) < 0) return -1;
+ ai->setup = 1;
+ return 0;
+#endif
default:
return -1;
}
@@ -96,6 +108,13 @@ int audio_in_set_samplerate(audio_in_t *ai, int rate)
if (ai_oss_set_samplerate(ai) < 0) return -1;
return ai->samplerate;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ ai->req_samplerate = rate;
+ if (!ai->setup) return 0;
+ if (ai_sndio_setup(ai) < 0) return -1;
+ return ai->samplerate;
+#endif
default:
return -1;
}
@@ -118,6 +137,13 @@ int audio_in_set_channels(audio_in_t *ai, int channels)
if (ai_oss_set_channels(ai) < 0) return -1;
return ai->channels;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ ai->req_channels = channels;
+ if (!ai->setup) return 0;
+ if (ai_sndio_setup(ai) < 0) return -1;
+ return ai->channels;
+#endif
default:
return -1;
}
@@ -146,6 +172,12 @@ int audio_in_set_device(audio_in_t *ai, char *device)
ai->oss.device = strdup(device);
return 0;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ if (ai->sndio.device) free(ai->sndio.device);
+ ai->sndio.device = strdup(device);
+ return 0;
+#endif
default:
return -1;
}
@@ -171,6 +203,13 @@ int audio_in_uninit(audio_in_t *ai)
ai->setup = 0;
return 0;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ if (ai->sndio.hdl)
+ sio_close(ai->sndio.hdl);
+ ai->setup = 0;
+ return 0;
+#endif
}
}
return -1;
@@ -187,6 +226,12 @@ int audio_in_start_capture(audio_in_t *ai)
case AUDIO_IN_OSS:
return 0;
#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ if (!sio_start(ai->sndio.hdl))
+ return -1;
+ return 0;
+#endif
default:
return -1;
}
@@ -220,6 +265,20 @@ int audio_in_read_chunk(audio_in_t *ai, unsigned char *buffer)
#ifdef CONFIG_OSS_AUDIO
case AUDIO_IN_OSS:
ret = read(ai->oss.audio_fd, buffer, ai->blocksize);
+ if (ret != ai->blocksize) {
+ if (ret < 0) {
+ mp_msg(MSGT_TV, MSGL_ERR, "\nError reading audio: %s\n", strerror(errno));
+
+ } else {
+ mp_msg(MSGT_TV, MSGL_ERR, "\nNot enough audio samples!\n");
+ }
+ return -1;
+ }
+ return ret;
+#endif
+#ifdef CONFIG_SNDIO
+ case AUDIO_IN_SNDIO:
+ ret = sio_read(ai->sndio.hdl, buffer, ai->blocksize);
if (ret != ai->blocksize) {
if (ret < 0) {
mp_tmsg(MSGT_TV, MSGL_ERR, "\nError reading audio: %s\n", strerror(errno));
diff --git a/stream/audio_in.h b/stream/audio_in.h
index 31688e7192..2f42685c7c 100644
--- a/stream/audio_in.h
+++ b/stream/audio_in.h
@@ -21,6 +21,7 @@
#define AUDIO_IN_ALSA 1
#define AUDIO_IN_OSS 2
+#define AUDIO_IN_SNDIO 3
#include "config.h"
@@ -45,6 +46,16 @@ typedef struct {
} ai_oss_t;
#endif
+#ifdef CONFIG_SNDIO
+#include <sndio.h>
+
+typedef struct {
+ char *device;
+
+ struct sio_hdl *hdl;
+} ai_sndio_t;
+#endif
+
typedef struct
{
int type;
@@ -67,6 +78,9 @@ typedef struct
#ifdef CONFIG_OSS_AUDIO
ai_oss_t oss;
#endif
+#ifdef CONFIG_SNDIO
+ ai_sndio_t sndio;
+#endif
} audio_in_t;
int audio_in_init(audio_in_t *ai, int type);
@@ -90,4 +104,9 @@ int ai_oss_set_channels(audio_in_t *ai);
int ai_oss_init(audio_in_t *ai);
#endif
+#ifdef CONFIG_SNDIO
+int ai_sndio_setup(audio_in_t *ai);
+int ai_sndio_init(audio_in_t *ai);
+#endif
+
#endif /* MPLAYER_AUDIO_IN_H */