Playing .oggVorbis Format


#1

I converted some wav files to the oggVorbis format in hopes to load less into ram at runtime with the sampler.

[code]for(int s = 0; s < 66; s++)
{
BitArray samplerNotes;

		OggVorbisAudioFormat oggFormat;
		AudioFormatReader* audioReader;

		int i;
		for (i = sampleInfo[s].LoKey - 1; i < sampleInfo[s].HiKey; ++i)
		{
			samplerNotes.setBit (i);
		}

		audioReader = oggFormat.createReaderFor(new MemoryInputStream (sampleInfo[s].SoundSource,sampleInfo[s].SoundSize,false),true);

		synth.addSound (new SamplerSound (T("demo sound"),
                                      *audioReader,
                                      samplerNotes,
									  sampleInfo[s].RootKey- 1,   // root midi note zero based
                                      0.003,  // attack time
                                      7.5,  // release time
                                      10.0  // maximum sample length
                                      ));

		delete audioReader;
	}[/code]

But when I looked at the task manager it showed 120MB loaded in to my app which is exactly how big the files were when in .wav format.

Does the AudioFormatReader convert the files back to .wav data. Is there no way to actually play pure .ogg format?


#2

The SamplerSound class doesn’t support disk streaming, so it needs to load the entire file into RAM. The AudioFormatReader itself does allow you to stream data without decoding the entire file, but you’d have to come up with a class of your own that streams (which isn’t trivial, as I understand it).


#3

I don’t think you need to create your own streaming class; Juce should have everything you need. Here’s some code that associates an AudioFormatReader with an AudioTransportSource for buffered, positionable audio streaming:

// create a new source from the file AudioFormatManager mgr; mgr.registerBasicFormats(); AudioFormatReader* rdr = mgr.createReaderFor(file); if(rdr != 0) { reader = new AudioFormatReaderSource(rdr, true /* delete rdr when done */); transport.setSource(reader, 32768, // read ahead this many samples rdr->sampleRate); }

Here’s the code that actually plays the file:

[code]void AudioPlayer::audioDeviceIOCallback (const float **inputChannelData,
int totalNumInputChannels,
float **outputChannelData,
int totalNumOutputChannels,
int numSamples)
{

// for now assume #input channels = #output channels

AudioSampleBuffer buffer(totalNumInputChannels, numSamples);

AudioSourceChannelInfo info;

info.buffer = &buffer;
info.numSamples = numSamples;
info.startSample = 0;

transport.getNextAudioBlock(info);


for(int i = 0; i < totalNumInputChannels; i++)
{

	for(int j = 0; j < numSamples; j++)
	{
		outputChannelData[i][j] = inputChannelData[i][j];
	}
}

}
[/code]

The above can be simplified further by setting the source of an instance of AudioSourcePlayer to your AudioTransportSource; at the end of the first code snippet add: myAudioSourcePlayer->setSource(transport) and then set myAudioSourcePlayer as the AudioIOCallback object for the current audio device. The advantage of the code in the second snippet is that you can manipulate the samples whereas AudioSourcePlayer is just playback of whatever AudioSource it’s attached to (although you can manipulate which samples get played back via the AudioTransportSource).


#4