Exemplo n.º 1
0
    Sound::Sound(const std::string& fileName) :
        _channel_count(0),
        _sample_count(0),
        _sample_rate(0)
    {
        stb_vorbis* file = stb_vorbis_open_filename(const_cast<char*>(fileName.c_str()), 0, 0);
        if (file)
        {
            stb_vorbis_info info = stb_vorbis_get_info(file);
            _channel_count = info.channels;
            _sample_rate = info.sample_rate;

            int samples = stb_vorbis_stream_length_in_samples(file) * _channel_count;
            _sample_count  = samples;
            _samples.resize(samples);

            stb_vorbis_get_samples_short_interleaved(file, _channel_count, &_samples.front(), samples);

            stb_vorbis_close(file);
        }
        else
        {
            throw std::runtime_error("Unable to open audio file");
        }
    }
Exemplo n.º 2
0
static void
punp_sound_load_stbv(Sound *sound, stb_vorbis *stream)
{
    stb_vorbis_info info = stb_vorbis_get_info(stream);
    sound->volume = PUNP_SOUND_DEFAULT_SOUND_VOLUME;
    sound->rate = info.sample_rate;
    sound->samples_count = stb_vorbis_stream_length_in_samples(stream);
    sound->samples = (i16 *)bank_push(CORE->storage, PUNP_SOUND_SAMPLES_TO_BYTES(sound->samples_count));

    {
        static i16 buffer[1024];
        i16 *it = sound->samples;
        int samples_read_per_channel;
        for (; ;) {
            int samples_read_per_channel =
                    stb_vorbis_get_samples_short_interleaved(stream, PUNP_SOUND_CHANNELS, buffer, 1024);

            if (samples_read_per_channel == 0) {
                break;
            }

            // 2 channels, 16 bits per sample.
            memcpy(it, buffer, PUNP_SOUND_SAMPLES_TO_BYTES(samples_read_per_channel));
            it += samples_read_per_channel * PUNP_SOUND_CHANNELS;
        }
            }
    stb_vorbis_close(stream);
}
Exemplo n.º 3
0
//----------------------------------------------------------------------------
void fill_buffer(void *audioBuffer, size_t size) {
//----------------------------------------------------------------------------

	u32 *dest = (u32*)audioBuffer;

	stb_vorbis_get_samples_short_interleaved(vorbisFile, 2, (short*)dest, Samples * 2);

	DSP_FlushDataCache(audioBuffer,size);

}
Exemplo n.º 4
0
std::size_t cSoundFileOgg::Read( Int16 * Data, std::size_t SamplesCount ) {
	if ( NULL != mStream && Data && SamplesCount ) {
		int Read = stb_vorbis_get_samples_short_interleaved( mStream, mChannelCount, Data, static_cast<int>( SamplesCount ) );

		std::size_t scount = Read * mChannelCount;

		return scount;
	}

	return 0;
}
Exemplo n.º 5
0
int MusicPlayer::pullAudio(AUDIO_SAMPLE_TYPE *target, int sampleCount)
	{
	memset(target, 0, sampleCount * sizeof(AUDIO_SAMPLE_TYPE));
#ifdef USE_OGG
	if(v && error==0)
		{
		int samples = stb_vorbis_get_samples_short_interleaved(v, channels, target, sampleCount);
		if(samples==0)
			{
			stb_vorbis_seek_start(v);
			stb_vorbis_get_samples_short_interleaved(v, channels, target, sampleCount);
			// error=-1;
			}
		}
#endif

#ifdef USE_MP3
	if (!error)
		{
		size_t done;
		error = mpg123_read(mh, (unsigned char *) target, sampleCount
				* sizeof(AUDIO_SAMPLE_TYPE), &done);
		// read will return MPG123_DONE eventually...

		if (error == MPG123_DONE)
			{

			mpg123_seek(mh, 0, SEEK_SET);
			error = mpg123_read(mh, (unsigned char *) target, sampleCount
					* sizeof(AUDIO_SAMPLE_TYPE), &done);
			}

		// ignore format change
		if (error == MPG123_NEW_FORMAT)
			error = MPG123_OK;

		}
#endif
	return sampleCount;
	}
Exemplo n.º 6
0
// Load OGG file into Wave structure
// NOTE: Using stb_vorbis library
static Wave LoadOGG(char *fileName)
{
    Wave wave;

    stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);

    if (oggFile == NULL)
    {
        TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
        wave.data = NULL;
    }
    else
    {
        stb_vorbis_info info = stb_vorbis_get_info(oggFile);

        wave.sampleRate = info.sample_rate;
        wave.bitsPerSample = 16;
        wave.channels = info.channels;

        TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
        TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);

        int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);

        wave.dataSize = totalSamplesLength*sizeof(short);   // Size must be in bytes

        TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);

        float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);

        TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);

        if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);

        int totalSamples = totalSeconds*info.sample_rate*info.channels;

        TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);

        wave.data = malloc(sizeof(short)*totalSamplesLength);

        int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);

        TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);

        TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);

        stb_vorbis_close(oggFile);
    }

    return wave;
}
Exemplo n.º 7
0
void test_get_samples_short_interleaved(FILE *g, char *filename)
{
   int error;
   stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL);
   if (!v) stb_fatal("Couldn't open {%s}", filename);
   show_info(v);

   for(;;) {
      int16 sbuffer[333];
      int n;
      n = stb_vorbis_get_samples_short_interleaved(v, 2, sbuffer, 333);
      if (n == 0)
         break;
      fwrite(sbuffer, 2, n*2, g);
   }
   stb_vorbis_close(v);
}
Exemplo n.º 8
0
int try_seeking(stb_vorbis *v, unsigned int pos, short *output, unsigned int num_samples)
{
   int count;
   short samples[SAMPLES_TO_TEST*2];
   assert(pos <= num_samples);

   if (!stb_vorbis_seek(v, pos)) {
      fprintf(stderr, "Seek to %u returned error from stb_vorbis\n", pos);
      return 0;
   }

   count = stb_vorbis_get_samples_short_interleaved(v, 2, samples, SAMPLES_TO_TEST*2);

   if (count > (int) (num_samples - pos)) {
      fprintf(stderr, "Seek to %u allowed decoding %d samples when only %d should have been valid.\n",
            pos, count, (int) (num_samples - pos));
      return 0;
   }

   if (count < SAMPLES_TO_TEST && count < (int) (num_samples - pos)) {
      fprintf(stderr, "Seek to %u only decoded %d samples of %d attempted when at least %d should have been valid.\n",
         pos, count, SAMPLES_TO_TEST, num_samples - pos);
      return 0;                      
   }

   if (0 != memcmp(samples, output + pos*2, count*2)) {
      int k;
      for (k=0; k < SAMPLES_TO_TEST*2; ++k) {
         if (samples[k] != output[k]) {
            fprintf(stderr, "Seek to %u produced incorrect samples starting at sample %u (short #%d in buffer).\n",
                    pos, pos + (k/2), k);
            break;
         }
      }
      assert(k != SAMPLES_TO_TEST*2);
      return 0;
   }

   return 1;
}
Exemplo n.º 9
0
ALuint AEAudioContextBufferLoad(AEAudioContext* self, const char* filename){
	ALuint buffer=0;
	alGenBuffers(1, &buffer);
	
	stb_vorbis *stream = stb_vorbis_open_filename((char*)filename, NULL, NULL);
	if(not stream) return 0;

	stb_vorbis_info info = stb_vorbis_get_info(stream);
	ALenum format;
	if(info.channels == 2) format = AL_FORMAT_STEREO16;
	else format = AL_FORMAT_MONO16;

	size_t sampleCount = stb_vorbis_stream_length_in_samples(stream) * info.channels;
	void* data = malloc(sizeof(ALushort)*sampleCount);

	stb_vorbis_get_samples_short_interleaved(stream, info.channels, data, (int)sampleCount);
	stb_vorbis_close(stream);

	alBufferData(buffer, format, data, sampleCount * sizeof(ALushort), info.sample_rate);
	free(data);
	return buffer;
}
Exemplo n.º 10
0
bool AudioStream::Stream(unsigned int buffer)
{
	ALenum format;
	if (info.channels == 1) {
		format = AL_FORMAT_MONO16;
	}
	else {
		format = AL_FORMAT_STEREO16;
	}

	int16 pcm[32768];
	int size = stb_vorbis_get_samples_short_interleaved(stream, info.channels, pcm, 32768);
	if (!size) {
		return false;
	}
	else {
		alBufferData(buffer, format, pcm, size * info.channels * sizeof(short), info.sample_rate);
		samplesLeft -= size;
		return true;
	}


}
Exemplo n.º 11
0
// Fill music buffers with new data from music stream
static bool BufferMusicStream(ALuint buffer)
{
	short pcm[MUSIC_BUFFER_SIZE];
    
	int  size = 0;              // Total size of data steamed (in bytes)
	int  streamedBytes = 0;     // Bytes of data obtained in one samples get
    
    bool active = true;         // We can get more data from stream (not finished)
    
    if (musicEnabled)
    {
        while (size < MUSIC_BUFFER_SIZE)
        {
            streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic.stream, currentMusic.channels, pcm + size, MUSIC_BUFFER_SIZE - size);
            
            if (streamedBytes > 0) size += (streamedBytes*currentMusic.channels);
            else break;
        }
        
        TraceLog(DEBUG, "Streaming music data to buffer. Bytes streamed: %i", size);
    }
    
	if (size > 0)
    {
        alBufferData(buffer, currentMusic.format, pcm, size*sizeof(short), currentMusic.sampleRate);
        
        currentMusic.totalSamplesLeft -= size;
    }
    else
    {
        active = false;
        TraceLog(WARNING, "No more data obtained from stream");
    }

	return active;
}
Exemplo n.º 12
0
bool AEAudioStreamStream(AEAudioStream* self, ALuint buffer){
	//Uncomment this to avoid VLAs
	//#define BUFFER_SIZE 4096*32
	#ifndef BUFFER_SIZE//VLAs ftw
	#define BUFFER_SIZE (self->bufferSize)
	#endif
	ALshort pcm[BUFFER_SIZE];
	int  size = 0;
	int  result = 0;
	
	while(size < BUFFER_SIZE){
		result = stb_vorbis_get_samples_short_interleaved(self->stream, self->info.channels, pcm+size, BUFFER_SIZE-size);
		if(result > 0) size += result*self->info.channels;
		else break;
	}
	
	if(size == 0) return false;
	
	alBufferData(buffer, self->format, pcm, size*sizeof(ALshort), self->info.sample_rate);
	self->totalSamplesLeft-=size;
	#undef BUFFER_SIZE
	
	return true;
}
Exemplo n.º 13
0
// stereo LRLRLR order
void mixerCallback( void* userdata, Uint8* streamData, int len )
{
	memset( streamData, len, workingSilence );
	memset( workingBuffer, 0, workingBufferSize );
	if( workingBuffer == NULL ) {
		return;
	}

	int numSamples = ( len / WORKING_CHANNELS ) / ( ( SDL_AUDIO_MASK_BITSIZE & WORKING_FORMAT ) / 8 );

#if 0
	int soundFreq = 440; // wave length
	float step = 1.0f / WORKING_RATE;
	// for testing audio output
	for( int s = 0; s < numSamples; ++s ) {
		int streamIdx = ( s * WORKING_CHANNELS );
		testTimePassed += 1.0f / WORKING_RATE;
		float v = sinf( testTimePassed * soundFreq * M_TWO_PI_F );
		workingBuffer[streamIdx] = v * 0.1f;
		workingBuffer[streamIdx+1] = v * 0.1f;
	}
#else
	// advance each playing sound
	for( EntityID id = idSet_GetFirstValidID( &playingIDSet ); id != INVALID_ENTITY_ID; id = idSet_GetNextValidID( &playingIDSet, id ) ) {
		int i = idSet_GetIndex( id );
		Sound* snd = &( playingSounds[i] );
		Sample* sample = &( samples[snd->sample] );
		
		// for right now lets assume the pitch will stay the same, when we get it working it'll just involve
		//  changing the speed at which we move through the array
		bool soundDone = false;
		float volume = snd->volume * sbSoundGroups[snd->group].volume * masterVolume;
		for( int s = 0; ( s < numSamples ) && !soundDone; ++s ) {

			int streamIdx = ( s * WORKING_CHANNELS );

			// we're assuming stereo output here
			if( sample->numChannels == 1 ) {
				float data = sample->data[(int)snd->pos] * volume;
/* left */		workingBuffer[streamIdx] += data * inverseLerp( 1.0f, 0.0f, snd->pan );
/* right */		workingBuffer[streamIdx+1] += data * inverseLerp( -1.0f, 0.0f, snd->pan );
				snd->pos += snd->pitch;
			} else {
				// if the sample is stereo then we ignore panning
				//  NOTE: Pitch change doesn't work with stereo samples yet
				workingBuffer[streamIdx] += sample->data[(int)snd->pos] * volume;
				workingBuffer[streamIdx+1] += sample->data[(int)snd->pos+1] * volume;
				snd->pos += 2.0f;
			}

			if( snd->pos >= sample->numSamples ) {
				if( sample->loops ) {
					snd->pos -= (float)sample->numSamples;
				} else {
					soundDone = true;
				}
			}
		}

		if( soundDone ) {
			idSet_ReleaseID( &playingIDSet, id ); // this doesn't invalidate the id for the loop
		}
	}

	for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) {
		if( !streamingSounds[i].playing ) continue;

		StreamingSound* stream = &( streamingSounds[i] );
		bool soundDone = false;
		float volume = stream->volume * sbSoundGroups[stream->group].volume * masterVolume;

		// if the next buffer fill would be past what we have loaded then load some more
		//  note: the SDL_AudioStreamAvailable return value is in bytes
		while( ( SDL_AudioStreamAvailable( stream->sdlStream ) < len ) && !( stream->readDone ) ) {
			int read = 0;
			int request = STREAM_READ_BUFFER_SIZE / sizeof( short );
			size_t test = ARRAY_SIZE( streamReadBuffer );
			// returns the number of samples stored per channel
			int samplesPerChannel = stb_vorbis_get_samples_short_interleaved(
				stream->access, stream->access->channels, streamReadBuffer, request );
			read = samplesPerChannel * sizeof( short );

			SDL_AudioStreamPut( stream->sdlStream, streamReadBuffer, samplesPerChannel * stream->channels * sizeof( short ) );

			// reached the end of the file, are we looping?
			if( read != request ) {
				if( stream->loops ) {
					stb_vorbis_seek_start( stream->access );
				} else {
					stream->readDone = true;
					SDL_AudioStreamFlush( stream->sdlStream );
				}
			}
		}

		// read data from the audio stream until there is no more left or the end of the buffer to fill
		int bytesToStream = numSamples * stream->channels * sizeof( sbStreamWorkingBuffer[0] );
		sb_Reserve( sbStreamWorkingBuffer, (size_t)bytesToStream );
		int gotten = SDL_AudioStreamGet( stream->sdlStream, sbStreamWorkingBuffer, bytesToStream );
		if( gotten < 0 ) {
			llog( LOG_ERROR, "Error reading from sdlStream: %s", SDL_GetError( ) );
			stream->playing = false;
			continue;
		} else if( gotten == 0 ) {
			// end of stream
			stream->playing = false;
		}

		int samplesGotten = gotten / ( stream->channels * sizeof( sbStreamWorkingBuffer[0] ) );
		for( int s = 0; s < samplesGotten; ++s ) {
			// then just mix those samples
			int streamIdx = ( s * WORKING_CHANNELS );
			int workingIdx = ( s * stream->channels );
			
			// we're assuming stereo output here
			if( stream->access->channels == 1 ) {
				float data = sbStreamWorkingBuffer[workingIdx] * volume;
				workingBuffer[streamIdx] += data * inverseLerp( 1.0f, 0.0f, stream->pan );		// left
				workingBuffer[streamIdx+1] += data * inverseLerp( -1.0f, 0.0f, stream->pan );   // right
			} else {
				// if the sample is stereo then we ignore panning
				workingBuffer[streamIdx] += sbStreamWorkingBuffer[workingIdx] * volume;
				workingBuffer[streamIdx+1] += sbStreamWorkingBuffer[workingIdx + 1] * volume;
			}
		}
	}
#endif

	memcpy( streamData, workingBuffer, len );
}
Exemplo n.º 14
0
Arquivo: buffer.c Projeto: SIEGE/siege
SGAudioBuffer* SG_CALL sgAudioBufferCreateStream(SGStream* stream, SGbool delstream)
{
    if(!stream || !stream->read || !stream->seek || !stream->tell) return NULL;

    SGAudioBuffer* buffer = malloc(sizeof(SGAudioBuffer));
    if(!buffer) goto error;

    buffer->stream = stream;
    buffer->del = delstream;

    buffer->handle = malloc(sizeof(ALuint));
    if(!buffer->handle) goto error;
    alGenBuffers(1, buffer->handle);

    SGuint channels;
    SGuint format;
    SGuint frequency;
    void* data = NULL;
    SGuint datalen;
    SGuint nsamples;

    void* buf = NULL;
    int error = 0;
    stb_vorbis* stb = NULL;
    stb_vorbis_info info;

    SGlong pos = sgStreamTell(stream);
    SGlong size = sgStreamTellSize(stream);
    size -= pos;
    if(pos < 0 || size < 0)
        goto lderr;

    buf = malloc(size);
    if(sgStreamRead(stream, buf, 1, size) != size)
        goto lderr;

    stb = stb_vorbis_open_memory(buf, size, &error, NULL);
    if(!stb) goto lderr;

    info = stb_vorbis_get_info(stb);
    channels = info.channels;
    frequency = info.sample_rate;
    format = SG_AUDIO_FORMAT_S16; // or SG_AUDIO_FORMAT_F

    nsamples = stb_vorbis_stream_length_in_samples(stb);
    datalen = 2 * nsamples * channels;
    data = malloc(datalen);

    datalen = 2 * stb_vorbis_get_samples_short_interleaved(stb, info.channels, data, datalen / 2);

    sgAudioBufferSetData(buffer, channels, format, frequency, data, datalen);
    free(data);

end:
    if(stb)
        stb_vorbis_close(stb);
    if(buf)
        free(buf);
    return buffer;
lderr:
    if(buffer)
    {
        free(buffer);
        buffer = NULL;
        goto end;
    }
error:
    if(buffer)
        free(buffer);
    return NULL;
}
quint64 nVorbisStream::read(void *data, unsigned long frames)
{
    return stb_vorbis_get_samples_short_interleaved(_vorbis, _channels, (short*) data, frames * _channels );

}
Exemplo n.º 16
0
AudioBuffer::AudioBuffer(const String &filename) {
	if (filename.ExtractExt() == "wav") {
		m_alBuffer = 0;
		File * file = new File(filename, FILE_READ);

		int32 chunkId = file->ReadInt();
		int32 riffChunkSize = file->ReadInt();
		int32 format = file->ReadInt();
		int32 subChunkId = file->ReadInt();
		int32 fmtChunkSize = file->ReadInt();
		int16 audioFormat = file->ReadInt16();
		int16 channels = file->ReadInt16();
		int32 sampleRate = file->ReadInt();
		int32 byteRate = file->ReadInt();
		int16 blockAlign = file->ReadInt16();
		int16 bitsPerSample = file->ReadInt16();
		if (fmtChunkSize > 16) {
			int16 extraParamsSize = file->ReadInt16();
			file->Seek(file->Pos() + extraParamsSize);
		}

		char text[5] = "";
		file->ReadBytes(text, 4);
		while (String(text) != "data" && !file->Eof()) {
			file->ReadBytes(text, 4);
			if (String(text) == "data")
				break;
			file->Seek(file->Pos() + 4);
		}

		int32 dataSize = file->ReadInt();
		uint32 * data = (uint32 *)malloc(dataSize);
		file->ReadBytes(data, dataSize);

		ALenum bufferFormat;
		if (bitsPerSample == 8) {
			if (channels == 1)
				bufferFormat = AL_FORMAT_MONO8;
			else
				bufferFormat = AL_FORMAT_STEREO8;
		}
		else {
			if (channels == 1)
				bufferFormat = AL_FORMAT_MONO16;
			else
				bufferFormat = AL_FORMAT_STEREO16;
		}

		alGenBuffers(1, &m_alBuffer);
		alBufferData(m_alBuffer, bufferFormat, data, dataSize, sampleRate);
		delete file;
		free(data);
	} else if (filename.ExtractExt() == "ogg") {
		stb_vorbis * file = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr);

		if (file) {
			stb_vorbis_info info = stb_vorbis_get_info(file);
			uint32 size = stb_vorbis_stream_length_in_samples(file) * info.channels;
			int16 * buffer = (int16 *)malloc(size * sizeof(int16));
			stb_vorbis_get_samples_short_interleaved(file, info.channels, buffer, size);
			alGenBuffers(1, &m_alBuffer);
			ALenum bufferFormat;
			if (info.channels == 1)
				bufferFormat = AL_FORMAT_MONO16;
			else
				bufferFormat = AL_FORMAT_STEREO16;
			alBufferData(m_alBuffer, bufferFormat, buffer, size, info.sample_rate);
			stb_vorbis_close(file);
			free(buffer);
		}
	}
}
Exemplo n.º 17
0
const i32 audio_updateAndPlay(MemoryArena_ *arena, AudioManager *audioManager,
                              AudioRenderer *audioRenderer)
{
	AudioVorbis *audio = audioRenderer->audio;
	if (!audio) return 0;

	u32 alSourceId = getSourceId(audioManager, audioRenderer);
	if (alIsSource(alSourceId) == AL_FALSE)
	{
		DEBUG_LOG("audio_updateAndPlay(): Update failed on invalid source id");
		return -1;
	}

	ALint audioState;
	alGetSourcei(alSourceId, AL_SOURCE_STATE, &audioState);
	AL_CHECK_ERROR();
	if (audioState == AL_STOPPED || audioState == AL_INITIAL)
	{
		if (audioState == AL_STOPPED)
		{
			if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE)
				audioRenderer->numPlays--;

			if (audioRenderer->numPlays == AUDIO_REPEAT_INFINITE ||
			    audioRenderer->numPlays > 0)
			{
				// TODO(doyle): Delete and recreate fixes clicking when reusing
				// buffers
				alDeleteBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				                audioRenderer->bufferId);
				AL_CHECK_ERROR();

				alGenBuffers(ARRAY_COUNT(audioRenderer->bufferId),
				             audioRenderer->bufferId);
				AL_CHECK_ERROR();
			}
			else
			{
				i32 result =
				    rendererRelease(arena, audioManager, audioRenderer);
				return result;
			}
		}

		if (audioRenderer->isStreaming)
		{
			stb_vorbis_seek_start(audio->file);
			for (i32 i = 0; i < ARRAY_COUNT(audioRenderer->bufferId); i++)
			{
				i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
				stb_vorbis_get_samples_short_interleaved(
				    audio->file, audio->info.channels, audioChunk,
				    AUDIO_CHUNK_SIZE_);

				alBufferData(audioRenderer->bufferId[i], audioRenderer->format,
				             audioChunk, AUDIO_CHUNK_SIZE_ * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
			}

			alSourceQueueBuffers(alSourceId,
			                     ARRAY_COUNT(audioRenderer->bufferId),
			                     audioRenderer->bufferId);
		}
		else
		{
			alSourceQueueBuffers(alSourceId, 1, audioRenderer->bufferId);
		}

		AL_CHECK_ERROR();
		alSourcePlay(alSourceId);
		AL_CHECK_ERROR();
	}
	else if (audioState == AL_PLAYING)
	{
		ALint numProcessedBuffers;
		alGetSourcei(alSourceId, AL_BUFFERS_PROCESSED,
		             &numProcessedBuffers);
		AL_CHECK_ERROR();
		if (numProcessedBuffers > 0)
		{
			// TODO(doyle): Possibly wrong, we should pass in all processed buffers?
			ALint numBuffersToUnqueue = 1;
			ALuint emptyBufferId;
			alSourceUnqueueBuffers(alSourceId, numBuffersToUnqueue,
			                       &emptyBufferId);
			AL_CHECK_ERROR();

			i16 audioChunk[AUDIO_CHUNK_SIZE_] = {0};
			i32 sampleCount = stb_vorbis_get_samples_short_interleaved(
			    audio->file, audio->info.channels, audioChunk,
			    AUDIO_CHUNK_SIZE_);

			/* There are still samples to play */
			if (sampleCount > 0)
			{
				alBufferData(emptyBufferId, audioRenderer->format, audioChunk,
				             sampleCount * audio->info.channels * sizeof(i16),
				             audio->info.sample_rate);
				AL_CHECK_ERROR();
				alSourceQueueBuffers(alSourceId, 1, &emptyBufferId);
				AL_CHECK_ERROR();
			}
		}
	}

	return 0;
}
Exemplo n.º 18
0
AudioBuffer::AudioBuffer(const String & filename):alBuffer(0)
{

	if (filename.ExtractExt() == "wav") {

		alGenBuffers(1, &alBuffer);
		File file(filename, FILE_READ);
		file.Seek(16);
		uint32 fmtChunkSize;
		file.ReadBytes(&fmtChunkSize, 4);
		uint16 audioFormat;
		file.ReadBytes(&audioFormat, 2);
		uint16 channels;
		file.ReadBytes(&channels, 2);
		file.Seek(24);
		uint32 sampleRate;
		file.ReadBytes(&sampleRate, 4);
		file.Seek(34);
		uint16 bitsPerSample;
		file.ReadBytes(&bitsPerSample, 2);
		uint16 extraParamSize;
		if (fmtChunkSize != 16) {
			file.ReadBytes(&extraParamSize, 2);
			file.Seek(38 + extraParamSize);
		}
		char texto[5];
		texto[4] = '\0';

		while (String(texto) != "data") {

			file.ReadBytes(texto, 4);
		}

		uint32 dataSize;
		uint32* data;
		file.ReadBytes(&dataSize, 4);
		data = (uint32*)malloc(dataSize);
		file.ReadBytes(data, dataSize);

		ALenum format;

		if (bitsPerSample == 8) {
			if (channels == 1) {
				format = AL_FORMAT_MONO8;
			}
			else {
				format = AL_FORMAT_STEREO8;
			}
		}

		if (bitsPerSample == 16) {
			if (channels == 1) {
				format = AL_FORMAT_MONO16;
			}
			else {
				format = AL_FORMAT_STEREO16;
			}
		}

		alBufferData(alBuffer, format, data, dataSize, sampleRate);
		free(data);
	}
	else if (filename.ExtractExt() == "ogg") {
		stb_vorbis* stb_vorbis;

		stb_vorbis = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr);
		if (stb_vorbis == nullptr) return;

		stb_vorbis_info info = stb_vorbis_get_info(stb_vorbis);
		uint32 dataSize = stb_vorbis_stream_length_in_samples(stb_vorbis) *  info.channels;
		int16* buffer = (int16*)malloc(dataSize  * sizeof(uint16));
		stb_vorbis_get_samples_short_interleaved(stb_vorbis, info.channels,(short *) buffer, dataSize);
		alGenBuffers(1, &alBuffer);
		ALenum format;
		if (info.channels == 1) {
			format = AL_FORMAT_MONO16;
		}
		else {
			format = AL_FORMAT_STEREO16;
		}
		alBufferData(alBuffer, format, buffer, dataSize * sizeof(int16), info.sample_rate);
		free(buffer);
		stb_vorbis_close(stb_vorbis);
	}




}
Exemplo n.º 19
0
sInt sOGGDecoder::Render(sS16 *stream,sInt samples) 
{
  return stb_vorbis_get_samples_short_interleaved(dec,2,stream,samples*2);
}
Exemplo n.º 20
0
int main()
{
   // Initialize services
   srvInit();
   aptInit();
   hidInit(NULL);
   ptmInit();
   gfxInitDefault();
   // consoleInit(GFX_TOP, NULL);
   csndInit();
   // fsInit();
   // sdmcInit();

   chdir("sdmc:/");

   void *device = gfxCreateDevice(240, 320);
   gfxMakeCurrent(device);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);

   glTranslatef(0.5f, 0.5f, 0.0f);
   glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
   glTranslatef(-0.5f, -0.5f, 0.0f);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glGenTextures(1, &play_button);
   glGenTextures(1, &pause_button);
   glGenTextures(1, &loop_button);
   glGenTextures(1, &loop_disable_button);
   glGenTextures(1, &power_icon);

   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

   int x, y, n;
   u8* image_data = stbi_load_from_memory(play_3_png, play_3_png_size, &x, &y, &n, 4);
   glBindTexture(GL_TEXTURE_2D, play_button);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
   stbi_image_free(image_data);

   image_data = stbi_load_from_memory(pause_2_png, pause_2_png_size, &x, &y, &n, 4);
   glBindTexture(GL_TEXTURE_2D, pause_button);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
   stbi_image_free(image_data);

   image_data = stbi_load_from_memory(loop_png, loop_png_size, &x, &y, &n, 4);
   glBindTexture(GL_TEXTURE_2D, loop_button);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
   stbi_image_free(image_data);

   image_data = stbi_load_from_memory(loop_disable_png, loop_disable_png_size, &x, &y, &n, 4);
   glBindTexture(GL_TEXTURE_2D, loop_disable_button);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
   stbi_image_free(image_data);

   image_data = stbi_load_from_memory(power_png, power_png_size, &x, &y, &n, 4);
   glBindTexture(GL_TEXTURE_2D, power_icon);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
   stbi_image_free(image_data);

   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   void *top_device = gfxCreateDevice(240, 400);
   gfxMakeCurrent(top_device);
   initfont_goth();
   initfont_anita();
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);

   glTranslatef(0.5f, 0.5f, 0.0f);
   glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
   glTranslatef(-0.5f, -0.5f, 0.0f);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable(GL_BLEND);
   glEnable(GL_TEXTURE_2D);

   int frames = 0;
   int channel = 0x8;


   while (aptMainLoop())
   {
      gspWaitForVBlank();
      hidScanInput();
      gfxMakeCurrent(top_device);
      glClear(GL_COLOR_BUFFER_BIT);
      glLoadIdentity();
      glScalef(1.0/400.0, 1.0/240.0, 1.0);
      state_man();
      gfxFlush(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL));
      u8 plevel;
      u8 charge;
      PTMU_GetBatteryLevel(NULL, &plevel);
      PTMU_GetBatteryChargeState(NULL, &charge);
      if (plevel != power_level) {
         power_level = plevel;
         // draw_ui = true;
      }
      if (charge != is_charging) {
         is_charging = charge;
         //draw_ui = true;
      }

      gfxMakeCurrent(device);
      u8* fb = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
      render();
      gfxFlush(fb);
      // Your code goes here

      u32 kDown = hidKeysDown();
      if (kDown & KEY_START)
         break; // break in order to return to hbmenu

      // Flush and swap framebuffers
      if (audiobuf && !paused) {
         if(frames >= 50) {
            frames = 0;
            int n = 0;
            if (decode_mode == AUDIO_MODE_VORBIS) {
               n = stb_vorbis_get_samples_short_interleaved(v, 2, audiobuf, Samples * 2);
            } else {
               while (audiobuf_index < Samples * 2) {
                  n = FLAC__stream_decoder_process_single(FLAC_decoder);
                  if (FLAC__stream_decoder_get_state(FLAC_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) break;
               }
               audiobuf_index = 0;
            }

            if(n == 0) {
               if (decode_mode == AUDIO_MODE_VORBIS) {
                  stb_vorbis_close(v);
               } else {
                  FLAC__stream_decoder_delete(FLAC_decoder);
               }
               linearFree(audiobuf);
               audiobuf = NULL;
               v = NULL;
               FLAC_decoder = NULL;
               if (loop_flag) play_file_from_filename(currently_playing);
            }

            GSPGPU_FlushDataCache(NULL, (u8*)audiobuf, audiobuf_size);
            if (channel == 0x8) channel = 0x6;
            if (channel == 0x6) channel = 0x8;
            csndPlaySound(SOUND_CHANNEL(channel), SOUND_ONE_SHOT | SOUND_LINEAR_INTERP | SOUND_FORMAT_16BIT, Samples * 2, 10.0, 0.0, (u32*)audiobuf, (u32*)audiobuf, audiobuf_size);

         }
         frames++;
      }

      gfxFlushBuffers();
      gfxSwapBuffersGpu();
   }

   // Exit services
   if (FLAC_decoder) {
      FLAC__stream_decoder_delete(FLAC_decoder);
   }
   csndExit();
   gfxExit();
   ptmExit();
   hidExit();
   aptExit();
   srvExit();
   return 0;
}