Ogg & flac


#1

When an AudioFormatReader is created via the AudioFormatManager using an InputStream, there is only one way to check which format it is, by trying to create a reader. In ogg & flac this can be done switftly by checking the “magic” doubleword at the beginning like:

public:
    //==============================================================================
    FlacReader (InputStream* const in)
        : AudioFormatReader (in, formatName),
          reservoir (2, 0),
          reservoirStart (0),
          samplesInReservoir (0),
          scanningForLength (false),
		  ok (false),
		  decoder (0)
    {
        int64 oldPos = input->getPosition();
        int32 flacMagic = input->readIntBigEndian();
        bool seekOk = input->setPosition(oldPos);
        if (flacMagic == 'fLaC' && seekOk)
        {
			lengthInSamples = 0;

			decoder = FLAC__stream_decoder_new();

and for the ogg reader:

public:
    //==============================================================================
    OggReader (InputStream* const inp)
        : AudioFormatReader (inp, formatName),
          reservoir (2, 2048),
          reservoirStart (0),
          samplesInReservoir (0)
    {
		memset( &ovFile, 0, sizeof(OggVorbis_File) );

		int64 oldPos = input->getPosition();
		int32 oggMagic = input->readIntBigEndian();
		bool seekOk = input->setPosition(0);
		if (oggMagic == 'OggS' && seekOk)
		{
			sampleRate = 0;
			usesFloatingPointData = true;

			callbacks.read_func = &oggReadCallback;
			callbacks.seek_func = &oggSeekCallback;
			callbacks.close_func = &oggCloseCallback;
			callbacks.tell_func = &oggTellCallback;

			const int err = ov_open_callbacks (input, &ovFile, 0, 0, callbacks);

			if (err == 0)
			{
				vorbis_info* info = ov_info (&ovFile, -1);
				lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1);
				numChannels = info->channels;
				bitsPerSample = 16;
				sampleRate = info->rate;

				reservoir.setSize (numChannels,
					(int) jmin (lengthInSamples, (int64) reservoir.getNumSamples()));
			}
		}
    }

    ~OggReader()
    {
		if (ovFile.datasource != 0)
		{
			ov_clear (&ovFile);
		}
    }

#2

True, but this might be a stream that can’t seek, in which case it’d fail to open completely.

Are you having trouble with the speed of opening these things? I can’t imagine that the ogg or flac initialisation code would spend very long trying to open the file - presumably they’d start by doing the same check you’re suggesting here, and fail immediately…


#3