예제 #1
0
파일: ogg.c 프로젝트: sesc4mt/mvcdecoder
static bool ogg_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time)
{
   AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra;
   if (time >= extra->loop_end)
      return false;
#if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE) 
   return (ov_time_seek_lap(extra->vf, time) != -1);
#else
   return ov_time_seek(extra->vf, time*1000) != -1;
#endif
}
예제 #2
0
파일: ogg.c 프로젝트: hdijkema/BackToBasics
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;
}