Exemple #1
0
/**
 * @brief Loads a buffer.
 *
 *    @param buffer Buffer to load.
 */
static int stream_loadBuffer( ALuint buffer )
{
   int ret, size, section, result;

   musicVorbisLock();

   /* Make sure music is valid. */
   if (music_vorbis.rw == NULL) {
      musicVorbisUnlock();
      return -1;
   }

   ret  = 0;
   size = 0;
   while (size < music_bufSize) { /* fille up the entire data buffer */

      result = ov_read_filter(
            &music_vorbis.stream,   /* stream */
            &music_buf[size],       /* data */
            music_bufSize - size,   /* amount to read */
            VORBIS_ENDIAN,          /* big endian? */
            2,                      /* 16 bit */
            1,                      /* signed */
            &section,               /* current bitstream */
            rg_filter,              /* filter function */
            &music_vorbis );        /* filter parameter */

      /* End of file. */
      if (result == 0) {
         if (size == 0) {
            musicVorbisUnlock();
            return -2;
         }
         ret = 1;
         break;
      }
      /* Hole error. */
      else if (result == OV_HOLE) {
         musicVorbisUnlock();
         WARN("OGG: Vorbis hole detected in music!");
         return 0;
      }
      /* Bad link error. */
      else if (result == OV_EBADLINK) {
         musicVorbisUnlock();
         WARN("OGG: Invalid stream section or corrupt link in music!");
         return -1;
      }

      size += result;
   }

   musicVorbisUnlock();

   /* load the buffer up */
   soundLock();
   alBufferData( buffer, music_vorbis.format,
         music_buf, size, music_vorbis.info->rate );
   soundUnlock();

   return ret;
}
Exemple #2
0
static void* player_thread(void* _minfo) 
{
  ogg_t* minfo = (ogg_t*) _minfo;
  
  log_debug("ogg player started");
  
  long current_position_in_ms = 0;
  long previous_position_in_ms = -1; 
  long guard_position_in_ms = -1;
  el_bool playing = el_false;
  
  post_event(minfo->client_notification, AUDIO_READY, current_position_in_ms);
 
  audio_event_t *event;
  event = audio_event_fifo_dequeue(minfo->player_control);
  while (event->state != INTERNAL_CMD_DESTROY) {
    
    audio_state_t event_state = event->state;
    long event_position = event->position_in_ms;
    audio_event_destroy(event);
    
    switch (event_state) {
      case INTERNAL_CMD_LOAD_FILE: {
        playing = el_false;
        if (minfo->is_open) {
          ov_clear(&minfo->vf);
          fclose(minfo->fh);
          aodev_close(minfo->ao_handle);
        }

        minfo->fh = fopen(minfo->file_or_url, "rb");
        if (minfo->fh != NULL) {
          if (ov_open_callbacks(minfo->fh , &minfo->vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0) {
            fclose(minfo->fh);
            post_event(minfo->client_notification, AUDIO_NOT_SUPPORTED, -1);
            minfo->is_open = el_false;
          } else {
            minfo->is_open = el_true;
            minfo->can_seek = ov_seekable(&minfo->vf);
            minfo->length = (long) (ov_time_total(&minfo->vf, -1) * 1000.0);
            psem_post(minfo->length_set);
            minfo->current_section = 0;
            vorbis_info* vi = ov_info(&minfo->vf, -1);
            aodev_set_format(minfo->ao_handle, 16, vi->rate, vi->channels);
            aodev_set_endian(minfo->ao_handle, AO_FMT_LITTLE);
            aodev_open(minfo->ao_handle);
          }
        } else {
          post_event(minfo->client_notification, AUDIO_IO_ERROR, -1);
          minfo->is_open = el_false;
        }
        
        current_position_in_ms = 0;
        guard_position_in_ms = -1; 
        
        log_debug("Stream initialized");
          
      }
      break;
      case INTERNAL_CMD_LOAD_URL: {
      }
      break;
      case INTERNAL_CMD_SEEK: {
        ov_time_seek_lap(&minfo->vf, ((double) event_position / 1000.0));
      }
      break;
      case INTERNAL_CMD_PLAY: {
        playing = el_true;
      }
      break;
      case INTERNAL_CMD_PAUSE: {
        playing = el_false;
      }
      break;
      case INTERNAL_CMD_GUARD: {
        guard_position_in_ms = event_position;
      }
      break;
      case INTERNAL_CMD_SET_VOLUME: {
        double scale = ((double) event_position) / 1000.0;
        minfo->volume_scale = scale;
        log_debug2("setting volume to %lf", scale);
      }
      break;
      case INTERNAL_CMD_NONE:
      break;
      default:
      break;
    }
    
    if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) {

      guard_position_in_ms = -1;
      post_event(minfo->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms);
      
    } else if (playing) {
      if (minfo->is_file) {
        int n = ov_read_filter(&minfo->vf, minfo->buffer, BUFFER_SIZE(minfo), 0, 2, 1, &minfo->current_section,
                               adjust_volume, minfo
                              );
        if (n > 0) {
          aodev_play_buffer(minfo->ao_handle, minfo->buffer, n);
          //log_debug("buffer played");
          
          double tm = ov_time_tell(&minfo->vf);
          current_position_in_ms = (long) (tm * 1000.0);
          
          if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
            post_event(minfo->client_notification, AUDIO_PLAYING, current_position_in_ms);
          }
          previous_position_in_ms = current_position_in_ms;
          
        } else {
          post_event(minfo->client_notification, AUDIO_EOS, current_position_in_ms);
          playing = el_false;
        } 
      } else { // Stream playing
        post_event(minfo->client_notification, AUDIO_STATE_ERROR, -1);
        playing = el_false;
      } 
    
    }
    
    if (playing) {
      if (audio_event_fifo_peek(minfo->player_control) != NULL) {
        event = audio_event_fifo_dequeue(minfo->player_control);
      } else {
        event = (audio_event_t*) mc_malloc(sizeof(audio_event_t));
        event->state = INTERNAL_CMD_NONE;
        event->position_in_ms = -1;
      }
    } else {
      event = audio_event_fifo_dequeue(minfo->player_control);
    }
  }

  // destroy event received
  audio_event_destroy(event);

  // exit thread  
  return NULL;
}