Changeset 3736:970298ece9e4 in roaraudio for plugins/alsa
- Timestamp:
- 04/26/10 01:35:03 (14 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/alsa/pcm.c
r3660 r3736 3 3 /* 4 4 * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010 5 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 5 6 * 6 7 * This file is part of libroar a part of RoarAudio, … … 35 36 36 37 #include "roar.h" 38 39 // Equvivalent to prepare(). Starts a stream. Also needs to reset the writec since pointer() will do funny 40 // things without it. Will be called several times during a program! 41 static int roar_pcm_start (snd_pcm_ioplug_t * io) { 42 struct roar_alsa_pcm * self = io->private_data; 43 44 ROAR_DBG("roar_pcm_start(*) = ?"); 45 46 // If start is called several times in a row, just ignore it. 47 if (self->stream_opened) 48 return 0; 49 50 if ( roar_vio_simple_stream( &(self->stream_vio), self->info.rate, 51 self->info.channels, self->info.bits, self->info.codec, 52 NULL, ROAR_DIR_PLAY, "ALSA plugin" ) == -1 ) { 53 return -EINVAL; 54 } 55 56 // Stream is now active, yay. 57 self->stream_opened = 1; 58 self->writec = 0; 59 60 return 0; 61 } 62 63 // Simply stopping the stream. Will need to be restarted to play more. 64 // Will be called several times together with roar_pcm_start() 65 static int roar_pcm_stop (snd_pcm_ioplug_t *io) { 66 struct roar_alsa_pcm * self = io->private_data; 67 68 ROAR_DBG("roar_pcm_stop(*) = ?"); 69 70 // If this is called several times in a row, just ignore. 71 if ( !self->stream_opened ) 72 return 0; 73 74 roar_vio_close(&(self->stream_vio)); 75 self->stream_opened = 0; 76 77 ROAR_DBG("roar_pcm_stop(*) = 0"); 78 79 return 0; 80 } 37 81 38 82 static int roar_hw_constraint(struct roar_alsa_pcm * self) { … … 68 112 return ret; 69 113 114 #if 0 70 115 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1, 4294967295U)) < 0 ) 71 116 return ret; … … 76 121 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1, 4294967295U)) < 0 ) 77 122 return ret; 123 #else 124 // We shouldn't let ALSA use extremely low or high values, it will kill a kitty most likely. :v 125 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1 << 6, 1 << 18)) < 0 ) 126 return ret; 127 128 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 1024)) < 0 ) 129 return ret; 130 131 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1 << 13, 1 << 24)) < 0 ) 132 return ret; 133 #endif 78 134 79 135 ROAR_DBG("roar_hw_constraint(*) = 0"); … … 87 143 } 88 144 145 146 /////////////////////////////// 147 /// TODO: Needs to be implemented 148 /////////////////////////////// 149 // This hacky hack should not be used, since apparently, using this, ALSA will think the audio buffer is always empty (?), 150 // leading to completely broken blocking audio which will only work with audio players. 151 // Will need a method to determine how much buffer data is available to write to the roar buffer without blocking. 152 // We therefore also need to know the buffersize that ALSA uses. 153 154 // Referring to alsa-lib/src/pcm/pcm_ioplug.c : snd_pcm_ioplug_hw_ptr_update 89 155 static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) { 90 156 struct roar_alsa_pcm * self = io->private_data; … … 108 174 ROAR_DBG("roar_pcm_transfer(*): len=%lu", (long unsigned int) len); 109 175 176 // Weird ALSA stuff. 110 177 buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; 111 178 112 179 ret = roar_vio_write(&(self->stream_vio), buf, len); 113 180 114 if ( ret != -1 ) 181 if ( ret != -1 ) { 182 // We increment the written counter so that subsequent calls to pointer() will not cause 183 // the library to hang due to several quirks that ALSA uses to determine available size. 184 // This approach is bad, but is needed until pointer() is implemented correctly. 115 185 self->writec += ret; 186 } else { 187 return -EIO; 188 } 116 189 117 190 ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size); … … 119 192 } 120 193 194 195 /////////////////////////////// 196 /// TODO: Needs to be implemented 197 /////////////////////////////// 121 198 static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) { 199 (void)io; 200 122 201 ROAR_DBG("roar_pcm_delay(*) = ?"); 202 203 // TODO: We need to set *delayp the latency in frames. 204 *delayp = 0; 205 123 206 return 0; 124 207 } … … 129 212 ROAR_DBG("roar_pcm_prepare(*) = ?"); 130 213 214 return roar_pcm_start(io); 215 216 #if 0 131 217 if ( self->stream_opened ) { 132 218 roar_vio_close(&(self->stream_vio)); … … 145 231 ROAR_DBG("roar_pcm_prepare(*) = 0"); 146 232 return 0; 233 #endif 147 234 } 148 235 149 236 static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) { 150 237 struct roar_alsa_pcm * self = io->private_data; 238 239 (void) params; 151 240 152 241 ROAR_DBG("roar_pcm_hw_params(*) = ?"); … … 197 286 198 287 static snd_pcm_ioplug_callback_t roar_pcm_callback = { 199 .start = roar_pcm_ dummy,200 .stop = roar_pcm_ dummy,201 .drain = roar_pcm_dummy,288 .start = roar_pcm_start, 289 .stop = roar_pcm_stop, 290 .drain = NULL, 202 291 .pointer = roar_pcm_pointer, 203 292 .transfer = roar_pcm_transfer, … … 224 313 int ret; 225 314 315 (void)root; 316 226 317 ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = ?"); 227 318
Note: See TracChangeset
for help on using the changeset viewer.