int alogg_play_ex_oggstream(ALOGG_OGGSTREAM *ogg, int buffer_len, int vol, int pan, int speed) {
  int samples;
 
  /* continue only if we are not already playing it */
  if (alogg_is_playing_oggstream(ogg))
    return ALOGG_OK;

  /* check the buffer is big enough*/
  if (buffer_len < 4096)
    return ALOGG_PLAY_BUFFERTOOSMALL;
   
  /* create a new audiostream and play it */
  samples = buffer_len / (ogg->stereo ? 2 : 1) / 2; /* / 2 = 16 bits samples */
  ogg->audiostream = play_audio_stream(samples, 16, ogg->stereo, ogg->freq, vol, pan);
  ogg->audiostream_buffer_len = samples * (ogg->stereo ? 2 : 1) * 2; /* * 2 = 16 bits samples */

  ogg->wait_for_audio_stop = 0;

  if (speed != 1000)
    adjust_sample(ogg->audiostream->samp, vol, pan, speed, TRUE);

  /* if the user asked for autopolling, install the interrupt now */
  if (ogg->auto_polling) {
    LOCK_FUNCTION(alogg_autopoll_oggstream);
    install_param_int(&alogg_autopoll_oggstream, (void *)ogg, ogg->auto_poll_speed);
  }

  return ALOGG_OK;
}
void alogg_adjust_oggstream(ALOGG_OGGSTREAM *ogg, int vol, int pan, int speed) {
  /* return if we are not playing */
  if (!alogg_is_playing_oggstream(ogg))
    return;

  /* adjust the sample */
  adjust_sample(ogg->audiostream->samp, vol, pan, speed, TRUE);
}
void *alogg_get_output_wave_oggstream(ALOGG_OGGSTREAM *ogg, int *buffer_size) {
  /* return if we are not playing */
  if (!alogg_is_playing_oggstream(ogg))
    return NULL;

  /* set the buffer_size */
  *buffer_size = ogg->audiostream_buffer_len;

  /* return the current audiostream sample data */
  return (ogg->audiostream->samp->data);
}
void alogg_stop_autopoll_oggstream(ALOGG_OGGSTREAM *ogg) {
  /* return if we are already not auto polling */
  if (!ogg->auto_polling)
    return;

  ogg->auto_polling = FALSE;

  /* only remove the interrupt if we were already playing */
  /* otherwise, stop will do*/
  if (alogg_is_playing_oggstream(ogg))
    remove_param_int(&alogg_autopoll_oggstream, (void *)ogg);
}
void alogg_stop_oggstream(ALOGG_OGGSTREAM *ogg) {
  /* continue if we are playing it */
  if (!alogg_is_playing_oggstream(ogg))
    return;

  /* remove the interrupt, if we were using autopolling */
  if (ogg->auto_polling)
    remove_param_int(&alogg_autopoll_oggstream, (void *)ogg);

  /* stop the audio stream */
  stop_audio_stream(ogg->audiostream);
  ogg->audiostream = NULL;
}
void alogg_start_autopoll_oggstream(ALOGG_OGGSTREAM *ogg, int speed) {
  /* return if we are already auto polling */
  if (ogg->auto_polling)
    return;

  ogg->auto_polling = TRUE;
  ogg->auto_poll_speed = speed;

  /* only install the interrupt if we are already playing */
  /* otherwise, play will do */
  if (alogg_is_playing_oggstream(ogg)) {
    LOCK_FUNCTION(alogg_autopoll_oggstream);
    install_param_int(&alogg_autopoll_oggstream, (void *)ogg, ogg->auto_poll_speed);
  }
}
Beispiel #7
0
int MYOGG::get_pos_ms()
{
    // Unfortunately the alogg_get_pos_msecs_oggstream function
    // returns the ms offset that was last decoded, so it's always
    // ahead of the actual playback. Therefore we have this
    // hideous hack below to sort it out.
    if ((done) || (!alogg_is_playing_oggstream(stream)))
        return 0;

    AUDIOSTREAM *str = alogg_get_audiostream_oggstream(stream);
    long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq;

    if (last_ms_offs != alogg_get_pos_msecs_oggstream(stream)) {
        last_but_one_but_one = last_but_one;
        last_but_one = last_ms_offs;
        last_ms_offs = alogg_get_pos_msecs_oggstream(stream);
    }

    // just about to switch buffers
    if (offs < 0)
        return last_but_one;

    int end_of_stream = alogg_is_end_of_oggstream(stream);

    if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == NULL)) {
        switch (end_of_stream) {
case 0:
case 2:
    offs -= (last_but_one - last_but_one_but_one);
    break;
case 1:
    offs -= (last_but_one - last_but_one_but_one);
    break;
        }
    }

    /*    char tbuffer[260];
    sprintf(tbuffer,"offs: %d  last_but_one_but_one: %d  last_but_one: %d  active:%d  locked: %p   EOS: %d",
    offs, last_but_one_but_one, last_but_one, str->active, str->locked, end_of_stream);
    write_log(tbuffer);*/

    if (end_of_stream == 1) {

        return offs + last_but_one;
    }

    return offs + last_but_one_but_one;
}
int alogg_poll_oggstream(ALOGG_OGGSTREAM *ogg) {
  void *audiobuf;
  char *audiobuf_p;
  int i, size_done;
  int last_block;

  /* continue only if we are playing it */
  if (!alogg_is_playing_oggstream(ogg))
    return ALOGG_POLL_NOTPLAYING;

  /* get the audio stream buffer and only continue if we need to fill it */
  audiobuf = get_audio_stream_buffer(ogg->audiostream);
  if (audiobuf == NULL)
    return ALOGG_OK;

  /* clear the buffer with unsinged data*/
  {
    int i;
    unsigned short *j = (unsigned short *)audiobuf;
    for (i = 0; i < (ogg->audiostream_buffer_len / 2); i++, j++)
      *j = 0x8000;
  }

  /* if we need to fill it, but we were just waiting for it to finish */
  if (ogg->wait_for_audio_stop > 0) {
    free_audio_stream_buffer(ogg->audiostream);
    if (--ogg->wait_for_audio_stop == 0) {
      /* stop it */
      alogg_stop_oggstream(ogg);
      return ALOGG_POLL_PLAYJUSTFINISHED;
    }
    else
      return ALOGG_OK;
  }

  /* get if this will be the last block to be processed */
  if (ogg->bytes_used != -1)
    last_block = TRUE;
  else
    last_block = FALSE;

  audiobuf_p = (char *)audiobuf;
  size_done = 0;
  for (i = ogg->audiostream_buffer_len; i > 0; i -= size_done) {
    size_done = ov_read(&(ogg->vf), audiobuf_p, i, 0, 2, 0, &(ogg->current_section));

    /* check if the decoding was not successful */
    if (size_done < 0) {
      if (size_done == OV_HOLE)
        size_done = 0;
      else {
        free_audio_stream_buffer(ogg->audiostream);
        alogg_stop_oggstream(ogg);
        return ALOGG_POLL_FRAMECORRUPT;
      }
    }
    else if (size_done == 0) {
      free_audio_stream_buffer(ogg->audiostream);
      /* if this was not the last block, buffer underrun */
      if (!last_block) {
        alogg_stop_oggstream(ogg);
        return ALOGG_POLL_BUFFERUNDERRUN;
      }
      /* else we just finished playing, we need to wait for audio to stop */
      else {
        ogg->wait_for_audio_stop = 2;
        return ALOGG_OK;
      }
    }

    audiobuf_p += size_done;
  }

  /* lock the buffer */
  free_audio_stream_buffer(ogg->audiostream);

  return ALOGG_OK;
}