Changeset 5196:6769899f55d2 in roaraudio


Ignore:
Timestamp:
10/23/11 12:46:47 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Re-wrote ALSA plugin (pr1)

Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5182 r5196  
    1212        * Updated manpages (pr1) 
    1313        * Updated filters to support 8 and 32 bit mode as well (pr1) 
     14        * Re-wrote ALSA plugin (pr1) 
    1415 
    1516v. 0.4rc0 - Mon Sep 05 2011 15:25 CEST 
  • plugins/alsavs/Makefile

    r5165 r5196  
    33TARGET=$(SLIB) 
    44INSTALL_DIR=$(PREFIX_LIB)/alsa-lib/ 
    5 OBJS=pcm_roar.o roar.o thread.o 
     5OBJS=pcm_roar.o roar.o 
    66 
    77include ../../Makefile.conf 
  • plugins/alsavs/pcm_roar.c

    r5174 r5196  
    33/* 
    44 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011 
    5  *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 
     5 *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011 
    66 * 
    77 *  This file is part of libroar a part of RoarAudio, 
     
    7171 } 
    7272 
    73  if ( roar_vs_buffer(self->vss, self->bufsize, &err) == -1 ) { 
     73 // ALSA really expects there to be self->bufsize writable bytes. 
     74 if ( roar_vs_buffer(self->vss, self->bufsize + 1, &err) == -1 ) { 
    7475  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); 
    7576  self->vss = NULL; 
     
    110111 self->stream_opened = 1; 
    111112 
    112 //RM: self->bufptr = 0; 
    113  ROAR_DBG("roar_pcm_start(*): Starting background thread"); 
    114  self->thread_active = 1; // We have to activate the thread before starting it, because the thread lives on that thread_active is 1. 
    115  if ( pthread_create(&(self->thread), NULL, roar_plugin_thread, self) < 0 ) { 
    116   self->thread_active = 0; 
    117   ROAR_DBG("roar_pcm_start(*) = -1"); 
    118   return -1; 
    119  } 
    120  pthread_mutex_lock(&(self->lock)); // wait for the background thread to wake up. 
    121  ROAR_DBG("roar_pcm_start(*): background thread was successfully started"); 
    122  
    123113 ROAR_DBG("roar_pcm_start(*) = 0"); 
    124114 return 0; 
     
    132122 self->vss = NULL; 
    133123 self->stream_opened = 0; 
    134  self->thread_active = 0; 
    135 //RM: self->bufptr = 0; 
    136 //RM: self->last_ptr = 0; 
    137 //RM: self->total_written = 0; 
    138 //RM: self->has_written = 0; 
     124 self->last_ptr = 0; 
    139125} 
    140126 
     
    153139 
    154140 ROAR_DBG("roar_pcm_stop(*) = 0"); 
    155  
    156  
    157  if ( self->thread_active ) { 
    158   self->thread_active = 0; 
    159   pthread_cond_signal(&(self->cond)); 
    160   pthread_join(self->thread, NULL); 
    161  } 
    162141 
    163142 roar_plugin_reset(self); 
     
    233212 struct roar_alsa_pcm * self = io->private_data; 
    234213 int ptr; 
     214 int buffered; 
    235215 ssize_t avail; 
    236216 
     
    244224 } 
    245225 
    246 #if 0 
    247  // ALSA has a weird way of calculating how much data can be written to the audio buffer. 
    248  // It uses the formula: 
    249  // avail = bufsize + ptr - io->appl_ptr; (??!?) 
    250  // We really want this: 
    251  // avail = bufsize - ptr; 
    252  // This is the obvious way, so we have to manipulate ptr like this: 
    253  // ptr = io->appl_ptr - ptr; 
    254  
    255  pthread_mutex_lock(&(self->lock)); 
    256  ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufptr); 
    257  pthread_mutex_unlock(&(self->lock)); 
    258 #else 
    259  pthread_mutex_lock(&(self->lock)); 
     226 // ALSA expects return value to be equal to the amount of data written on the hardware side. 
     227 // It uses this to calculate writable amount. (Because hey, just calling a get_avail() is too hard.) 
     228 // Return value is thus io->appl_ptr - buffered_amount; 
     229 
     230 while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 ); 
     231 
    260232 avail = roar_vs_get_avail_write(self->vss, NULL); 
    261  pthread_mutex_unlock(&(self->lock)); 
    262  
    263233 ROAR_DBG("roar_pcm_pointer(*): avail=%lli", (long long int)avail); 
    264  
    265  ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufsize - avail); 
    266 #endif 
    267  
    268  ptr = io->appl_ptr - ptr; 
     234 buffered = snd_pcm_bytes_to_frames(io->pcm, self->bufsize - avail); 
     235 
     236 ptr = io->appl_ptr - buffered; 
    269237 self->last_ptr = io->appl_ptr; 
    270238 
    271  ROAR_DBG("roar_pcm_pointer(*) appl_ptr: %i, ptr: %i, calculated avail frames: %i", (int)io->appl_ptr, (int)ptr, (int)(io->appl_ptr - ptr)); 
     239 ROAR_DBG("roar_pcm_pointer(*) appl_ptr (frames): %i, buffered (frames): %i", (int)io->appl_ptr, (int)buffered); 
    272240 ROAR_DBG("roar_pcm_pointer(*) = %i", ptr); 
    273241 return ptr; 
     
    293261 buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; 
    294262 
    295  ret = roar_plugin_write(self, buf, len); 
    296  
    297  if ( ret == -1 ) 
    298   return -EIO; 
     263 while (len) { 
     264  ret = roar_vs_write(self->vss, buf, len, NULL); 
     265/* 
     266 * <ph3-der-loewe> is it supposed to be EIO? 
     267 * <ph3-der-loewe> or can we return the true error code from roar_vs_write()? 
     268 * <maister> ALSA tends to give -EIO errors 
     269 * <maister> It shouldn't cause problems to pass roar_vs errnos. 
     270 * <maister> But the error strings might be a bit confusing perhaps 
     271 */ 
     272  if ( ret == -1 ) 
     273   return -EIO; 
     274  len -= ret; 
     275  buf += ret; 
     276 } 
     277 
     278 while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 ); 
    299279 
    300280 ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size); 
     
    312292 ROAR_DBG("roar_pcm_delay(*) = ?"); 
    313293 
    314  // TODO: We need to set *delayp the latency in frames. 
    315  pthread_mutex_lock(&(self->lock)); 
    316  roar_plugin_drain(self); // why do we call this? 
    317  
    318294 lat = roar_vs_latency2(self->vss, ROAR_VS_BACKEND_DEFAULT, ROAR_VS_NOWAIT, NULL); 
    319  *delayp = lat * self->info.rate; 
    320  
    321  pthread_mutex_unlock(&(self->lock)); 
     295 *delayp = (lat * self->info.rate) / 1000000; 
    322296 
    323297 return 0; 
     
    420394  return err; 
    421395 
    422  ROAR_DBG("roar_pcm_hw_params(*) buffersize (bytes): %i", (int)buffersize); 
    423  
    424  //self->bufsize = snd_pcm_frames_to_bytes(io->pcm, buffersize); 
     396 ROAR_DBG("roar_pcm_hw_params(*) buffersize (frames): %i", (int)buffersize); 
     397 
    425398 self->bufsize = self->info.bits * self->info.channels * buffersize / 8; 
    426 //RM: self->buffer = malloc(self->bufsize); 
    427 //RM: if (self->buffer == NULL) 
    428 //RM:  return -1; 
    429 //RM: self->bufptr = 0; 
    430399 
    431400 ROAR_DBG("roar_pcm_hw_params(*) Setting buffersize (bytes): %i", (int)self->bufsize); 
     
    445414 roar_disconnect(&(self->roar.con)); 
    446415 
    447  pthread_mutex_destroy(&(self->lock)); 
    448  pthread_mutex_destroy(&(self->cond_lock)); 
    449  pthread_cond_destroy(&(self->cond)); 
    450  
    451 //RM: free(self->buffer); 
    452416 free(self); 
    453417 
     
    533497 } 
    534498 
    535  pthread_mutex_init(&(self->lock), NULL); 
    536  pthread_mutex_init(&(self->cond_lock), NULL); 
    537  pthread_cond_init(&(self->cond), NULL); 
    538  
    539  
    540499 if ( (ret = roar_hw_constraint(self)) < 0 ) { 
    541500  snd_pcm_ioplug_delete(&(self->io)); 
  • plugins/alsavs/roar.h

    r5174 r5196  
    33/* 
    44 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011 
    5  *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 
     5 *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011 
    66 * 
    77 *  This file is part of libroar a part of RoarAudio, 
     
    6060 int                    stream_role; 
    6161 int                    stream_opened; 
    62  size_t                 _writec; 
     62 size_t                 bufsize; 
    6363 size_t                 last_ptr; 
    64  char*                  _buffer; 
    65  size_t                 bufsize; 
    66  volatile size_t        _bufptr; 
    67  pthread_t              thread; 
    68  pthread_mutex_t        lock; 
    69  pthread_mutex_t        cond_lock; 
    70  pthread_cond_t         cond; 
    71  volatile int           thread_active; 
    72  int                    _bytes_in_buffer; 
    73  volatile int64_t       _total_written; 
    74  int                    _has_written; 
    75  struct timespec        _start_tv; 
    7664}; 
    7765 
Note: See TracChangeset for help on using the changeset viewer.