示例#1
0
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;
}
示例#2
0
文件: sasound.c 项目: albinoz/raine
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);
}
示例#3
0
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);
}
示例#5
0
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;
}
示例#6
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;
}
示例#7
0
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;
}
示例#8
0
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;
}