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