source: roaraudio/plugins/alsa/pcm.c @ 3135:af6a10f1b0ab

Last change on this file since 3135:af6a10f1b0ab was 3135:af6a10f1b0ab, checked in by phi, 14 years ago

done a lot stuff for testing, plugin now loads but libasound2 segfaults

File size: 7.4 KB
Line 
1//pcm.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *
6 *  This file is part of libroar 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 *  libroar 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 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "roar.h"
36
37static int roar_hw_constraint(struct roar_alsa_pcm * self) {
38 snd_pcm_ioplug_t *io = &(self->io);
39 static const snd_pcm_access_t access_list[] = {
40  SND_PCM_ACCESS_RW_INTERLEAVED
41 };
42 static const unsigned int formats[] = {
43  // TODO: add list of additioal formats we support
44  SND_PCM_FORMAT_U8,
45  SND_PCM_FORMAT_A_LAW,
46  SND_PCM_FORMAT_MU_LAW,
47  SND_PCM_FORMAT_S16_LE,
48  SND_PCM_FORMAT_S16_BE,
49 };
50 int ret;
51
52 ROAR_DBG("roar_hw_constraint(*) = ?");
53
54 if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS,
55        _as(access_list), access_list)) < 0 )
56  return ret;
57
58 if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,
59        _as(formats), formats)) < 0 )
60  return ret;
61
62 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS,
63        1, ROAR_MAX_CHANNELS)) < 0 )
64  return ret;
65
66 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 48000)) < 0 )
67  return ret;
68
69 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1, 4294967295U)) < 0 )
70  return ret;
71
72 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 4294967295U)) < 0 )
73  return ret;
74
75 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1, 4294967295U)) < 0 )
76  return ret;
77
78 ROAR_DBG("roar_hw_constraint(*) = 0");
79
80 return 0;
81}
82
83static int roar_pcm_dummy (snd_pcm_ioplug_t * io) {
84 ROAR_DBG("roar_pcm_dummy(*) = ?");
85 return 0;
86}
87
88static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) {
89 ROAR_DBG("roar_pcm_pointer(*) = ?");
90 return 0;
91}
92
93// TODO: FIXME: add support for reading data!
94static snd_pcm_sframes_t roar_pcm_transfer(snd_pcm_ioplug_t *io,
95                                        const snd_pcm_channel_area_t *areas,
96                                        snd_pcm_uframes_t offset,
97                                        snd_pcm_uframes_t size) {
98 struct roar_alsa_pcm * self = io->private_data;
99 char * buf;
100
101 ROAR_DBG("roar_pcm_transfer(*) = ?");
102
103 buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
104
105 roar_vio_write(&(self->stream_vio), buf, size * self->info.channels * self->info.bits / 8);
106
107 return size;
108}
109
110static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) {
111 ROAR_DBG("roar_pcm_delay(*) = ?");
112 return 0;
113}
114
115static int roar_pcm_prepare(snd_pcm_ioplug_t *io) {
116 struct roar_alsa_pcm * self = io->private_data;
117
118 ROAR_DBG("roar_pcm_prepare(*) = ?");
119
120 if ( self->stream_opened ) {
121  roar_vio_close(&(self->stream_vio));
122  self->stream_opened = 0;
123 }
124
125 if ( roar_stream_new(&(self->stream), self->info.rate, self->info.channels, self->info.bits, self->info.codec) == -1 ) {
126  return -EINVAL;
127 }
128
129 if ( roar_stream_connect(&(self->roar.con), &(self->stream), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR) == -1 ) {
130  return -EINVAL;
131 }
132
133 self->stream_opened = 1;
134
135 return -ENOSYS;
136}
137
138static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) {
139 struct roar_alsa_pcm * self = io->private_data;
140
141 ROAR_DBG("roar_pcm_hw_params(*) = ?");
142
143 self->info.channels = io->channels;
144 self->info.rate     = io->rate;
145
146 switch (io->format) {
147  case SND_PCM_FORMAT_U8:
148    self->info.codec = ROAR_CODEC_PCM_U_LE;
149    self->info.bits  = 8;
150   break;
151  case SND_PCM_FORMAT_A_LAW:
152    self->info.codec = ROAR_CODEC_ALAW;
153    self->info.bits  = 8;
154   break;
155  case SND_PCM_FORMAT_MU_LAW:
156    self->info.codec = ROAR_CODEC_MULAW;
157    self->info.bits  = 8;
158   break;
159  case SND_PCM_FORMAT_S16_LE:
160    self->info.codec = ROAR_CODEC_PCM_S_LE;
161    self->info.bits  = 16;
162   break;
163  case SND_PCM_FORMAT_S16_BE:
164    self->info.codec = ROAR_CODEC_PCM_S_BE;
165    self->info.bits  = 16;
166   break;
167  default:
168    return-EINVAL;
169 }
170
171 return 0;
172}
173
174static int roar_pcm_close (snd_pcm_ioplug_t * io) {
175 struct roar_alsa_pcm * self = io->private_data;
176
177 ROAR_DBG("roar_pcm_close(*) = ?");
178
179 roar_disconnect(&(self->roar.con));
180
181 free(self);
182
183 return 0;
184}
185
186static snd_pcm_ioplug_callback_t roar_pcm_callback = {
187    .start                  = roar_pcm_dummy,
188    .stop                   = roar_pcm_dummy,
189    .drain                  = roar_pcm_dummy,
190    .pointer                = roar_pcm_pointer,
191    .transfer               = roar_pcm_transfer,
192    .delay                  = roar_pcm_delay,
193    .poll_descriptors_count = NULL,
194    .poll_descriptors       = NULL,
195    .poll_revents           = NULL,
196    .prepare                = roar_pcm_prepare,
197    .hw_params              = roar_pcm_hw_params,
198    .close                  = roar_pcm_close,
199};
200
201SND_PCM_PLUGIN_DEFINE_FUNC(roar) {
202 struct roar_alsa_pcm * self;
203 snd_config_iterator_t i, next;
204 snd_config_t * n;
205 const char   * para;
206 const char   * server = NULL;
207 int            ret;
208
209 ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = ?");
210
211 snd_config_for_each(i, next, conf) {
212  n = snd_config_iterator_entry(i);
213  if ( snd_config_get_id(n, &para) < 0 )
214   continue;
215
216  if ( !strcmp(para, "type") || !strcmp(para, "comment") )
217   continue;
218
219  if ( !strcmp(para, "server") ) {
220   if (snd_config_get_string(n, &server) < 0) {
221    return -EINVAL;
222   }
223  } else {
224   return -EINVAL;
225  }
226 }
227
228 errno = ENOSYS;
229
230 if ( (self = malloc(sizeof(struct roar_alsa_pcm))) == NULL )
231  return -errno;
232
233 memset(self, 0, sizeof(struct roar_alsa_pcm));
234
235 errno = ENOSYS;
236 if ( roar_simple_connect(&(self->roar.con), (char*)server, "ALSA Plugin") == -1 ) {
237  free(self);
238  return -errno;
239 }
240
241 self->io.version      = SND_PCM_IOPLUG_VERSION;
242 self->io.name         = "RoarAudio Plugin";
243 self->io.poll_fd      = -1;
244 self->io.poll_events  =  0;
245 self->io.mmap_rw      =  0;
246 self->io.callback     = &roar_pcm_callback;
247 self->io.private_data =  self;
248
249 if ( (ret = snd_pcm_ioplug_create(&(self->io), name, stream, mode)) < 0 ) {
250  roar_disconnect(&(self->roar.con));
251  free(self);
252  return ret;
253 }
254
255 if ( (ret = roar_hw_constraint(self)) < 0 ) {
256  snd_pcm_ioplug_delete(&(self->io));
257  roar_disconnect(&(self->roar.con));
258  free(self);
259  return ret;
260 }
261
262 ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = 0");
263
264 return 0;
265}
266
267SND_PCM_PLUGIN_SYMBOL(roar);
268
269int __snd_pcm_roar_open_dlsym_pcm_001 (void) {
270 return 0;
271}
272
273//ll
Note: See TracBrowser for help on using the repository browser.