Changeset 5174:c24a2089056a in roaraudio


Ignore:
Timestamp:
10/22/11 12:11:33 (13 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added some experimental fork of the old alsa plugin using VS API

Location:
plugins/alsavs
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • plugins/alsavs/pcm_roar.c

    r5168 r5174  
    4646 struct roar_alsa_pcm * self = io->private_data; 
    4747 int fh; 
     48 int val; 
     49 int err; 
    4850 
    4951 ROAR_DBG("roar_pcm_start(*) = ?"); 
     
    5355  return 0; 
    5456 
    55  if ( roar_vio_simple_new_stream_obj(&(self->stream_vio), &(self->roar.con), &(self->stream), 
    56     self->info.rate, self->info.channels, self->info.bits, self->info.codec, 
    57     io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR 
    58     ) == -1 ) { 
    59   return -EINVAL; 
     57 if ( (self->vss = roar_vs_new_from_con(&(self->roar.con), &err)) == NULL ) { 
     58  roar_err_set(err); 
     59  roar_err_update(); 
     60  return -errno; 
     61 } 
     62 
     63 if ( roar_vs_stream(self->vss, &(self->info), 
     64                     io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR, 
     65                     &err) == -1 ) { 
     66  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); 
     67  self->vss = NULL; 
     68  roar_err_set(err); 
     69  roar_err_update(); 
     70  return -errno; 
     71 } 
     72 
     73 if ( roar_vs_buffer(self->vss, self->bufsize, &err) == -1 ) { 
     74  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); 
     75  self->vss = NULL; 
     76  roar_err_set(err); 
     77  roar_err_update(); 
     78  return -errno; 
     79 } 
     80 
     81 val = ROAR_VS_ASYNCLEVEL_AUTO; 
     82 if ( roar_vs_ctl(self->vss, ROAR_VS_CMD_SET_ASYNC, &val, &err) == -1 ) { 
     83  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); 
     84  self->vss = NULL; 
     85  roar_err_set(err); 
     86  roar_err_update(); 
     87  return -errno; 
    6088 } 
    6189 
    6290 if ( self->stream_role != ROAR_ROLE_UNKNOWN ) { 
    63   if ( roar_stream_set_role(&(self->roar.con), &(self->stream), self->stream_role) == -1 ) { 
    64    ROAR_WARN("roar_pcm_start(*): Can not set stream role: %i: %s", self->stream_role, roar_error2str(roar_error)); 
     91  if ( roar_vs_role(self->vss, self->stream_role, &err) == -1 ) { 
     92   ROAR_WARN("roar_pcm_start(*): Can not set stream role: %s(%i): %s", 
     93             roar_role2str(self->stream_role), self->stream_role, roar_error2str(roar_error)); 
    6594  } 
    6695 } 
    6796 
    68  if ( roar_vio_ctl(&(self->stream_vio),  
     97 if ( roar_vio_ctl(roar_vs_vio_obj(self->vss, NULL),  
    6998    io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_VIO_CTL_GET_SELECT_WRITE_FH : 
    7099    ROAR_VIO_CTL_GET_SELECT_READ_FH, &fh) != 1 ) { 
     
    81110 self->stream_opened = 1; 
    82111 
    83  self->bufptr = 0; 
     112//RM: self->bufptr = 0; 
     113 ROAR_DBG("roar_pcm_start(*): Starting background thread"); 
    84114 self->thread_active = 1; // We have to activate the thread before starting it, because the thread lives on that thread_active is 1. 
    85115 if ( pthread_create(&(self->thread), NULL, roar_plugin_thread, self) < 0 ) { 
    86116  self->thread_active = 0; 
     117  ROAR_DBG("roar_pcm_start(*) = -1"); 
    87118  return -1; 
    88119 } 
    89  
     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 
     123 ROAR_DBG("roar_pcm_start(*) = 0"); 
    90124 return 0; 
    91125} 
     
    95129  return; 
    96130 
    97  roar_vio_close(&(self->stream_vio)); 
     131 roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); 
     132 self->vss = NULL; 
    98133 self->stream_opened = 0; 
    99134 self->thread_active = 0; 
    100  self->bufptr = 0; 
    101  self->last_ptr = 0; 
    102  self->total_written = 0; 
    103  self->has_written = 0; 
     135//RM: self->bufptr = 0; 
     136//RM: self->last_ptr = 0; 
     137//RM: self->total_written = 0; 
     138//RM: self->has_written = 0; 
    104139} 
    105140 
     
    198233 struct roar_alsa_pcm * self = io->private_data; 
    199234 int ptr; 
     235 ssize_t avail; 
    200236 
    201237 ROAR_DBG("roar_pcm_pointer(*) = ?"); 
     238 
    202239 // Did ALSA just call snd_pcm_reset() or something like that without calling the plugin?  
    203240 // We should restart our stream as well. 
     
    207244 } 
    208245 
     246#if 0 
    209247 // ALSA has a weird way of calculating how much data can be written to the audio buffer. 
    210248 // It uses the formula: 
     
    218256 ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufptr); 
    219257 pthread_mutex_unlock(&(self->lock)); 
     258#else 
     259 pthread_mutex_lock(&(self->lock)); 
     260 avail = roar_vs_get_avail_write(self->vss, NULL); 
     261 pthread_mutex_unlock(&(self->lock)); 
     262 
     263 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 
    220267 
    221268 ptr = io->appl_ptr - ptr; 
     
    261308static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) { 
    262309 struct roar_alsa_pcm * self = io->private_data; 
     310 roar_mus_t lat; 
    263311 
    264312 ROAR_DBG("roar_pcm_delay(*) = ?"); 
     
    266314 // TODO: We need to set *delayp the latency in frames. 
    267315 pthread_mutex_lock(&(self->lock)); 
    268  roar_plugin_drain(self); 
    269  *delayp = snd_pcm_bytes_to_frames(io->pcm, self->bytes_in_buffer); 
     316 roar_plugin_drain(self); // why do we call this? 
     317 
     318 lat = roar_vs_latency2(self->vss, ROAR_VS_BACKEND_DEFAULT, ROAR_VS_NOWAIT, NULL); 
     319 *delayp = lat * self->info.rate; 
     320 
    270321 pthread_mutex_unlock(&(self->lock)); 
    271322 
     
    373424 //self->bufsize = snd_pcm_frames_to_bytes(io->pcm, buffersize); 
    374425 self->bufsize = self->info.bits * self->info.channels * buffersize / 8; 
    375  self->buffer = malloc(self->bufsize); 
    376  if (self->buffer == NULL) 
    377   return -1; 
    378  self->bufptr = 0; 
     426//RM: self->buffer = malloc(self->bufsize); 
     427//RM: if (self->buffer == NULL) 
     428//RM:  return -1; 
     429//RM: self->bufptr = 0; 
    379430 
    380431 ROAR_DBG("roar_pcm_hw_params(*) Setting buffersize (bytes): %i", (int)self->bufsize); 
     
    398449 pthread_cond_destroy(&(self->cond)); 
    399450 
    400  free(self->buffer); 
     451//RM: free(self->buffer); 
    401452 free(self); 
    402453 
  • plugins/alsavs/roar.h

    r5168 r5174  
    5757 struct roar_alsa       roar; 
    5858 struct roar_audio_info info; 
    59  struct roar_stream     stream; 
    60  struct roar_vio_calls  stream_vio; 
     59 roar_vs_t            * vss; 
    6160 int                    stream_role; 
    6261 int                    stream_opened; 
    63  size_t                 writec; 
     62 size_t                 _writec; 
    6463 size_t                 last_ptr; 
    65  char*                  buffer; 
     64 char*                  _buffer; 
    6665 size_t                 bufsize; 
    67  volatile size_t        bufptr; 
     66 volatile size_t        _bufptr; 
    6867 pthread_t              thread; 
    6968 pthread_mutex_t        lock; 
     
    7170 pthread_cond_t         cond; 
    7271 volatile int           thread_active; 
    73  int                    bytes_in_buffer; 
    74  volatile int64_t       total_written; 
    75  int                    has_written; 
    76  struct timespec        start_tv; 
     72 int                    _bytes_in_buffer; 
     73 volatile int64_t       _total_written; 
     74 int                    _has_written; 
     75 struct timespec        _start_tv; 
    7776}; 
    7877 
  • plugins/alsavs/thread.c

    r5157 r5174  
    4242 
    4343 
     44 
     45/* 
     46 * The following function should be re-written: 
     47 * write in a loop untill all date is written, 
     48 * if vs write returns less than requested call the thread and ask it to iterate. 
     49 */ 
     50 
    4451// Writes to the FIFO buffer. Waits until there is room to write. 
    4552size_t roar_plugin_write(struct roar_alsa_pcm *self, const char *buf, size_t size) { 
     53 ssize_t ret; 
     54 
     55 ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu) = ?", self, buf, (long long unsigned int)size); 
     56 
     57#if 0 
    4658 /* Wait until we have a ready buffer */ 
    4759 while (1) { 
     
    5264  //fprintf(stderr, "%d + %d : %d\n", (int)self->bufptr, (int)size, (int)self->bufsize); 
    5365  pthread_mutex_lock(&(self->lock)); 
    54   if (self->bufptr + size <= self->bufsize) { 
     66  if (roar_vs_get_avail_write(self->vss, NULL) >= (ssize_t)size) { 
    5567   pthread_mutex_unlock(&(self->lock)); 
    5668   break; 
     
    5870  pthread_mutex_unlock(&(self->lock)); 
    5971 
     72  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Send signal", self, buf, (long long unsigned int)size); 
    6073  pthread_cond_signal(&(self->cond)); 
    6174  /* Sleeps until we can write to the FIFO. */ 
     75  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Waiting for answer", self, buf, (long long unsigned int)size); 
    6276  pthread_mutex_lock(&(self->cond_lock)); 
    6377  pthread_cond_wait(&(self->cond), &(self->cond_lock)); 
    6478  pthread_mutex_unlock(&(self->cond_lock)); 
    6579 } 
    66  
    67  pthread_mutex_lock(&(self->lock)); 
    68  memcpy(self->buffer + self->bufptr, buf, size); 
    69  self->bufptr += (int)size; 
    70  pthread_mutex_unlock(&(self->lock)); 
    71  
    72  /* Send signal to thread that buffer has been updated */ 
    73  pthread_cond_signal(&(self->cond)); 
     80#endif 
     81 
     82 
     83 while (size) { 
     84  pthread_mutex_lock(&(self->lock)); 
     85  ret = roar_vs_write(self->vss, buf, size, NULL); 
     86  pthread_mutex_unlock(&(self->lock)); 
     87 
     88  if ( ret == -1 ) { 
     89   ROAR_WARN("roar_plugin_write(self=%p, buf=?, size=?): Can not write data: %s", self, roar_error2str(roar_error)); 
     90   return -1; 
     91  } 
     92 
     93  size -= ret; 
     94  buf  += ret; 
     95 
     96  /* Send signal to thread that buffer has been updated */ 
     97  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Send signal", self, buf, (long long unsigned int)size); 
     98  pthread_cond_signal(&(self->cond)); 
     99 } 
    74100 
    75101 return size; 
     
    83109// Attemps to drain the buffer at all times and write to libroar. 
    84110// If there is no data, it will wait for roar_plugin_write() to fill up more data. 
    85 void* roar_plugin_thread (void * thread_data) { 
     111void * roar_plugin_thread (void * thread_data) { 
    86112 /* We share data between thread and callable functions */ 
    87113 struct roar_alsa_pcm *self = thread_data; 
    88114 int rc; 
     115 int err; 
     116 
     117 ROAR_DBG("roar_plugin_thread(thread_data=%p) = ?", thread_data); 
     118 pthread_mutex_unlock(&(self->lock)); // we are now up. 
    89119 
    90120 /* Plays back data as long as there is data in the buffer. Else, sleep until it can. */ 
    91121 /* Two loops! :3 Beware! */ 
    92122 while(1) { 
     123  ROAR_DBG("roar_plugin_thread(thread_data=%p): got woken up.", thread_data); 
    93124  while(1) { 
    94125   _TEST_CANCEL(); 
     
    96127   // We only bother to check after 1 sec of audio has been played, as it might be quite inaccurate in the start of the stream. 
    97128 
     129   // do wee need to lock before this? 
     130   pthread_mutex_lock(&(self->lock)); 
     131   ROAR_DBG("roar_plugin_thread(thread_data=%p): Start iterate", thread_data); 
     132   rc = roar_vs_iterate(self->vss, ROAR_VS_WAIT, &err); 
     133   ROAR_DBG("roar_plugin_thread(thread_data=%p): Ended iterate", thread_data); 
     134   pthread_mutex_unlock(&(self->lock)); 
     135 
     136   if ( rc == 0 ) { 
     137    break; 
     138   } else if ( rc < 0 ) { 
     139    _TEST_CANCEL(); 
     140    roar_plugin_reset(self); 
     141 
     142    /* Wakes up a potentially sleeping fill_buffer() */ 
     143    pthread_cond_signal(&(self->cond)); 
     144 
     145    /* This thread will not be joined, so detach. */ 
     146    pthread_detach(pthread_self()); 
     147    pthread_exit(NULL); 
     148   } 
     149 
     150   pthread_cond_signal(&(self->cond)); 
     151 
     152#if 0 
    98153   /* If the buffer is empty or we've stopped the stream. Jump out of this for loop */ 
    99154   pthread_mutex_lock(&(self->lock)); 
     
    139194   /* Buffer has decreased, signal fill_buffer() */ 
    140195   pthread_cond_signal(&(self->cond)); 
    141  
    142   } 
     196#endif 
     197 
     198  } 
     199  ROAR_DBG("roar_plugin_thread(thread_data=%p): going to sleep again.", thread_data); 
    143200 
    144201  /* If we're still good to go, sleep. We are waiting for fill_buffer() to fill up some data. */ 
    145202test_quit: 
    146203  if ( self->thread_active ) { 
    147    pthread_cond_signal(&(self->cond)); 
     204   //struct timespec abstime = {0, 1000*1000*100}; 
     205   pthread_cond_signal(&(self->cond)); 
     206   ROAR_DBG("roar_plugin_thread(thread_data=%p): Wating for wakeup", thread_data); 
    148207   pthread_mutex_lock(&(self->cond_lock)); 
    149208   pthread_cond_wait(&(self->cond), &(self->cond_lock)); 
     
    159218 
    160219void roar_plugin_drain(struct roar_alsa_pcm *self) { 
     220#if 0 
    161221 struct timespec now_tv; 
    162222 int64_t temp, temp2; 
     
    183243  self->bytes_in_buffer = self->bufptr; 
    184244 } 
     245#endif 
     246 ROAR_DBG("roar_plugin_drain(self=%p) = (void)", self); 
    185247} 
    186248 
Note: See TracChangeset for help on using the changeset viewer.