Ejemplo n.º 1
0
void test_push_mode_forever(FILE *g, char *filename)
{
   int p,q, len, error, used;
   uint8 *data = stb_file(filename, &len);
   stb_vorbis *v;

   if (!data) stb_fatal("Couldn't open {%s}", filename);

   p = 0;
   q = 1;
  retry:
   v = stb_vorbis_open_pushdata(data, q, &used, &error, NULL);
   if (v == NULL) {
      if (error == VORBIS_need_more_data) {
         q += 1;
         goto retry;
      }
      printf("Error %d\n", error);
      exit(1);
   }
   p += used;

   show_info(v);

   for(;;) {
      int k=0;
      int n;
      float *left, *right;
      float **outputs;
      int num_c;
      q = 32;
      retry3:
      if (q > len-p) q = len-p;
      used = stb_vorbis_decode_frame_pushdata(v, data+p, q, &num_c, &outputs, &n);
      if (used == 0) {
         if (p+q == len) {
            // seek randomly when at end... this makes sense when listening to it, but dumb when writing to file
            p = stb_rand();
            if (p < 0) p = -p;
            p %= (len - 8000);
            stb_vorbis_flush_pushdata(v);
            q = 128;
            goto retry3;
         }
         if (q < 128) q = 128;
         q *= 2;
         goto retry3;
      }
      p += used;
      if (n == 0) continue;
      left = outputs[0];
      right = num_c > 1 ? outputs[1] : outputs[0];
      write_floats(g, n, left, right);
   }
   stb_vorbis_close(v);
}
Ejemplo n.º 2
0
// in push mode, you can load your data any way you want, then
// feed it a little bit at a time. this is the preferred way to
// handle reading from a packed file or some custom stream format;
// instead of putting callbacks inside stb_vorbis, you just keep
// a little buffer (it needs to be big enough for one packet of
// audio, except at the beginning where you need to buffer up the
// entire header).
//
// for this test, I just load all the data and just lie to stb_vorbis
// and claim I only have a little of it
void test_decode_frame_pushdata(FILE *g, char *filename)
{
   int p,q, len, error, used;
   stb_vorbis *v;
   uint8 *data = stb_file(filename, &len);

   if (!data) stb_fatal("Couldn't open {%s}", filename);

   p = 0;
   q = 1;
  retry:
   v = stb_vorbis_open_pushdata(data, q, &used, &error, NULL);
   if (v == NULL) {
      if (error == VORBIS_need_more_data) {
         q += 1;
         goto retry;
      }
      fprintf(stderr, "Error %d\n", error);
      exit(1);
   }
   p += used;

   show_info(v);

   for(;;) {
      int k=0;
      int n;
      float *left, *right;
      uint32 next_t=0;

      float **outputs;
      int num_c;
      q = 32;
     retry3:
      if (q > len-p) q = len-p;
      used = stb_vorbis_decode_frame_pushdata(v, data+p, q, &num_c, &outputs, &n);
      if (used == 0) {
         if (p+q == len) break; // no more data, stop
         if (q < 128) q = 128;
         q *= 2;
         goto retry3;
      }
      p += used;
      if (n == 0) continue; // seek/error recovery
      left = outputs[0];
      right = num_c > 1 ? outputs[1] : outputs[0];
      write_floats(g, n, left, right);
   }
   stb_vorbis_close(v);
}
Ejemplo n.º 3
0
	S32 PCMAudioManager::playStreamingSound(const char *assetName, S16 loops, F32 leftVol, F32 rightVol, F32 rate) {
		if (leftVol < 0) {
			leftVol = 0;
		} else if (leftVol > 1) {
			leftVol = 1;
		}
		if (rightVol < 0) {
			rightVol = 0;
		} else if (rightVol > 1) {
			rightVol = 1;
		}
		S32 streamId = -1;
		//char buf[50];
		//sprintf(buf, "Playing sound %i", soundId);
		//logmsg(buf);
		// create a stream
		BOOL32 success = FALSE;
		for (S32 i = 0; i < streamCount; i++) {
			PCMStream *stream = &pcmStreams[i];
			if (!stream->isPlaying && !stream->audioHandle) {
				//sprintf(buf, "Using Stream %i", i);
				//logmsg(buf);
				// use this stream;
				stream->isStreaming = TRUE;
				stream->pcmSound = NULL;
				stream->loopsRemaining = loops;
				stream->bufferPosition = 0;
				stream->overallPosition = 0;
				streamId = ++lastStreamId;
				stream->streamId = streamId;
				stream->volumeLeft = leftVol;
				stream->volumeRight = rightVol;
				stream->assetName = strDuplicate(assetName);
				stream->channels = 0;
				stream->playbackRate = rate;
				stream->filePosition = 0;
				stream->assetLength = _platform_get_asset_length(assetName);
				if (stream->assetLength > 0) {
					// get vorbis handle and read info
					// fill both audio buffers
					if (!stream->audioBuf) {
						stream->audioBuf = new S16*[PCM_AUDIO_STREAM_BUFFERS];
						for (S32 j = 0; j < PCM_AUDIO_STREAM_BUFFERS; j++) {
							stream->audioBuf[j] = new S16[PCM_AUDIO_STREAM_BUFFER_SIZE];
						}
					}
					unsigned char buf[CHUNKED_READ_BUFFER_SIZE];
					BOOL32 eof = FALSE;
					S32 bytesRead = _platform_read_asset_chunk(assetName, 0, buf, CHUNKED_READ_BUFFER_SIZE, &eof);
					S32 bytesConsumed;
					S32 error;
					// start vorbis pushdata
					stb_vorbis *vorb = stb_vorbis_open_pushdata(buf, bytesRead, &bytesConsumed, &error, NULL);
					stb_vorbis_info info = stb_vorbis_get_info(vorb);
					stream->channels = info.channels;
					stream->sampleRate = info.sample_rate;
					stream->maxFrameSize = info.max_frame_size;
					stream->length = 0; // unknown until we hit eof
					stream->tempLength = 0;
					stream->filePosition = bytesConsumed;
					stream->audioHandle = vorb;
					stream->resampleActiveRate = stream->sampleRate * stream->playbackRate;
					stream->resampleInt = stream->resampleActiveRate / PCM_AUDIO_PLAYBACK_RATE;
					stream->resampleFrac = stream->resampleActiveRate % PCM_AUDIO_PLAYBACK_RATE;
					stream->resampleFracAccumulated = 0;
					for (S32 j = 0; j < PCM_AUDIO_STREAM_BUFFERS; j++) {
						fillStreamingBuffer(stream, j);
					}
					stream->activeAudioBuf = 0;
					// set isPlaying to true last
					stream->isPlaying = TRUE;
				}
				success = TRUE;
				break;
			}
		}
		if (!success) {
			logmsg("No streams left to play on");
		}
		return streamId;
	}