aboutsummaryrefslogtreecommitdiff
path: root/src/output/mint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output/mint.c')
-rw-r--r--src/output/mint.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/output/mint.c b/src/output/mint.c
new file mode 100644
index 0000000..7210293
--- /dev/null
+++ b/src/output/mint.c
@@ -0,0 +1,197 @@
+/*
+ mint: audio output for MINT
+
+ copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
+ see COPYING and AUTHORS files in distribution or http://mpg123.org
+ initially written by Petr Stehlik
+*/
+
+/* derived from LINUX, VOXWARE and SUN for MiNT Audio Device by Petr Stehlik */
+#include <fcntl.h>
+#include "mpg123app.h"
+#include <ioctl.h>
+#include <audios.h>
+#include "debug.h"
+
+/* Globals */
+extern int outburst;
+int real_rate_printed = 0;
+
+
+
+static int rate_best_match(audio_output_t *ao)
+{
+ int ret,dsp_rate;
+
+ if(!ai || ao->fn < 0 || ao->rate < 0)
+ return -1;
+
+ dsp_rate = ao->rate;
+ ret = ioctl(ao->fn,AIOCSSPEED, (void *)dsp_rate);
+ ret = ioctl(ao->fn,AIOCGSPEED,&dsp_rate);
+ if(ret < 0) return ret;
+ ao->rate = dsp_rate;
+ return 0;
+}
+
+static int set_rate(audio_output_t *ao)
+{
+ int dsp_rate = ao->rate;
+
+ if(ao->rate >= 0) {
+ int ret, real_rate;
+ ret = ioctl(ao->fn, AIOCSSPEED, (void *)dsp_rate);
+ if (ret >= 0 && !real_rate_printed) {
+ ioctl(ao->fn,AIOCGSPEED,&real_rate);
+ if (real_rate != dsp_rate) {
+ fprintf(stderr, "Replay rate: %d Hz\n", real_rate);
+ real_rate_printed = 1;
+ }
+ }
+ return ret;
+ }
+
+ return 0;
+}
+
+static int set_channels(audio_output_t *ao)
+{
+ int chan = ao->channels;
+
+ if(ao->channels < 1) return 0;
+
+ return ioctl(ao->fn, AIOCSCHAN, (void *)chan);
+}
+
+static int set_format(audio_output_t *ao)
+{
+ int fmts;
+
+ if(ao->format == -1)
+ return 0;
+
+ switch(ao->format) {
+ case MPG123_ENC_SIGNED_16:
+ default:
+ fmts = AFMT_S16;
+ break;
+ case MPG123_ENC_UNSIGNED_8:
+ fmts = AFMT_U8;
+ break;
+ case MPG123_ENC_SIGNED_8:
+ fmts = AFMT_S8;
+ break;
+ case MPG123_ENC_ULAW_8:
+ fmts = AFMT_ULAW;
+ break;
+ }
+
+ return ioctl(ao->fn, AIOCSFMT, (void *)fmts);
+}
+
+static int reset_parameters(audio_output_t *ao)
+{
+ int ret;
+ ret = ioctl(ao->fn,AIOCRESET,NULL);
+ if(ret >= 0) ret = set_format(ai);
+ if(ret >= 0) ret = set_channels(ai);
+ if(ret >= 0) ret = set_rate(ai);
+ return ret;
+}
+
+
+
+static int open_mint(audio_output_t *ao)
+{
+ if(!ai) return -1;
+
+ if(!ao->device)
+ ao->device = "/dev/audio";
+
+ ao->fn = open(ao->device,O_WRONLY);
+
+ if(ao->fn < 0)
+ {
+ error1("Can't open %s!",ao->device);
+ return -1;
+ }
+ ioctl(ao->fn, AIOCGBLKSIZE, &outburst);
+ if(outburst > MAXOUTBURST)
+ outburst = MAXOUTBURST;
+ if(audio_reset_parameters(ai) < 0) {
+ close(ao->fn);
+ return -1;
+ }
+
+ return ao->fn;
+}
+
+static int get_formats_mint(audio_output_t *ao)
+{
+ int ret = 0;
+ int fmts;
+
+ if(ioctl(ao->fn,AIOCGFMTS,&fmts) < 0)
+ return -1;
+
+ if(fmts & AFMT_ULAW)
+ ret |= MPG123_ENC_ULAW_8;
+ if(fmts & AFMT_S16)
+ ret |= MPG123_ENC_SIGNED_16;
+ if(fmts & AFMT_U8)
+ ret |= MPG123_ENC_UNSIGNED_8;
+ if(fmts & AFMT_S8)
+ ret |= MPG123_ENC_SIGNED_8;
+
+ return ret;
+}
+
+static int write_mint(audio_output_t *ao,unsigned char *buf,int len)
+{
+ return write(ao->fn,buf,len);
+}
+
+static int close_mint(audio_output_t *ao)
+{
+ close (ao->fn);
+ return 0;
+}
+
+static void flush_mint(audio_output_t *ao)
+{
+}
+
+
+static int init_mint(audio_output_t* ao)
+{
+ if (ao==NULL) return -1;
+
+ /* Set callbacks */
+ ao->open = open_mint;
+ ao->flush = flush_mint;
+ ao->write = write_mint;
+ ao->get_formats = get_formats_mint;
+ ao->close = close_mint;
+
+ /* Success */
+ return 0;
+}
+
+
+
+
+
+/*
+ Module information data structure
+*/
+mpg123_module_t mpg123_output_module_info = {
+ /* api_version */ MPG123_MODULE_API_VERSION,
+ /* name */ "mint",
+ /* description */ "Audio output for MINT.",
+ /* revision */ "$Rev:$",
+ /* handle */ NULL,
+
+ /* init_output */ init_mint,
+};
+
+