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); } }
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; }