source: roaraudio/roard/codecfilter_wave.c @ 3686:9a6d918fb3a2

Last change on this file since 3686:9a6d918fb3a2 was 3686:9a6d918fb3a2, checked in by phi, 14 years ago

enable RIFF_WAVE codec filter to read RSound data

File size: 7.1 KB
RevLine 
[559]1//codecfilter_wave.c:
2
[668]3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[668]23 *
24 */
25
[559]26#include "roard.h"
27
[2505]28#ifndef ROAR_WITHOUT_CF_WAVE
29
[559]30int cf_wave_open(CODECFILTER_USERDATA_T * inst, int codec,
31                                            struct roar_stream_server * info,
32                                            struct roar_codecfilter   * filter) {
33 struct codecfilter_wave_inst * self = malloc(sizeof(struct codecfilter_wave_inst));
[609]34 struct roar_stream * s = ROAR_STREAM(info);
[559]35
36 if ( !self )
37  return -1;
38
39 self->stream               = info;
[2595]40 self->vstream              = NULL;
[559]41 self->opened               = 0;
42
43 *inst = (CODECFILTER_USERDATA_T) self;
44
45 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
46 return 0;
47}
48
49int cf_wave_close(CODECFILTER_USERDATA_T   inst) {
[562]50// struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
[559]51
52 if ( !inst )
53  return -1;
54
55 free(inst);
56 return 0;
57}
58
59int cf_wave_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
60 struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
61 int r = -1;
[562]62 char tbuf[44];
[2599]63 struct roar_stream * ps = ROAR_STREAM(self->stream);
64 struct roar_stream *  s;
65 struct roar_audio_info info;
[2590]66 uint16_t tmp16;
67 uint32_t tmp32;
68 int codec = -1;
[2599]69 int vid, fh;
[559]70
71 if ( self->opened ) {
[606]72  return stream_vio_s_read(self->stream, buf, len);
[559]73 } else {
[606]74  if (stream_vio_s_read(self->stream, tbuf, 44) != 44) {
[559]75   return -1;
76  }
[565]77
78  // TODO: write better code here!
79
[2599]80  if ( (fh = streams_get_fh(ps->id)) == -1 ) {
81   return -1;
82  }
83
84  if ( (vid = streams_new_virtual(ps->id, &(self->vstream))) == -1 ) {
85   return -1;
86  }
87
88  ROAR_DBG("cf_wave_read(*): self->vstream=%p", self->vstream);
89
90  s = ROAR_STREAM(self->vstream);
91
[2590]92  memcpy(&tmp32, tbuf+24, 4);
93  s->info.rate = ROAR_LE2HOST32(tmp32);
94
95  memcpy(&tmp16, tbuf+22, 2);
96  s->info.channels = ROAR_LE2HOST16(tmp16);
97
98  memcpy(&tmp16, tbuf+34, 2);
99  s->info.bits = ROAR_LE2HOST16(tmp16);
100
101  memcpy(&tmp16, tbuf+20, 2);
102
103  switch (ROAR_LE2HOST16(tmp16)) {
104   case ROAR_RIFF_WAVE_CID_PCM:
105     if ( s->info.bits == 8 ) {
106      codec = ROAR_CODEC_PCM_U_LE;
107     } else {
108      codec = ROAR_CODEC_PCM_S_LE;
109     }
110    break;
111   case ROAR_RIFF_WAVE_CID_ALAW:
112     codec = ROAR_CODEC_ALAW;
113    break;
114   case ROAR_RIFF_WAVE_CID_MULAW:
115     codec = ROAR_CODEC_MULAW;
116    break;
[3686]117   case ROAR_RIFF_WAVE_CID_RSOUND:
118     memcpy(&tmp16, tbuf+42, 2);
119     switch (ROAR_LE2HOST16(tmp16)) {
120      case ROAR_RIFF_WAVE_RSID_S16_LE:
121        s->info.bits = 16;
122        codec        = ROAR_CODEC_PCM_S_LE;
123       break;
124      case ROAR_RIFF_WAVE_RSID_S16_BE:
125        s->info.bits = 16;
126        codec        = ROAR_CODEC_PCM_U_BE;
127       break;
128      case ROAR_RIFF_WAVE_RSID_U16_LE:
129        s->info.bits = 16;
130        codec        = ROAR_CODEC_PCM_U_LE;
131       break;
132      case ROAR_RIFF_WAVE_RSID_U16_BE:
133        s->info.bits = 16;
134        codec        = ROAR_CODEC_PCM_U_BE;
135       break;
136      case ROAR_RIFF_WAVE_RSID_S8:
137        s->info.bits = 8;
138        codec        = ROAR_CODEC_PCM_S_LE;
139       break;
140      case ROAR_RIFF_WAVE_RSID_U8:
141        s->info.bits = 8;
142        codec        = ROAR_CODEC_PCM_U_LE;
143       break;
144      default:
145        return -1;
146     }
147    break;
[2590]148   case ROAR_RIFF_WAVE_CID_IEEE_FLOAT:
149   default:
150     return -1;
151  }
152
[2599]153   s->info.codec            = codec;
154  self->vstream->codec_orgi = codec;
155
156  memcpy(&info, &(s->info), sizeof(struct roar_audio_info));
157
158  if ( streams_set_fh(vid, fh) == -1 ) {
159   return -1;
160  }
161
162/*
163  if ( roar_vio_open_pass(&(self->vstream->vio), &(self->stream->vio)) == -1 ) {
164   return -1;
165  }
166*/
167
168  memcpy(&(self->vstream->vio), &(self->stream->vio), sizeof(struct roar_vio_calls));
169
[2607]170  if ( streams_set_null_io(ps->id) == -1 ) {
[2599]171   return -1;
172  }
173
174  memcpy(&(ps->info), &info, sizeof(struct roar_audio_info));
[559]175
[564]176  self->opened = 1;
177
[559]178  errno = EAGAIN;
179  return -1;
180 }
181
182 return r;
183}
184
185int cf_wave_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
186 struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
[1012]187 struct roar_stream           * s    = ROAR_STREAM(self->stream);
[2816]188 void   * header;
[1012]189 int32_t  tmp32;
190 int16_t  tmp16;
191 int16_t  bits;
192 int16_t  codec;
[2816]193 int      sid;
[559]194
[1013]195 ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len);
196 ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i): self->opened=%i", inst, buf, len, self->opened);
[1012]197
198 if ( self->opened ) {
199  return stream_vio_s_write(self->stream, buf, len);
200 } else {
201
202  if ( s->fh == -1 ) {
203   errno = EAGAIN;
204   return -1;
205  }
206
[2816]207  sid = ROAR_STREAM(self->stream)->id;
208
209  if ( stream_prethru_destroy(sid) == -1 ) {
210   return -1;
211  }
212
213  if ( stream_prethru_add_data(sid, &header, 44) == -1 ) {
214   return -1;
215  }
216
[1012]217  memcpy(header   , "RIFF\367\377\377\177WAVEfmt \020", 17);
218  memcpy(header+36, "data\313\377\377\177", 8);
219
220  switch (s->info.codec) {
221   case ROAR_CODEC_PCM_S_LE:
222     codec = 0x0001;
223    break;
224   default:
225     ROAR_ERR("cf_wave_write(*) Codec not supported!");
226     return -1;
227    break;
228  }
229
[1013]230  ROAR_DBG("cf_wave_write(*) Codec supported!");
[1012]231
232  bits = s->info.bits;
233  memcpy(header+24, &(s->info.rate    ), 4);
234  memcpy(header+22, &(s->info.channels), 2);
235  memcpy(header+34, &bits, 2);
236
237  tmp16 = s->info.channels * bits / 8;
238  memcpy(header+32, &tmp16, 2);
239  tmp32 = tmp16 * s->info.rate;
240  memcpy(header+28, &tmp32, 4);
241  memcpy(header+20, &codec, 2);
242
243  if ( stream_vio_s_write(self->stream, header, 44) != 44 )
244   return -1;
245
246  self->opened = 1;
247
248  errno = EAGAIN;
249//  return -1;
250
251  len = stream_vio_s_write(self->stream, buf, len);
252
253  cf_wave_close(inst);
254  ROAR_STREAM_SERVER(s)->codecfilter = -1;
255
256  return len;
257
258//  return stream_vio_s_write(self->stream, buf, len);
259 }
260
261 return -1;
[559]262}
263
[2604]264int cf_wave_ctl(CODECFILTER_USERDATA_T   inst, int cmd, void * data) {
[2607]265 struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
266 int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK;
267
268 cmd -= type;
269
270 ROAR_DBG("cf_wave_ctl(*): command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x",
271                    cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd));
272
273 switch (cmd) {
274  case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_VIRTUAL_DELETE):
275    streams_delete(ROAR_STREAM(self->stream)->id);
276    return 0;
277   break;
278  default:
279    ROAR_DBG("cf_wave_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x",
280                    cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd));
281    return -1;
282 }
283
[2604]284 return -1;
285}
286
[2505]287#endif
288
[559]289//ll
Note: See TracBrowser for help on using the repository browser.