int logg_update_stream(LOGG_Stream* s) { unsigned char* data = get_audio_stream_buffer(s->audio_stream); if (!data) { if (s->current_page != s->playing_page) { int read = read_ogg_data(s); if (read < logg_bufsize) { return 0; } else { return 1; } } else { return 1; } } s->playing_page++; s->playing_page %= OGG_PAGES_TO_BUFFER; memcpy(data, s->buf[s->playing_page], logg_bufsize); free_audio_stream_buffer(s->audio_stream); return 1; }
void saPlayStreamedSampleBase( int channel, signed char *data, int len, int freq, int volume, int bits , int pan ){ // This one should leave most of the sync work to allegro int pos; void *buff; // position in the stream unsigned short *dout; signed short *din; int i; if (bits == 8) { fprintf(stderr,"error: Can't play 8 bits\n"); // Just because I don't want to bother with this now. return; } if( audio_sample_rate == 0 || channel >= NUMVOICES ) return; if( SndMachine == NULL ) return; if( !playing[channel] ){ if( stream[channel] ){ stop_audio_stream(stream[channel]); free_audio_stream_buffer(stream[channel]); stream[channel] = NULL; } if (!(stream[channel] = play_audio_stream(len,bits,0,freq,volume,pan))){ return; } playing[channel] = 1; /* use front surface */ // Wait for the buffer to be ready... while (!(buff = get_audio_stream_buffer(stream[channel]))); //print_debug("first stream entry. [%d:%d:%d:%d]\n", channel, len, freq, volume ); } if (!(buff = get_audio_stream_buffer(stream[channel]))) { fprintf(stderr,"init stream impossible : buffer NULL\n"); return; } // fprintf(stderr,"len memcpy : %d\n",len); dout=buff; din = ((signed short*)data); for (i=0; i<len; i+=2) *(dout++) = *(din++)^0x8000; //fprintf(stderr,"set chanel vol = %d\n",volume); }
void CSoundStream::AddData (BYTE* pbData_, int nLength_) { // We must have some samples or there's be nothing to do if (nLength_ > 0) { int nSpace = m_pbEnd - m_pbNow; // Overflow? If so, discard all we've got to force the callback to correct it if (nLength_ > nSpace) { // m_pbNow = m_pbStart + (m_nSampleBufferSize >> 1); TRACE("Overflowed by %d samples\n", (nLength_-nSpace)/m_nSampleSize); } // Append the new block else { memcpy(m_pbNow, pbData_, nLength_); m_pbNow += nLength_; } } BYTE* pb = NULL; while (m_pStream && (pb = reinterpret_cast<BYTE*>(get_audio_stream_buffer(m_pStream)))) { int nNeed = FRAGMENT_SIZE*m_nSampleSize, nData = m_pbNow-m_pbStart, nCopy = min(nNeed,nData); if (nCopy) { memcpy(pb, m_pbStart, nCopy); memmove(m_pbStart, m_pbStart+nCopy, nData-nCopy); m_pbNow = m_pbStart + nData-nCopy; nNeed -= nCopy; } if (nNeed) { TRACE("Short by %d samples\n", nNeed/m_nSampleSize); Generate(pb+nCopy, nNeed/m_nSampleSize); int nPad = (m_nSampleBufferSize >> 1); if (nCopy && nNeed != nPad) { Generate(m_pbStart, nPad/m_nSampleSize); m_pbNow = m_pbStart + nPad; } } free_audio_stream_buffer(m_pStream); } }
void SoundDriver_Allegro::MainLoop() { /* We haven't opened a stream yet */ if (_stream == NULL) return; void *data = get_audio_stream_buffer(_stream); /* We don't have to fill the stream yet */ if (data == NULL) return; /* Mix the samples */ MxMixSamples(data, _buffer_size); /* Allegro sound is always unsigned, so we need to correct that */ uint16 *snd = (uint16*)data; for (int i = 0; i < _buffer_size * 2; i++) snd[i] ^= 0x8000; /* Tell we've filled the stream */ free_audio_stream_buffer(_stream); }
int al_poll_duh(AL_DUH_PLAYER *dp) { unsigned short *sptr; long n; long size; int n_channels; if (!dp || !dp->sigrenderer) return 1; if (!(dp->flags & ADP_PLAYING)) return 0; sptr = get_audio_stream_buffer(dp->stream); if (!sptr) return 0; n = duh_render(dp->sigrenderer, 16, 1, dp->volume, 65536.0 / dp->freq, dp->bufsize, sptr); if (n == 0) { if (++dp->silentcount >= 2) { duh_end_sigrenderer(dp->sigrenderer); free_audio_stream_buffer(dp->stream); stop_audio_stream(dp->stream); dp->sigrenderer = NULL; return 1; } } n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer); n *= n_channels; size = dp->bufsize * n_channels; for (; n < size; n++) sptr[n] = 0x8000; free_audio_stream_buffer(dp->stream); return 0; }
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; }
int alogg_poll_ogg(ALOGG_OGG *ogg) { void *audiobuf; char *audiobuf_p; int i, size_done; /* continue only if we are playing it */ if (!alogg_is_playing_ogg(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 16bit unsigned 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->loop) { if (ogg->wait_for_audio_stop > 0) { free_audio_stream_buffer(ogg->audiostream); if (--ogg->wait_for_audio_stop == 0) { /* stop it */ //rest(500); alogg_stop_ogg(ogg); return ALOGG_POLL_PLAYJUSTFINISHED; } else return ALOGG_OK; } } audiobuf_p = (char *)audiobuf; size_done = 0; for (i = ogg->audiostream_buffer_len; i > 0; i -= size_done) { /* decode */ 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_ogg(ogg); alogg_rewind_ogg(ogg); return ALOGG_POLL_FRAMECORRUPT; } } else if (size_done == 0) { /* we have reached the end */ alogg_rewind_ogg(ogg); if (!ogg->loop) { free_audio_stream_buffer(ogg->audiostream); 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; }
int alogg_poll_ogg_ts(ALOGG_OGG *ogg) { void *audiobuf; char *audiobuf_p; unsigned short *audiobuf_sp; int i, size_done, finished = 0; /* continue only if we are playing it */ if (!alogg_is_playing_ogg(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 16bit unsigned 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->loop) { if (ogg->wait_for_audio_stop > 0) { free_audio_stream_buffer(ogg->audiostream); if (--ogg->wait_for_audio_stop == 0) { /* stop it */ alogg_stop_ogg(ogg); return ALOGG_POLL_PLAYJUSTFINISHED; } else return ALOGG_OK; } } audiobuf_sp = (unsigned short *)audiobuf; while (!finished && rubberband_available(ogg->time_stretch_state) < ogg->time_stretch_buffer_samples) { /* reset these each iteration so we don't overrun the buffer */ audiobuf_p = (char *)audiobuf; size_done = 0; /* read samples from Ogg Vorbis file */ for (i = ogg->audiostream_buffer_len; i > 0; i -= size_done) { /* decode */ size_done = ov_read(&(ogg->vf), audiobuf_p, i, alogg_endianess, 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_ogg(ogg); alogg_rewind_ogg(ogg); return ALOGG_POLL_FRAMECORRUPT; } } else if (size_done == 0) { alogg_rewind_ogg(ogg); ogg->wait_for_audio_stop = 2; finished = 1; break; // playback finished so get out of loop } audiobuf_p += size_done; } /* process samples with Rubber Band */ if (ogg->stereo) { for (i = 0; i < ogg->time_stretch_buffer_samples; i++) { ogg->time_stretch_buffer[0][i] = (float)((long)audiobuf_sp[i * 2] - 0x8000) / (float)0x8000; //Convert sample to signed floating point format ogg->time_stretch_buffer[1][i] = (float)((long)audiobuf_sp[i * 2 + 1] - 0x8000) / (float)0x8000; //Repeat for the other channel's sample } } else { for (i = 0; i < ogg->time_stretch_buffer_samples; i++) { ogg->time_stretch_buffer[0][i] = (float)((long)audiobuf_sp[i] - 0x8000) / (float)0x8000; //Convert sample to signed floating point format } } rubberband_process(ogg->time_stretch_state, (const float **)ogg->time_stretch_buffer, ogg->time_stretch_buffer_samples, 0); } /* retrieve audio from rubberband and put it into stream buffer */ size_done = rubberband_retrieve(ogg->time_stretch_state, ogg->time_stretch_buffer, ogg->time_stretch_buffer_samples); if (ogg->stereo) { for (i = 0; i < size_done; i++) { if(ogg->time_stretch_buffer[0][i] > 1.0) { audiobuf_sp[i * 2] = 0xFFFF; } else if(ogg->time_stretch_buffer[0][i] < -1.0) { audiobuf_sp[i * 2] = 0; } else { audiobuf_sp[i * 2] = (ogg->time_stretch_buffer[0][i] * (float)0x8000) + (float)0x8000; //Convert sample back to unsigned integer format } if(ogg->time_stretch_buffer[1][i] > 1.0) { audiobuf_sp[i * 2 + 1] = 0xFFFF; } else if(ogg->time_stretch_buffer[1][i] < -1.0) { audiobuf_sp[i * 2 + 1] = 0; } else { audiobuf_sp[i * 2 + 1] = (ogg->time_stretch_buffer[1][i] * (float)0x8000) + (float)0x8000; //Repeat for the other channel's sample } } } else { for (i = 0; i < size_done; i++) { if(ogg->time_stretch_buffer[0][i] > 1.0) { audiobuf_sp[i] = 0xFFFF; } else if(ogg->time_stretch_buffer[0][i] < -1.0) { audiobuf_sp[i] = 0; } else { audiobuf_sp[i] = (ogg->time_stretch_buffer[0][i] * (float)0x8000) + (float)0x8000; //Convert sample back to unsigned integer format } } } /* lock the buffer */ if(alogg_buffer_callback) { alogg_buffer_callback(audiobuf, ogg->audiostream_buffer_len); } free_audio_stream_buffer(ogg->audiostream); return ALOGG_OK; }