1 /*
2 * madplay - MPEG audio decoder and player
3 * Copyright (C) 2000-2004 Robert Leslie
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id: audio_raw.c,v 1.22 2004/01/23 09:41:31 rob Exp $
20 */
21
22 # ifdef HAVE_CONFIG_H
23 # include "config.h"
24 # endif
25
26 # include "global.h"
27
28 # include <stdio.h>
29 # include <string.h>
30 # include <mad.h>
31
32 # include "audio.h"
33
34 # if defined(WORDS_BIGENDIAN)
35 # define audio_pcm_s32 audio_pcm_s32be
36 # define audio_pcm_s24 audio_pcm_s24be
37 # define audio_pcm_s16 audio_pcm_s16be
38 # else
39 # define audio_pcm_s32 audio_pcm_s32le
40 # define audio_pcm_s24 audio_pcm_s24le
41 # define audio_pcm_s16 audio_pcm_s16le
42 # endif
43
44 static FILE *outfile;
45 static audio_pcmfunc_t *audio_pcm;
46
47 static
init(struct audio_init * init)48 int init(struct audio_init *init)
49 {
50 if (init->path && strcmp(init->path, "-") != 0) {
51 outfile = fopen(init->path, "wb");
52 if (outfile == 0) {
53 audio_error = ":";
54 return -1;
55 }
56 }
57 else
58 outfile = stdout;
59
60 return 0;
61 }
62
63 static
config(struct audio_config * config)64 int config(struct audio_config *config)
65 {
66 unsigned int bitdepth;
67
68 bitdepth = config->precision & ~7;
69 if (bitdepth == 0)
70 bitdepth = 16;
71 else if (bitdepth > 32)
72 bitdepth = 32;
73
74 switch (config->precision = bitdepth) {
75 case 8:
76 audio_pcm = audio_pcm_u8;
77 break;
78
79 case 16:
80 audio_pcm = audio_pcm_s16;
81 break;
82
83 case 24:
84 audio_pcm = audio_pcm_s24;
85 break;
86
87 case 32:
88 audio_pcm = audio_pcm_s32;
89 break;
90 }
91
92 return 0;
93 }
94
95 static
play(struct audio_play * play)96 int play(struct audio_play *play)
97 {
98 unsigned char data[MAX_NSAMPLES * 4 * 2];
99 unsigned int len;
100
101 len = audio_pcm(data, play->nsamples, play->samples[0], play->samples[1],
102 play->mode, play->stats);
103
104 if (fwrite(data, len, 1, outfile) != 1) {
105 audio_error = ":fwrite";
106 return -1;
107 }
108
109 return 0;
110 }
111
112 static
stop(struct audio_stop * stop)113 int stop(struct audio_stop *stop)
114 {
115 return 0;
116 }
117
118 static
finish(struct audio_finish * finish)119 int finish(struct audio_finish *finish)
120 {
121 if (outfile != stdout &&
122 fclose(outfile) == EOF) {
123 audio_error = ":fclose";
124 return -1;
125 }
126
127 return 0;
128 }
129
audio_raw(union audio_control * control)130 int audio_raw(union audio_control *control)
131 {
132 audio_error = 0;
133
134 switch (control->command) {
135 case AUDIO_COMMAND_INIT:
136 return init(&control->init);
137
138 case AUDIO_COMMAND_CONFIG:
139 return config(&control->config);
140
141 case AUDIO_COMMAND_PLAY:
142 return play(&control->play);
143
144 case AUDIO_COMMAND_STOP:
145 return stop(&control->stop);
146
147 case AUDIO_COMMAND_FINISH:
148 return finish(&control->finish);
149 }
150
151 return 0;
152 }
153