Beispiel #1
0
void MusicPlayer::play(const char *filename)
	{
#ifdef USE_OGG
	stb_vorbis_close(v);
        stb_vorbis_alloc t;
	t.alloc_buffer=this->buf;
	t.alloc_buffer_length_in_bytes=STB_BUFSIZE;
	// stb_vorbis has char* pointer even though it is not really writing to buffer
	v = stb_vorbis_open_filename((char *)filename, &error, &t);
#endif

#ifdef USE_MP3
	mpg123_close(mh);
	error = mpg123_open(mh, filename);

	if (!error)
		{
		error = mpg123_getformat(mh, &rate, &channels, &encoding);

		rate = AUDIO_FREQUENCY;
		channels = 2;

		mpg123_format_none(mh);
		mpg123_format(mh, rate, channels, encoding);

		}
#endif
	}
Beispiel #2
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");
        }
    }
Beispiel #3
0
void play_file_from_filename(const std::string name) {
   currently_playing = std::string(name);
   if (audiobuf) linearFree(audiobuf);

   if (name.rfind(".flac") != std::string::npos) {
      if (!FLAC_decoder) {
         FLAC_decoder = FLAC__stream_decoder_new();
         FLAC__stream_decoder_set_md5_checking(FLAC_decoder, true);
      }
      audiobuf_index = 0;
      decode_mode = AUDIO_MODE_FLAC;
      FLAC__StreamDecoderInitStatus init_status = FLAC__stream_decoder_init_file(FLAC_decoder, name.c_str(), FLAC_write_callback, FLAC_metadata_callback, FLAC_error_callback, NULL);
      if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
         printf("ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
      }
      FLAC__stream_decoder_process_until_end_of_metadata(FLAC_decoder);
   } else {
      decode_mode = AUDIO_MODE_VORBIS;
      v = stb_vorbis_open_filename(name.c_str(), &error, NULL);
      info = stb_vorbis_get_info(v);
      Samples = info.sample_rate;
      audiobuf_size = Samples * sizeof(s16) * 2;
      audiobuf = (s16*)linearAlloc(audiobuf_size);
   }
   paused = false;
}
Beispiel #4
0
// Start music playing (open stream)
void PlayMusicStream(char *fileName)
{
    if (strcmp(GetExtension(fileName),"ogg") == 0)
    {
        // Stop current music, clean buffers, unload current stream
        StopMusicStream();

        // Open audio stream
        currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL);

        if (currentMusic.stream == NULL)
        {
            TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
        }
        else
        {
            // Get file info
            stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream);

            currentMusic.channels = info.channels;
            currentMusic.sampleRate = info.sample_rate;

            TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
            TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
            TraceLog(INFO, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);

            if (info.channels == 2) currentMusic.format = AL_FORMAT_STEREO16;
            else currentMusic.format = AL_FORMAT_MONO16;

            currentMusic.loop = true;                  // We loop by default
            musicEnabled = true;

            // Create an audio source
            alGenSources(1, &currentMusic.source);     // Generate pointer to audio source

            alSourcef(currentMusic.source, AL_PITCH, 1);
            alSourcef(currentMusic.source, AL_GAIN, 1);
            alSource3f(currentMusic.source, AL_POSITION, 0, 0, 0);
            alSource3f(currentMusic.source, AL_VELOCITY, 0, 0, 0);
            //alSourcei(currentMusic.source, AL_LOOPING, AL_TRUE);     // ERROR: Buffers do not queue!

            // Generate two OpenAL buffers
            alGenBuffers(2, currentMusic.buffers);

            // Fill buffers with music...
            BufferMusicStream(currentMusic.buffers[0]);
            BufferMusicStream(currentMusic.buffers[1]);

            // Queue buffers and start playing
            alSourceQueueBuffers(currentMusic.source, 2, currentMusic.buffers);
            alSourcePlay(currentMusic.source);

            // NOTE: Regularly, we must check if a buffer has been processed and refill it: MusicStreamUpdate()

            currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
        }
    }
    else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
}
void LoadTestChannel(ShadertoyTestResource *channel_data, ShadertoyState *state, ShadertoyInputs *inputs, ShadertoyOutputs *outputs, ShadertoyPass pass, int channel_id) {

    ImageFile *image = &image_files[channel_id][pass];
    memset(image->filepath, 0, sizeof(image->filepath));

    switch (channel_data->type) {
    case SHADERTOY_RESOURCE_TEXTURE: {
        GetFilePath(image->filepath, channel_data->filename[0]);
        LoadTexture(state, image->filepath, pass, channel_id);
        break;
    }
    case SHADERTOY_RESOURCE_CUBE_MAP: {
        char *cubemap_paths[6];
        for (int j = 0; j < 6; ++j) {
            cubemap_paths[j] = new char[1024];
            GetFilePath(cubemap_paths[j], channel_data->filename[j]);
            if (j == 0) {
                strcpy(image->filepath, cubemap_paths[j]);
            }
        }
        LoadTexture(state, cubemap_paths, pass, channel_id);
        for (int j = 0; j < 6; ++j) {
            delete[] cubemap_paths[j];
        }
        break;
    }
    case SHADERTOY_RESOURCE_MUSIC: {
        AudioFile *file = &audio_files[channel_id];
        memset(file->filepath, 0, sizeof(file->filepath));
        GetFilePath(file->filepath, channel_data->filename[0]);

        int ogg_error;
        stb_vorbis *ogg_data = stb_vorbis_open_filename(file->filepath, &ogg_error, NULL);
        file->channels = ogg_data->channels;
        file->samples_count = stb_vorbis_stream_length_in_samples(ogg_data) * ogg_data->channels;
        file->samples = (float*)malloc(sizeof(float) * file->samples_count);
        stb_vorbis_get_samples_float_interleaved(ogg_data, ogg_data->channels, file->samples, file->samples_count);

        audio_data[channel_id] = { &inputs->audio_played_samples[channel_id], &file->samples, (int)ogg_data->sample_rate, ogg_data->channels, file->samples_count / ogg_data->channels };
        ShadertoyLoadAudio(state, audio_data + channel_id, SHADERTOY_IMAGE_PASS, channel_id);

        outputs->music_data_param[channel_id] = init_audio_output(ogg_data->channels, ogg_data->sample_rate, 32, file->samples_count * sizeof(float));
        stb_vorbis_close(ogg_data);

        break;
    }
    case SHADERTOY_RESOURCE_MICROPHONE: {
        // 512 * sizeof(float) == FFT sampling data, so should be fine to use
        inputs->micro_data_param = init_audio_input(2, 44100, 32, 2048 * sizeof(float));
        break;
    }
    case SHADERTOY_RESOURCE_KEYBOARD:
    case SHADERTOY_RESOURCE_NONE:
        break;
    }
}
Beispiel #6
0
void
sound_load(Sound *sound, const char *path)
{
    int error = 0;
    stb_vorbis *stream;

    memset(sound, 0, sizeof(Sound));
    stream = stb_vorbis_open_filename(path, &error, 0);
    ASSERT(!error && stream);

    punp_sound_load_stbv(sound, stream);
}
void test_get_frame_short_interleaved(FILE *g, char *filename)
{
   short sbuffer[8000];
   int n, error;
   stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL);
   if (!v) stb_fatal("Couldn't open {%s}", filename);
   show_info(v);

   while (0 != (n=stb_vorbis_get_frame_short_interleaved(v, 2, sbuffer, 8000))) {
      fwrite(sbuffer, 2, n*2, g);
   }
   stb_vorbis_close(v);
}
Beispiel #8
0
bool cSoundFileOgg::IsFileSupported( const std::string& Filename, bool Read ) {
	if ( Read ) {
		// Open the vorbis stream
		stb_vorbis* Stream = stb_vorbis_open_filename( const_cast<char*>( Filename.c_str() ), NULL, NULL );

		if ( NULL != Stream ) {
			stb_vorbis_close( Stream );
			return true;
		} else
			return false;
	} else // No support for writing ogg files yet...
		return false;
}
Beispiel #9
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;
}
Beispiel #10
0
AudioStream::AudioStream(const String & filename, AudioSource * source)
{

	buffers[0] = buffers[1] = 0;
	AudioStream::source = source;
	stream = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr);
	if (!stream) return;
	info = stb_vorbis_get_info(stream);
	samplesLeft = stb_vorbis_stream_length_in_samples(stream) * info.channels;
	alGenBuffers(2, buffers);
	Stream(buffers[0]);
	Stream(buffers[1]);
	alSourceQueueBuffers(AudioStream::source->GetID(), 2, buffers);
	streams.Add(this);
}
Beispiel #11
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);
}
Beispiel #12
0
bool AEAudioStreamOpen(AEAudioStream* self, const char* filename){
	self->stream = stb_vorbis_open_filename((char*)filename, NULL, NULL);
	if(not self->stream) return false;
	// Get file info
	self->info = stb_vorbis_get_info(self->stream);
	if(self->info.channels == 2) self->format = AL_FORMAT_STEREO16;
	else self->format = AL_FORMAT_MONO16;
	
	if(not AEAudioStreamStream(self, self->buffers[0])) return false;
	if(not AEAudioStreamStream(self, self->buffers[1])) return false;
	alSourceQueueBuffers(self->source, 2, self->buffers);
	alSourcePlay(self->source);
	
	self->totalSamplesLeft=stb_vorbis_stream_length_in_samples(self->stream) * self->info.channels;
	
	return true;
}
Beispiel #13
0
bool cSoundFileOgg::OpenRead( const std::string& Filename, std::size_t& SamplesCount, unsigned int& ChannelCount, unsigned int& SampleRate ) {
	// Close the file if already opened
	if ( NULL != mStream )
		stb_vorbis_close( mStream );

	// Open the vorbis stream
	mStream = stb_vorbis_open_filename( const_cast<char*>( Filename.c_str() ), NULL, NULL );

	if ( NULL == mStream ) {
		eePRINTL( "Failed to read sound file %s (cannot open the file)", Filename.c_str() );
		return false;
	}

	// Get the music parameters
	stb_vorbis_info Infos = stb_vorbis_get_info( mStream );
	ChannelCount	= mChannelCount = Infos.channels;
	SampleRate		= Infos.sample_rate;
	SamplesCount	= static_cast<std::size_t>( stb_vorbis_stream_length_in_samples( mStream ) * ChannelCount );

	return true;
}
Beispiel #14
0
void test_get_frame_float(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(;;) {
      int n;
      float *left, *right;
      float **outputs;
      int num_c;
      n = stb_vorbis_get_frame_float(v, &num_c, &outputs);
      if (n == 0)
         break;
      left = outputs[0];
      right = outputs[num_c > 1];
      write_floats(g, n, left, right);
   }
   stb_vorbis_close(v);
}
Beispiel #15
0
    void MusicOGG::play(bool loop)
    {
        if (m_isPlaying) return;
        m_loop = loop;

        for (auto pBuffer : m_buffers) delete pBuffer;
        m_buffers.clear();
        m_bufferCount = 0;

        m_pStream = stb_vorbis_open_filename((char*)m_filename.c_str(), NULL, NULL);
        if (!m_pStream) return;

        m_info = stb_vorbis_get_info(m_pStream);
        m_sampleCount = stb_vorbis_stream_length_in_samples(m_pStream);

        m_isPlaying = true;
        m_paused = false;
        m_samplingT = 0.0f;

        // We will buffer 5 seconds
        m_engineChannelCount = m_pStream->channels;
        m_bufferMax = oAudioEngine->getSampleRate() * m_engineChannelCount;
        for (int i = 0; i < MUSIC_BUFFER_COUNT; ++i)
        {
            auto pBuffer = new Buffer();
            pBuffer->data.assign(m_bufferMax, 0.0f);
            m_buffers.push_back(pBuffer);
        }
        m_bufferCount = 0;

        if (m_thread.joinable()) m_thread.join();
        m_thread = std::thread(std::bind(&MusicOGG::run, this));

        m_musicSampleRate = (int)m_pStream->sample_rate;
        m_musicChannelCount = (int)m_pStream->channels;
        m_pSamplings = new float[4 * m_pStream->channels];
        memset(m_pSamplings, 0, sizeof(float) * 4 * m_pStream->channels);

        oAudioEngine->addInstance(OThis);
    }
Beispiel #16
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;
}
Beispiel #17
0
//***** Streaming
int snd_LoadStreaming( const char* fileName, bool loops, unsigned int group )
{
	assert( group >= 0 );
	assert( group < sb_Count( sbSoundGroups ) );

	int newIdx = -1;
	for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) {
		if( streamingSounds[i].access == NULL ) {
			newIdx = i;
			break;
		}
	}

	if( newIdx < 0 ) {
		llog( LOG_ERROR, "Unable to find empty slot for streaming sound %s", fileName );
		return -1;
	}

	int error;
	streamingSounds[newIdx].access = stb_vorbis_open_filename( fileName, &error, NULL );
	if( streamingSounds[newIdx].access == NULL ) {
		llog( LOG_ERROR, "Unable to acquire a handle to streaming sound %s", fileName );
		return -1;
	}

	streamingSounds[newIdx].playing = false;
	streamingSounds[newIdx].loops = loops;
	streamingSounds[newIdx].group = group;

	streamingSounds[newIdx].channels = (Uint8)( streamingSounds[newIdx].access->channels );
	if( streamingSounds[newIdx].channels > 2 ) {
		streamingSounds[newIdx].channels = 2;
	}

	return newIdx;
}
Beispiel #18
0
			OGGStream(String file, bool _loop)
			{
				loop = _loop;
				finished = true;
				valid = false;

				std::string name = ToStdString(file);

				//cout << "Load OGG " << name << endl;

				//OGG file
				int error = 0;
				ogg = stb_vorbis_open_filename(&name[0], &error, NULL);
				if (!ogg) {cout << " VORBIS FAIL" << endl; return;}
				info = stb_vorbis_get_info(ogg);

				//Info
				output.channels = info.channels;
				output.rate = info.sample_rate;

				//Woot!
				valid = true;
				finished = false;
			}
Beispiel #19
0
int main(int argc, char **argv)
{
   int num_chan, samprate;
   int i, j, test, phase;
   short *output;

   if (argc == 1) {
      fprintf(stderr, "Usage: vorbseek {vorbisfile} [{vorbisfile]*]\n");
      fprintf(stderr, "Tests various seek offsets to make sure they're sample exact.\n");
      return 0;
   }

   #if 0
   {
      // check that outofmem occurs correctly
      stb_vorbis_alloc va;
      va.alloc_buffer = malloc(1024*1024);
      for (i=0; i < 1024*1024; i += 10) {
         int error=0;
         stb_vorbis *v;
         va.alloc_buffer_length_in_bytes = i;
         v = stb_vorbis_open_filename(argv[1], &error, &va);
         if (v != NULL)
            break;
         printf("Error %d at %d\n", error, i);
      }
   }
   #endif

   for (j=1; j < argc; ++j) {
      unsigned int successes=0, attempts = 0;
      unsigned int num_samples = stb_vorbis_decode_filename(argv[j], &num_chan, &samprate, &output);

      break;

      if (num_samples == 0xffffffff) {
         fprintf(stderr, "Error: couldn't open file or not vorbis file: %s\n", argv[j]);
         goto fail;
      }

      if (num_chan != 2) {
         fprintf(stderr, "vorbseek testing only works with files with 2 channels, %s has %d\n", argv[j], num_chan);
         goto fail;
      }

      for (test=0; test < 5; ++test) {
         int error;
         stb_vorbis *v = stb_vorbis_open_filename(argv[j], &error, NULL);
         if (v == NULL) {
            fprintf(stderr, "Couldn't re-open %s for test #%d\n", argv[j], test);
            goto fail;
         }
         for (phase=0; phase < 3; ++phase) {
            unsigned int base = phase == 0 ? 0 : phase == 1 ? num_samples - test_count[test]*test_spacing[test] : num_samples/3;
            for (i=0; i < test_count[test]; ++i) {
               unsigned int pos = base + i*test_spacing[test];
               if (pos > num_samples) // this also catches underflows
                  continue;
               successes += try_seeking(v, pos, output, num_samples);
               attempts += 1;
            }
         }
         stb_vorbis_close(v);
      }
      printf("%d of %d seeks failed in %s (%d samples)\n", attempts-successes, attempts, argv[j], num_samples);
      free(output);
   }
   return 0;
  fail:
   return 1;
}
Beispiel #20
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);
	}




}
Beispiel #21
0
//----------------------------------------------------------------------------
int main(int argc, char **argv) {
//----------------------------------------------------------------------------

	PrintConsole topScreen;
	ndspWaveBuf waveBuf[2];

	gfxInitDefault();

	consoleInit(GFX_TOP, &topScreen);

	consoleSelect(&topScreen);

	printf("libctru streaming audio\n");
	
	
	
	stb_vorbis_info info;
	int error;


      vorbisFile = stb_vorbis_open_filename("/mau5.ogg", &error, NULL);
      info = stb_vorbis_get_info(vorbisFile);
      Samples = info.sample_rate;
   
	

	u32 *audioBuffer = (u32*)linearAlloc(Samples*sizeof(s16)*2);

	bool fillBlock = false;

	ndspInit();

	ndspSetOutputMode(NDSP_OUTPUT_STEREO);

	ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
	ndspChnSetRate(0, Samples);
	ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16);

	float mix[12];
	memset(mix, 0, sizeof(mix));
	mix[0] = 1.0;
	mix[1] = 1.0;
	ndspChnSetMix(0, mix);

	int note = 4;

	memset(waveBuf,0,sizeof(waveBuf));
	waveBuf[0].data_vaddr = &audioBuffer[0];
	waveBuf[0].nsamples = Samples;
	waveBuf[1].data_vaddr = &audioBuffer[Samples];
	waveBuf[1].nsamples = Samples;

	ndspChnWaveBufAdd(0, &waveBuf[0]);
	ndspChnWaveBufAdd(0, &waveBuf[1]);

	printf("Press up/down to change tone\n");

	
	
	
	
	
	
	while(aptMainLoop()) {

		gfxSwapBuffers();
		gfxFlushBuffers();
		gspWaitForVBlank();

		hidScanInput();
		u32 kDown = hidKeysDown();

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


		if (waveBuf[fillBlock].status == NDSP_WBUF_DONE) {

			fill_buffer(waveBuf[fillBlock].data_pcm16, waveBuf[fillBlock].nsamples);

			ndspChnWaveBufAdd(0, &waveBuf[fillBlock]);

			fillBlock = !fillBlock;
		}
	}

	ndspExit();

	linearFree(audioBuffer);

	gfxExit();
	return 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);
		}
	}
}