source: roaraudio/plugins/alsa/pcm.c @ 3134:9ad85b26c1fa

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

some very, very experimentel code that does not work at all

File size: 6.9 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 if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS,
53        _as(access_list), access_list)) < 0 )
54  return ret;
55
56 if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,
57        _as(formats), formats)) < 0 )
58  return ret;
59
60 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS,
61        1, ROAR_MAX_CHANNELS)) < 0 )
62  return ret;
63
64 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 48000)) < 0 )
65  return ret;
66
67 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1, 4294967295U)) < 0 )
68  return ret;
69
70 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 4294967295U)) < 0 )
71  return ret;
72
73 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1, 4294967295U)) < 0 )
74  return ret;
75
76 return 0;
77}
78
79static int roar_pcm_dummy (snd_pcm_ioplug_t * io) {
80 return 0;
81}
82
83static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) {
84 return 0;
85}
86
87// TODO: FIXME: add support for reading data!
88static snd_pcm_sframes_t roar_pcm_transfer(snd_pcm_ioplug_t *io,
89                                        const snd_pcm_channel_area_t *areas,
90                                        snd_pcm_uframes_t offset,
91                                        snd_pcm_uframes_t size) {
92 struct roar_alsa_pcm * self = io->private_data;
93 char * buf;
94
95 buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
96
97 roar_vio_write(&(self->stream_vio), buf, size * self->info.channels * self->info.bits / 8);
98
99 return size;
100}
101
102static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) {
103 return 0;
104}
105
106static int roar_pcm_prepare(snd_pcm_ioplug_t *io) {
107 struct roar_alsa_pcm * self = io->private_data;
108
109 if ( self->stream_opened ) {
110  roar_vio_close(&(self->stream_vio));
111  self->stream_opened = 0;
112 }
113
114 if ( roar_stream_new(&(self->stream), self->info.rate, self->info.channels, self->info.bits, self->info.codec) == -1 ) {
115  return -EINVAL;
116 }
117
118 if ( roar_stream_connect(&(self->roar.con), &(self->stream), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR) == -1 ) {
119  return -EINVAL;
120 }
121
122 self->stream_opened = 1;
123
124 return -ENOSYS;
125}
126
127static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) {
128 struct roar_alsa_pcm * self = io->private_data;
129
130 self->info.channels = io->channels;
131 self->info.rate     = io->rate;
132
133 switch (io->format) {
134  case SND_PCM_FORMAT_U8:
135    self->info.codec = ROAR_CODEC_PCM_U_LE;
136    self->info.bits  = 8;
137   break;
138  case SND_PCM_FORMAT_A_LAW:
139    self->info.codec = ROAR_CODEC_ALAW;
140    self->info.bits  = 8;
141   break;
142  case SND_PCM_FORMAT_MU_LAW:
143    self->info.codec = ROAR_CODEC_MULAW;
144    self->info.bits  = 8;
145   break;
146  case SND_PCM_FORMAT_S16_LE:
147    self->info.codec = ROAR_CODEC_PCM_S_LE;
148    self->info.bits  = 16;
149   break;
150  case SND_PCM_FORMAT_S16_BE:
151    self->info.codec = ROAR_CODEC_PCM_S_BE;
152    self->info.bits  = 16;
153   break;
154  default:
155    return-EINVAL;
156 }
157
158 return 0;
159}
160
161static int roar_pcm_close (snd_pcm_ioplug_t * io) {
162 struct roar_alsa_pcm * self = io->private_data;
163
164 roar_disconnect(&(self->roar.con));
165
166 free(self);
167
168 return 0;
169}
170
171static snd_pcm_ioplug_callback_t roar_pcm_callback = {
172    .start                  = roar_pcm_dummy,
173    .stop                   = roar_pcm_dummy,
174    .drain                  = roar_pcm_dummy,
175    .pointer                = roar_pcm_pointer,
176    .transfer               = roar_pcm_transfer,
177    .delay                  = roar_pcm_delay,
178    .poll_descriptors_count = NULL,
179    .poll_descriptors       = NULL,
180    .poll_revents           = NULL,
181    .prepare                = roar_pcm_prepare,
182    .hw_params              = roar_pcm_hw_params,
183    .close                  = roar_pcm_close,
184};
185
186SND_PCM_PLUGIN_DEFINE_FUNC(roar) {
187 struct roar_alsa_pcm * self;
188 snd_config_iterator_t i, next;
189 snd_config_t * n;
190 const char   * para;
191 const char   * server = NULL;
192 int            ret;
193
194 printf("TEST!\n");
195
196 snd_config_for_each(i, next, conf) {
197  n = snd_config_iterator_entry(i);
198  if ( snd_config_get_id(n, &para) < 0 )
199   continue;
200
201  if ( !strcmp(para, "type") || !strcmp(para, "comment") )
202   continue;
203
204  if ( !strcmp(para, "server") ) {
205   if (snd_config_get_string(n, &server) < 0) {
206    return -EINVAL;
207   }
208  } else {
209   return -EINVAL;
210  }
211 }
212
213 errno = ENOSYS;
214
215 if ( (self = malloc(sizeof(struct roar_alsa_pcm))) == NULL )
216  return -errno;
217
218 memset(self, 0, sizeof(struct roar_alsa_pcm));
219
220 errno = ENOSYS;
221 if ( roar_simple_connect(&(self->roar.con), (char*)server, "ALSA Plugin") == -1 ) {
222  free(self);
223  return -errno;
224 }
225
226 self->io.version      = SND_PCM_IOPLUG_VERSION;
227 self->io.name         = "RoarAudio Plugin";
228 self->io.poll_fd      = -1;
229 self->io.poll_events  =  0;
230 self->io.mmap_rw      =  0;
231 self->io.callback     = &roar_pcm_callback;
232 self->io.private_data =  self;
233
234 if ( (ret = snd_pcm_ioplug_create(&(self->io), name, stream, mode)) < 0 ) {
235  roar_disconnect(&(self->roar.con));
236  free(self);
237  return ret;
238 }
239
240 if ( (ret = roar_hw_constraint(self)) < 0 ) {
241  snd_pcm_ioplug_delete(&(self->io));
242  roar_disconnect(&(self->roar.con));
243  free(self);
244  return ret;
245 }
246
247 return 0;
248}
249
250SND_PCM_PLUGIN_SYMBOL(roar);
251
252//ll
Note: See TracBrowser for help on using the repository browser.