source: roaraudio/roard/codecfilter_wave.c @ 2595:da9d63539138

Last change on this file since 2595:da9d63539138 was 2595:da9d63539138, checked in by phi, 15 years ago

added new member /vstream/

File size: 4.5 KB
Line 
1//codecfilter_wave.c:
2
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
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "roard.h"
26
27#ifndef ROAR_WITHOUT_CF_WAVE
28
29int cf_wave_open(CODECFILTER_USERDATA_T * inst, int codec,
30                                            struct roar_stream_server * info,
31                                            struct roar_codecfilter   * filter) {
32 struct codecfilter_wave_inst * self = malloc(sizeof(struct codecfilter_wave_inst));
33 struct roar_stream * s = ROAR_STREAM(info);
34
35 if ( !self )
36  return -1;
37
38 self->stream               = info;
39 self->vstream              = NULL;
40 self->opened               = 0;
41
42 *inst = (CODECFILTER_USERDATA_T) self;
43
44 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
45 return 0;
46}
47
48int cf_wave_close(CODECFILTER_USERDATA_T   inst) {
49// struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
50
51 if ( !inst )
52  return -1;
53
54 free(inst);
55 return 0;
56}
57
58int cf_wave_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
59 struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
60 int r = -1;
61 char tbuf[44];
62 struct roar_stream * s = ROAR_STREAM(self->stream);
63 uint16_t tmp16;
64 uint32_t tmp32;
65 int codec = -1;
66
67 if ( self->opened ) {
68  return stream_vio_s_read(self->stream, buf, len);
69 } else {
70  if (stream_vio_s_read(self->stream, tbuf, 44) != 44) {
71   return -1;
72  }
73
74  // TODO: write better code here!
75
76  memcpy(&tmp32, tbuf+24, 4);
77  s->info.rate = ROAR_LE2HOST32(tmp32);
78
79  memcpy(&tmp16, tbuf+22, 2);
80  s->info.channels = ROAR_LE2HOST16(tmp16);
81
82  memcpy(&tmp16, tbuf+34, 2);
83  s->info.bits = ROAR_LE2HOST16(tmp16);
84
85  memcpy(&tmp16, tbuf+20, 2);
86
87  switch (ROAR_LE2HOST16(tmp16)) {
88   case ROAR_RIFF_WAVE_CID_PCM:
89     if ( s->info.bits == 8 ) {
90      codec = ROAR_CODEC_PCM_U_LE;
91     } else {
92      codec = ROAR_CODEC_PCM_S_LE;
93     }
94    break;
95   case ROAR_RIFF_WAVE_CID_ALAW:
96     codec = ROAR_CODEC_ALAW;
97    break;
98   case ROAR_RIFF_WAVE_CID_MULAW:
99     codec = ROAR_CODEC_MULAW;
100    break;
101   case ROAR_RIFF_WAVE_CID_IEEE_FLOAT:
102   default:
103     return -1;
104  }
105
106  s->info.codec = codec;
107
108  self->opened = 1;
109
110  errno = EAGAIN;
111  return -1;
112 }
113
114 return r;
115}
116
117int cf_wave_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
118 struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst;
119 struct roar_stream           * s    = ROAR_STREAM(self->stream);
120 char header[44];
121 int32_t  tmp32;
122 int16_t  tmp16;
123 int16_t  bits;
124 int16_t  codec;
125
126 ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len);
127 ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i): self->opened=%i", inst, buf, len, self->opened);
128
129 if ( self->opened ) {
130  return stream_vio_s_write(self->stream, buf, len);
131 } else {
132
133  if ( s->fh == -1 ) {
134   errno = EAGAIN;
135   return -1;
136  }
137
138  memcpy(header   , "RIFF\367\377\377\177WAVEfmt \020", 17);
139  memcpy(header+36, "data\313\377\377\177", 8);
140
141  switch (s->info.codec) {
142   case ROAR_CODEC_PCM_S_LE:
143     codec = 0x0001;
144    break;
145   default:
146     ROAR_ERR("cf_wave_write(*) Codec not supported!");
147     return -1;
148    break;
149  }
150
151  ROAR_DBG("cf_wave_write(*) Codec supported!");
152
153  bits = s->info.bits;
154  memcpy(header+24, &(s->info.rate    ), 4);
155  memcpy(header+22, &(s->info.channels), 2);
156  memcpy(header+34, &bits, 2);
157
158  tmp16 = s->info.channels * bits / 8;
159  memcpy(header+32, &tmp16, 2);
160  tmp32 = tmp16 * s->info.rate;
161  memcpy(header+28, &tmp32, 4);
162  memcpy(header+20, &codec, 2);
163
164  if ( stream_vio_s_write(self->stream, header, 44) != 44 )
165   return -1;
166
167  self->opened = 1;
168
169  errno = EAGAIN;
170//  return -1;
171
172  len = stream_vio_s_write(self->stream, buf, len);
173
174  cf_wave_close(inst);
175  ROAR_STREAM_SERVER(s)->codecfilter = -1;
176
177  return len;
178
179//  return stream_vio_s_write(self->stream, buf, len);
180 }
181
182 return -1;
183}
184
185#endif
186
187//ll
Note: See TracBrowser for help on using the repository browser.