Beispiel #1
0
ALboolean ALFWIsXRAMSupported()
{
	ALboolean bXRAM = AL_FALSE;
	
	if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
	{
		// Get X-RAM Function pointers
		eaxSetBufferMode = (EAXSetBufferMode)alGetProcAddress("EAXSetBufferMode");
		eaxGetBufferMode = (EAXGetBufferMode)alGetProcAddress("EAXGetBufferMode");

		if (eaxSetBufferMode && eaxGetBufferMode)
		{
			eXRAMSize = alGetEnumValue("AL_EAX_RAM_SIZE");
			eXRAMFree = alGetEnumValue("AL_EAX_RAM_FREE");
			eXRAMAuto = alGetEnumValue("AL_STORAGE_AUTOMATIC");
			eXRAMHardware = alGetEnumValue("AL_STORAGE_HARDWARE");
			eXRAMAccessible = alGetEnumValue("AL_STORAGE_ACCESSIBLE");

			if (eXRAMSize && eXRAMFree && eXRAMAuto && eXRAMHardware && eXRAMAccessible)
				bXRAM = AL_TRUE;
		}
	}

	return bXRAM;
}
Beispiel #2
0
int AudioDevice::getFormatFromChannelCount(unsigned int channelCount)
{
    // Create a temporary audio device in case none exists yet.
    // This device will not be used in this function and merely
    // makes sure there is a valid OpenAL device for format
    // queries if none has been created yet.
    //
    // Using an std::vector for this since auto_ptr is deprecated
    // and we have no better STL facility for dynamically allocating
    // a temporary instance with strong exception guarantee.
    std::vector<AudioDevice> device;
    if (!audioDevice)
        device.resize(1);

    // Find the good format according to the number of channels
    int format = 0;
    switch (channelCount)
    {
        case 1:  format = AL_FORMAT_MONO16;                    break;
        case 2:  format = AL_FORMAT_STEREO16;                  break;
        case 4:  format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
        case 6:  format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
        case 7:  format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
        case 8:  format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
        default: format = 0;                                   break;
    }

    // Fixes a bug on OS X
    if (format == -1)
        format = 0;

    return format;
}
Beispiel #3
0
    void AudioSample::loadSampleData(const AudioFile& audioFile)
    {
        std::vector<int16_t> sampleData = audioFile.getSampleData();
        FEA_ASSERT(sampleData.size() > 0, "Trying to load samples from a file containing no samples!");

        if(!mBuffer)
            mBuffer = std::unique_ptr<AudioBuffer>(new AudioBuffer());

        ALint format;
        
        switch(audioFile.getChannelCount())
        {
            case 1  : format = AL_FORMAT_MONO16;                    break;
            case 2  : format = AL_FORMAT_STEREO16;                  break;
            case 4  : format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
            case 6  : format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
            case 7  : format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
            case 8  : format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
            default : format = 0;                                   break;
        }

        // Fixes a bug on OS X supposedly
        if (format == -1)
            format = 0;

        alBufferData(mBuffer->getBufferId(), format, sampleData.data(), sampleData.size() * sizeof(int16_t), audioFile.getSampleRate());
    }
Beispiel #4
0
int AudioDevice::getFormatFromChannelCount(unsigned int channelCount)
{
    // Create a temporary audio device in case none exists yet.
    // This device will not be used in this function and merely
    // makes sure there is a valid OpenAL device for format
    // queries if none has been created yet.
    std::auto_ptr<AudioDevice> device;
    if (!audioDevice)
        device.reset(new AudioDevice);

    // Find the good format according to the number of channels
    int format = 0;
    switch (channelCount)
    {
        case 1:  format = AL_FORMAT_MONO16;                    break;
        case 2:  format = AL_FORMAT_STEREO16;                  break;
        case 4:  format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
        case 6:  format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
        case 7:  format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
        case 8:  format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
        default: format = 0;                                   break;
    }

    // Fixes a bug on OS X
    if (format == -1)
        format = 0;

    return format;
}
Beispiel #5
0
	int AudioDevice::getFormatFromChannels(unsigned int channelCount)
	{
		// Find audio format based on channel count
		switch (channelCount)
		{
			case 1 : return AL_FORMAT_MONO16;
			case 2 : return AL_FORMAT_STEREO16;
			case 4 : return alGetEnumValue("AL_FORMAT_QUAD16");
			case 6 : return alGetEnumValue("AL_FORMAT_51CHN16");
			case 7 : return alGetEnumValue("AL_FORMAT_61CHN16");
			case 8 : return alGetEnumValue("AL_FORMAT_71CHN16");
			default : return 0;
		}
	}
Beispiel #6
0
ALenum SoundLoader::getFormat(unsigned int channels)
{
    switch (channels)
    {
        case 1 : return AL_FORMAT_MONO16;
        case 2 : return AL_FORMAT_STEREO16;
        case 4 : return alGetEnumValue("AL_FORMAT_QUAD16");
        case 6 : return alGetEnumValue("AL_FORMAT_51CHN16");
        case 7 : return alGetEnumValue("AL_FORMAT_61CHN16");
        case 8 : return alGetEnumValue("AL_FORMAT_71CHN16");
    }

    return 0;
}
Beispiel #7
0
void al_getenumvalue( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {

	if (NULL == alGetEnumValue) mogl_glunsupported("alGetEnumValue");
	plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL);
	*mxGetPr(plhs[0])=(double)alGetEnumValue((const ALchar*)mxGetData(prhs[0]));

}
Beispiel #8
0
int AudioDevice::getFormatFromChannelCount(unsigned int channelCount)
{
    ensureALInit();

    // Find the good format according to the number of channels
    switch (channelCount)
    {
        case 1  : return AL_FORMAT_MONO16;
        case 2  : return AL_FORMAT_STEREO16;
        case 4  : return alGetEnumValue("AL_FORMAT_QUAD16");
        case 6  : return alGetEnumValue("AL_FORMAT_51CHN16");
        case 7  : return alGetEnumValue("AL_FORMAT_61CHN16");
        case 8  : return alGetEnumValue("AL_FORMAT_71CHN16");
        default : return 0;
    }
}
Beispiel #9
0
HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size)
{
	DWORD _size, length, samples;
	void *data;

	if(hOpenAL)
	{
		if(bSilent) return 1;

		if(size) { data=(void *)filename; _size=size; }
		else
		{
			data=Resource_Load(filename, &_size);
			if(!data) return 0;
		}

		const BYTE *magic = (const BYTE *) data;
		const bool isOgg = ( (_size > 4) &&
		                     (magic[0] == 'O') && (magic[1] == 'g') &&
		                     (magic[2] == 'g') && (magic[3] == 'S') );

		// !!! FIXME: we currently expect Ogg Vorbis, since this is all we
		// !!! FIXME:  need at the moment.
		if (!isOgg)
		{
			if(!size) Resource_Free(data);
			return 0;
		}

		// !!! FIXME: alternately, stream ogg data?
		void *allocation_decompressed = NULL;
		void *decompressed = NULL;
		ALsizei decompressed_size = 0;
		ALsizei freq = 0;
		ALenum fmt = AL_FORMAT_STEREO16;
		if (isOgg)
		{
			if (alIsExtensionPresent((const ALchar *) "AL_EXT_vorbis"))
			{
				fmt = alGetEnumValue((const ALchar *) "AL_FORMAT_VORBIS_EXT");
				decompressed = data;
				decompressed_size = _size;
			}
			else
			{
				allocation_decompressed = decompress_vorbis((const BYTE *) data, _size, &decompressed_size, &fmt, &freq);
				decompressed = allocation_decompressed;
			}
		}

		ALuint bid = 0;
		alGenBuffers(1, &bid);
		alBufferData(bid, fmt, decompressed, decompressed_size, freq);
		free(allocation_decompressed);  // not delete[] !
		if(!size) Resource_Free(data);
		return (HEFFECT) bid;
	}
	else return 0;
}
Beispiel #10
0
static int lua_alGetEnumValue(lua_State* lua_state)
{
	const ALchar* string_name;
	ALenum ret_val;
	string_name = lua_tostring(lua_state, 1);
	ret_val = alGetEnumValue(string_name);
	lua_pushinteger(lua_state, ret_val);
	return 1;
}
Beispiel #11
0
////////////////////////////////////////////////////////////
/// Get the OpenAL format that matches the given number of channels
////////////////////////////////////////////////////////////
ALenum AudioDevice::GetFormatFromChannelsCount(unsigned int ChannelsCount) const
{
    // Find the good format according to the number of channels
    switch (ChannelsCount)
    {
    case 1 :
        return AL_FORMAT_MONO16;
    case 2 :
        return AL_FORMAT_STEREO16;
    case 4 :
        return alGetEnumValue("AL_FORMAT_QUAD16");
    case 6 :
        return alGetEnumValue("AL_FORMAT_51CHN16");
    case 7 :
        return alGetEnumValue("AL_FORMAT_61CHN16");
    case 8 :
        return alGetEnumValue("AL_FORMAT_71CHN16");
    }

    return 0;
}
	sound::sound ( int size, Uint8 *data, sound_handler::format_type format, int sample_count,
	               int sample_rate, bool stereo ) :
		m_volume ( 1.0f ),
		m_format ( format ),
		m_sample_count ( sample_count ),
		m_sample_rate ( sample_rate ),
		m_stereo ( stereo ),
		m_is_paused ( false ),
		m_loops ( 0 ),
		m_size ( 0 ),
		m_uiSource ( 0 ),
		m_uiBuffer ( 0 ),
		m_uiBuffers ( NULL )
	{
		m_size = size;

		if ( data != NULL && size > 0 )
		{
			// Generate AL Buffers for streaming
			alGenBuffers ( 1, &m_uiBuffer );
			// Generate a Source to playback the Buffers
			alGenSources ( 1, &m_uiSource );

			switch ( m_format )
			{
				case sound_handler::FORMAT_ADPCM :	// gameswf doesn't pass this through; it uncompresses and sends FORMAT_NATIVE16
					assert ( 0 );

				case sound_handler::FORMAT_MP3 :
					log_error ( "MP3 requires FFMPEG library\n" );
					return;

				case sound_handler::FORMAT_NELLYMOSER:	// Mystery proprietary format; see nellymoser.com
					assert ( 0 );
					return;

				case sound_handler::FORMAT_RAW:		// unspecified format.	Useful for 8-bit sounds???
				case sound_handler::FORMAT_UNCOMPRESSED:	// 16 bits/sample, little-endian
				case sound_handler::FORMAT_NATIVE16:	// gameswf extension: 16 bits/sample, native-endian
					break;
			}

			ALenum al_fmt = alGetEnumValue ( m_stereo ? "AL_FORMAT_STEREO16" : "AL_FORMAT_MONO16" );
			alBufferData ( m_uiBuffer, al_fmt, data, size, m_sample_rate );
		}
	}
Beispiel #13
0
void SoundManager::init() {
	for (int i = 0; i < kChannelCount; i++)
		_channels[i] = 0;

	for (int i = 0; i < kSoundTypeMAX; i++)
		_types[i].gain = 1.0;

	_curChannel = 1;
	_curID      = 1;

	_dev = alcOpenDevice(0);

	_hasSound = _dev != 0;
	if (!_hasSound)
		warning("Failed to open OpenAL device. Disabling sound output");

	_ctx = 0;

	_hasMultiChannel = false;
	_format51        = 0;

	if (_hasSound) {
		_ctx = alcCreateContext(_dev, 0);
		alcMakeContextCurrent(_ctx);
		if (!_ctx)
			throw Common::Exception("Could not create OpenAL context");

		_hasMultiChannel = alIsExtensionPresent("AL_EXT_MCFORMATS");
		_format51        = alGetEnumValue("AL_FORMAT_51CHN16");
	}

	if (!createThread())
		throw Common::Exception("Failed to create sound thread: %s", SDL_GetError());

	_ready = true;

	if (!_hasSound)
		return;

	setListenerGain(ConfigMan.getDouble("volume", 1.0));

	setTypeGain(kSoundTypeMusic, ConfigMan.getDouble("volume_music", 1.0));
	setTypeGain(kSoundTypeSFX  , ConfigMan.getDouble("volume_sfx"  , 1.0));
	setTypeGain(kSoundTypeVoice, ConfigMan.getDouble("volume_voice", 1.0));
	setTypeGain(kSoundTypeVideo, ConfigMan.getDouble("volume_video", 1.0));
}
Beispiel #14
0
void OALSoundChannel::addDataToPlayBuffer(char* data, DWORD size, 
                                          const std::string& format, 
                                          DWORD freq)
{
   if (m_freeBuffers.size() == 0)
   {
      throw std::runtime_error("No more free buffers");
   }

   ALuint buffer = m_freeBuffers.front();
   m_freeBuffers.pop_front();
      
   m_soundSystem.alBufferData(buffer, alGetEnumValue(format.c_str()), 
                              data, size, freq);

	m_soundSystem.alSourceQueueBuffers(m_oalSource, 1, &buffer);

   m_soundSystem.alSourcePlay(m_oalSource);
}
Beispiel #15
0
/*
    alcOpenDevice

    Open the Device specified.
*/
ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
{
    ALboolean bDeviceFound = AL_FALSE;
    ALCdevice *device;
    ALint i;

    InitAL();

    if(deviceName && !deviceName[0])
        deviceName = NULL;

    device = malloc(sizeof(ALCdevice));
    if (device)
    {
        const char *fmt;

        //Initialise device structure
        memset(device, 0, sizeof(ALCdevice));

        //Validate device
        device->IsCaptureDevice = AL_FALSE;

        //Set output format
        device->Frequency = GetConfigValueInt(NULL, "frequency", SWMIXER_OUTPUT_RATE);
        if((ALint)device->Frequency <= 0)
            device->Frequency = SWMIXER_OUTPUT_RATE;

        fmt = GetConfigValue(NULL, "format", "AL_FORMAT_STEREO16");
        if(fmt[0])
            device->Format = alGetEnumValue(fmt);

        if(!aluChannelsFromFormat(device->Format))
            device->Format = AL_FORMAT_STEREO16;

        device->UpdateSize = GetConfigValueInt(NULL, "refresh", 4096);
        if((ALint)device->UpdateSize <= 0)
            device->UpdateSize = 4096;

        device->MaxNoOfSources = GetConfigValueInt(NULL, "sources", 256);
        if((ALint)device->MaxNoOfSources <= 0)
            device->MaxNoOfSources = 256;

        // Find a playback device to open
        for(i = 0;BackendList[i].Init;i++)
        {
            device->Funcs = &BackendList[i].Funcs;
            if(ALCdevice_OpenPlayback(device, deviceName))
            {
                SuspendContext(NULL);
                device->next = g_pDeviceList;
                g_pDeviceList = device;
                g_ulDeviceCount++;
                ProcessContext(NULL);

                bDeviceFound = AL_TRUE;
                break;
            }
        }

        if (!bDeviceFound)
        {
            // No suitable output device found
            SetALCError(ALC_INVALID_VALUE);
            free(device);
            device = NULL;
        }
    }
    else
        SetALCError(ALC_OUT_OF_MEMORY);

    return device;
}
Beispiel #16
0
        bool SoundAL::init(const SoundDataPtr& newSoundData)
        {
            if (!Sound::init(newSoundData))
            {
                return false;
            }

            free();

            alGenSources(1, &sourceId);

            if (AudioAL::checkOpenALError())
            {
                log("Failed to create OpenAL source");
                return false;
            }

            alGenBuffers(1, &outputBuffer);

            if (AudioAL::checkOpenALError())
            {
                log("Failed to create OpenAL buffer");
                return false;
            }

            ALenum format = 0;

            if (soundData->getChannels() == 1)
            {
                if (soundData->getBitsPerSample() == 8) format = AL_FORMAT_MONO8;
                else if (soundData->getBitsPerSample() == 16) format = AL_FORMAT_MONO16;
            }
            else if (soundData->getChannels() == 2)
            {
                if (soundData->getBitsPerSample() == 8) format = AL_FORMAT_STEREO8;
                else if (soundData->getBitsPerSample() == 16) format = AL_FORMAT_STEREO16;
            }
            else if (soundData->getChannels() == 4)
            {
                if (soundData->getBitsPerSample() == 8) format = alGetEnumValue("AL_FORMAT_QUAD8");
                else if (soundData->getBitsPerSample() == 16) format = alGetEnumValue("AL_FORMAT_QUAD16");
            }
            else if (soundData->getChannels() == 6)
            {
                if (soundData->getBitsPerSample() == 8) format = alGetEnumValue("AL_FORMAT_51CHN8");
                else if (soundData->getBitsPerSample() == 16) format = alGetEnumValue("AL_FORMAT_51CHN16");
            }
            else if (soundData->getChannels() == 7)
            {
                if (soundData->getBitsPerSample() == 8) format = alGetEnumValue("AL_FORMAT_61CHN8");
                else if (soundData->getBitsPerSample() == 16) format = alGetEnumValue("AL_FORMAT_61CHN16");
            }
            else if (soundData->getChannels() == 8)
            {
                if (soundData->getBitsPerSample() == 8) format = alGetEnumValue("AL_FORMAT_71CHN8");
                else if (soundData->getBitsPerSample() == 16) format = alGetEnumValue("AL_FORMAT_71CHN16");
            }

            if (format == 0)
            {
                log("Unsupported audio format");
                return false;
            }

            alBufferData(outputBuffer, format, soundData->getData().data(), soundData->getData().size(), soundData->getSamplesPerSecond());

            if (AudioAL::checkOpenALError())
            {
                log("Failed to upload OpenAL data");
                return false;
            }

            alSourcef(sourceId, AL_PITCH, 1.0f);
            alSourcef(sourceId, AL_GAIN, 1.0f);

            alSourcei(sourceId, AL_BUFFER, outputBuffer);

            if (AudioAL::checkOpenALError())
            {
                log("Failed to set OpenAL buffer");
                return false;
            }

            ready = true;

            return true;
        }
Beispiel #17
0
static GstCaps *
gst_openal_helper_probe_caps (ALCcontext * context)
{
  static const struct
  {
    gint count;
    GstAudioChannelPosition positions[8];
  } chans[] = {
    {
      1, {
      GST_AUDIO_CHANNEL_POSITION_MONO}
    }, {
      2, {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
    }, {
      4, {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
            GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
            GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}
    }, {
      6, {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
            GST_AUDIO_CHANNEL_POSITION_LFE1,
            GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
            GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}
    }, {
      7, {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
            GST_AUDIO_CHANNEL_POSITION_LFE1,
            GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
            GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
            GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
    }, {
      8, {
      GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
            GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
            GST_AUDIO_CHANNEL_POSITION_LFE1,
            GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
            GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
            GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
            GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
  },};
  GstStructure *structure;
  guint64 channel_mask;
  GstCaps *caps;
  ALCcontext *old;

  old = pushContext (context);

  caps = gst_caps_new_empty ();

  if (alIsExtensionPresent ("AL_EXT_MCFORMATS")) {
    const char *fmt32[] = {
      "AL_FORMAT_MONO_FLOAT32",
      "AL_FORMAT_STEREO_FLOAT32",
      "AL_FORMAT_QUAD32",
      "AL_FORMAT_51CHN32",
      "AL_FORMAT_61CHN32",
      "AL_FORMAT_71CHN32",
      NULL
    }, *fmt16[] = {
    "AL_FORMAT_MONO16",
          "AL_FORMAT_STEREO16",
          "AL_FORMAT_QUAD16",
          "AL_FORMAT_51CHN16",
          "AL_FORMAT_61CHN16", "AL_FORMAT_71CHN16", NULL}, *fmt8[] = {
    "AL_FORMAT_MONO8",
          "AL_FORMAT_STEREO8",
          "AL_FORMAT_QUAD8",
          "AL_FORMAT_51CHN8", "AL_FORMAT_61CHN8", "AL_FORMAT_71CHN8", NULL};
    int i;

    if (alIsExtensionPresent ("AL_EXT_FLOAT32")) {
      for (i = 0; fmt32[i]; i++) {
        ALenum value = alGetEnumValue (fmt32[i]);
        if (checkALError () != AL_NO_ERROR || value == 0 || value == -1)
          continue;

        structure =
            gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
            GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
            OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL);
        if (chans[i].count > 2) {
          gst_audio_channel_positions_to_mask (chans[i].positions,
              chans[i].count, FALSE, &channel_mask);
          gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK,
              channel_mask, NULL);
        }
        gst_caps_append_structure (caps, structure);
      }
    }

    for (i = 0; fmt16[i]; i++) {
      ALenum value = alGetEnumValue (fmt16[i]);
      if (checkALError () != AL_NO_ERROR || value == 0 || value == -1)
        continue;

      structure =
          gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
          GST_AUDIO_NE (S16), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
          OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL);
      if (chans[i].count > 2) {
        gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count,
            FALSE, &channel_mask);
        gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK,
            channel_mask, NULL);
      }
      gst_caps_append_structure (caps, structure);
    }
    for (i = 0; fmt8[i]; i++) {
      ALenum value = alGetEnumValue (fmt8[i]);
      if (checkALError () != AL_NO_ERROR || value == 0 || value == -1)
        continue;

      structure =
          gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
          G_STRINGIFY (U8), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
          OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL);
      if (chans[i].count > 2) {
        gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count,
            FALSE, &channel_mask);
        gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK,
            channel_mask, NULL);
      }
      gst_caps_append_structure (caps, structure);
    }
  } else {
    if (alIsExtensionPresent ("AL_EXT_FLOAT32")) {
      structure =
          gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
          GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
          OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
      gst_caps_append_structure (caps, structure);
    }

    structure =
        gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
        GST_AUDIO_NE (S16), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
        OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
    gst_caps_append_structure (caps, structure);

    structure =
        gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
        G_STRINGIFY (U8), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
        OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_double")) {
    structure =
        gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
        GST_AUDIO_NE (F64), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
        OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_IMA4")) {
    structure =
        gst_structure_new ("audio/x-adpcm", "layout", G_TYPE_STRING, "ima",
        "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
        "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_ALAW")) {
    structure =
        gst_structure_new ("audio/x-alaw", "rate", GST_TYPE_INT_RANGE,
        OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2,
        NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_MULAW_MCFORMATS")) {
    const char *fmtmulaw[] = {
      "AL_FORMAT_MONO_MULAW",
      "AL_FORMAT_STEREO_MULAW",
      "AL_FORMAT_QUAD_MULAW",
      "AL_FORMAT_51CHN_MULAW",
      "AL_FORMAT_61CHN_MULAW",
      "AL_FORMAT_71CHN_MULAW",
      NULL
    };
    int i;

    for (i = 0; fmtmulaw[i]; i++) {
      ALenum value = alGetEnumValue (fmtmulaw[i]);
      if (checkALError () != AL_NO_ERROR || value == 0 || value == -1)
        continue;

      structure =
          gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE,
          OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT,
          chans[i].count, NULL);
      if (chans[i].count > 2) {
        gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count,
            FALSE, &channel_mask);
        gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK,
            channel_mask, NULL);
      }
      gst_caps_append_structure (caps, structure);
    }
  } else if (alIsExtensionPresent ("AL_EXT_MULAW")) {
    structure =
        gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE,
        OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2,
        NULL);
    gst_caps_append_structure (caps, structure);
  }

  popContext (old, context);

  return caps;
}
Beispiel #18
0
ALenum CDECL wine_alGetEnumValue(const ALchar* ename)
{
    return alGetEnumValue(ename);
}
	/* GetFormat retrieves a compatible buffer format given the channel config and
	* sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
	* provided, it will be called to find the closest-matching format from
	* AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
	* found. */
	ALenum GetAudioFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT)
	{
		ALenum format = AL_NONE;

		/* If using AL_SOFT_buffer_samples, try looking through its formats */
		if (palIsBufferFormatSupportedSOFT)
		{
			/* AL_SOFT_buffer_samples is more lenient with matching formats. The
			* specified sample type does not need to match the returned format,
			* but it is nice to try to get something close. */
			if (type == AL_UNSIGNED_BYTE_SOFT || type == AL_BYTE_SOFT)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
			}
			else if (type == AL_UNSIGNED_SHORT_SOFT || type == AL_SHORT_SOFT)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
			}
			else if (type == AL_UNSIGNED_BYTE3_SOFT || type == AL_BYTE3_SOFT ||
				type == AL_UNSIGNED_INT_SOFT || type == AL_INT_SOFT ||
				type == AL_FLOAT_SOFT || type == AL_DOUBLE_SOFT)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
			}

			if (format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
				format = AL_NONE;

			/* A matching format was not found or supported. Try 32-bit float. */
			if (format == AL_NONE)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;

				if (format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
					format = AL_NONE;
			}
			/* 32-bit float not supported. Try 16-bit int. */
			if (format == AL_NONE)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;

				if (format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
					format = AL_NONE;
			}
			/* 16-bit int not supported. Try 8-bit int. */
			if (format == AL_NONE)
			{
				if (channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
				else if (channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
				else if (channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
				else if (channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
				else if (channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
				else if (channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;

				if (format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
					format = AL_NONE;
			}

			return format;
		}

		/* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
		* and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
		* AL_EXT_DOUBLE for 64-bit float samples. */
		if (type == AL_UNSIGNED_BYTE_SOFT)
		{
			if (channels == AL_MONO_SOFT)
				format = AL_FORMAT_MONO8;
			else if (channels == AL_STEREO_SOFT)
				format = AL_FORMAT_STEREO8;
			else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
			{
				if (channels == AL_QUAD_SOFT)
					format = alGetEnumValue("AL_FORMAT_QUAD8");
				else if (channels == AL_5POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_51CHN8");
				else if (channels == AL_6POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_61CHN8");
				else if (channels == AL_7POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_71CHN8");
			}
		}
		else if (type == AL_SHORT_SOFT)
		{
			if (channels == AL_MONO_SOFT)
				format = AL_FORMAT_MONO16;
			else if (channels == AL_STEREO_SOFT)
				format = AL_FORMAT_STEREO16;
			else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
			{
				if (channels == AL_QUAD_SOFT)
					format = alGetEnumValue("AL_FORMAT_QUAD16");
				else if (channels == AL_5POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_51CHN16");
				else if (channels == AL_6POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_61CHN16");
				else if (channels == AL_7POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_71CHN16");
			}
		}
		else if (type == AL_FLOAT_SOFT && alIsExtensionPresent("AL_EXT_FLOAT32"))
		{
			if (channels == AL_MONO_SOFT)
				format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
			else if (channels == AL_STEREO_SOFT)
				format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
			else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
			{
				if (channels == AL_QUAD_SOFT)
					format = alGetEnumValue("AL_FORMAT_QUAD32");
				else if (channels == AL_5POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_51CHN32");
				else if (channels == AL_6POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_61CHN32");
				else if (channels == AL_7POINT1_SOFT)
					format = alGetEnumValue("AL_FORMAT_71CHN32");
			}
		}
		else if (type == AL_DOUBLE_SOFT && alIsExtensionPresent("AL_EXT_DOUBLE"))
		{
			if (channels == AL_MONO_SOFT)
				format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE");
			else if (channels == AL_STEREO_SOFT)
				format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE");
		}

		/* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
		* opposed to 0. Correct it. */
		if (format == -1)
			format = 0;

		return format;
	}
Beispiel #20
0
	/*/////////////////////////////////////////////////////////////////*/
	bool OgreOggStreamSound::_queryBufferInfo()
	{
		if (!mVorbisInfo)
		{
			Ogre::LogManager::getSingleton().logMessage("*** --- No vorbis info!");
			return false;
		}

		switch(mVorbisInfo->channels)
		{
		case 1:
			{
				mFormat = AL_FORMAT_MONO16;
				// Set BufferSize to 250ms (Frequency * 2 (16bit) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate >> 1;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 2);
			}
			break;
		case 2:
			{
				mFormat = AL_FORMAT_STEREO16;
				// Set BufferSize to 250ms (Frequency * 4 (16bit stereo) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 4);
			}
			break;
		case 4:
			{
				mFormat = alGetEnumValue("AL_FORMAT_QUAD16");
				if (!mFormat) return false;
				// Set BufferSize to 250ms (Frequency * 8 (16bit 4-channel) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate * 2;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 8);
			}
			break;
		case 6:
			{
				mFormat = alGetEnumValue("AL_FORMAT_51CHN16");
				if (!mFormat) return false;
				// Set BufferSize to 250ms (Frequency * 12 (16bit 6-channel) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate * 3;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 12);
			}
			break;
		case 7:
			{
				mFormat = alGetEnumValue("AL_FORMAT_61CHN16");
				if (!mFormat) return false;
				// Set BufferSize to 250ms (Frequency * 16 (16bit 7-channel) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate * 4;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 16);
			}
			break;
		case 8:
			{
				mFormat = alGetEnumValue("AL_FORMAT_71CHN16");
				if (!mFormat) return false;
				// Set BufferSize to 250ms (Frequency * 20 (16bit 8-channel) divided by 4 (quarter of a second))
				mBufferSize = mVorbisInfo->rate * 5;
				// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
				mBufferSize -= (mBufferSize % 20);
			}
			break;
		default:
			// Couldn't determine buffer format so log the error and default to mono
			Ogre::LogManager::getSingleton().logMessage("!!WARNING!! Could not determine buffer format!  Defaulting to MONO");

			mFormat = AL_FORMAT_MONO16;
			// Set BufferSize to 250ms (Frequency * 2 (16bit) divided by 4 (quarter of a second))
			mBufferSize = mVorbisInfo->rate >> 1;
			// IMPORTANT : The Buffer Size must be an exact multiple of the BlockAlignment ...
			mBufferSize -= (mBufferSize % 2);
			break;
		}
		return true;
	}
Beispiel #21
0
bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
{
	bool valid = true;
	format = 0;

	switch(m_specs.format)
	{
	case AUD_FORMAT_S16:
		switch(specs.channels)
		{
		case AUD_CHANNELS_MONO:
			format = AL_FORMAT_MONO16;
			break;
		case AUD_CHANNELS_STEREO:
			format = AL_FORMAT_STEREO16;
			break;
		case AUD_CHANNELS_SURROUND4:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_QUAD16");
				break;
			}
		case AUD_CHANNELS_SURROUND51:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_51CHN16");
				break;
			}
		case AUD_CHANNELS_SURROUND61:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_61CHN16");
				break;
			}
		case AUD_CHANNELS_SURROUND71:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_71CHN16");
				break;
			}
		default:
			valid = false;
		}
		break;
	case AUD_FORMAT_FLOAT32:
		switch(specs.channels)
		{
		case AUD_CHANNELS_MONO:
			format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
			break;
		case AUD_CHANNELS_STEREO:
			format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
			break;
		case AUD_CHANNELS_SURROUND4:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_QUAD32");
				break;
			}
		case AUD_CHANNELS_SURROUND51:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_51CHN32");
				break;
			}
		case AUD_CHANNELS_SURROUND61:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_61CHN32");
				break;
			}
		case AUD_CHANNELS_SURROUND71:
			if(m_useMC)
			{
				format = alGetEnumValue("AL_FORMAT_71CHN32");
				break;
			}
		default:
			valid = false;
		}
		break;
	default:
		valid = false;
	}

	if(!format)
		valid = false;

	return valid;
}
Beispiel #22
0
void vineoOpen( Vineo *v, char *file )
{
    // NOTE FIXME als er iets mis gaat in deze functie, netjes unloaden

    if( av_open_input_file( &v->fmt_ctx, file, NULL, 0, NULL ) != 0 )
    {
        printf( "Error @ vineoOpen() @ av_open_input_file()\n" );
        return;
    }

    if( av_find_stream_info( v->fmt_ctx ) < 0 )
    {
        printf( "Error @ vineoOpen() @ av_find_stream_info()\n" );
        return;
    }


    //dump_format( v->fmt_ctx, 0, file, 0 );


    // doe we have a start time offset?
    if( v->fmt_ctx->start_time != AV_NOPTS_VALUE ) {
		v->start_time = v->fmt_ctx->start_time;
	}


    // find streams
    int i;

    for( i = 0; i < v->fmt_ctx->nb_streams; i++ )
    {
        if( v->fmt_ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO && v->idx_video < 0 ) {
            v->idx_video = i;
        }

         if( v->fmt_ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && v->idx_audio < 0) {
            v->idx_audio = i;
        }
    }


    // open video codec
    if( v->idx_video >= 0 )
    {
        v->vid_codec_ctx = v->fmt_ctx->streams[v->idx_video]->codec;
        v->vid_codec = avcodec_find_decoder( v->vid_codec_ctx->codec_id );

        if( !v->vid_codec )
        {
            printf( "Error @ vineoOpen() @ avcodec_find_decoder()\n" );
            v->idx_video = -1;
        }
        else if( avcodec_open( v->vid_codec_ctx, v->vid_codec ) < 0 )
        {
            printf( "Error @ vineoOpen() @ avcodec_open()\n" );
            v->idx_video = -1;
        }

        v->sws = sws_getContext(
            v->vid_codec_ctx->width,
            v->vid_codec_ctx->height,
            v->vid_codec_ctx->pix_fmt,
            v->vid_codec_ctx->width,
            v->vid_codec_ctx->height,
            PIX_FMT_RGBA32,
            SWS_FAST_BILINEAR,
            NULL,
            NULL,
            NULL
        );
    }


    // open audio codec
    if( v->idx_audio >= 0 )
    {
        v->aud_codec_ctx = v->fmt_ctx->streams[v->idx_audio]->codec;
        v->aud_codec = avcodec_find_decoder( v->aud_codec_ctx->codec_id );

        if( !v->aud_codec )
        {
            printf( "Error @ vineoOpen() @ avcodec_find_decoder()\n" );
            v->idx_audio = -1;
        }
        else if( avcodec_open( v->aud_codec_ctx, v->aud_codec ) < 0 )
        {
            printf( "Error @ vineoOpen() @ avcodec_open()\n" );
            v->idx_audio = -1;
        }
    }


    // allocate video frames for decoding
    if( v->idx_video >= 0 )
    {
        v->frame = avcodec_alloc_frame();
        v->frame_rgba = avcodec_alloc_frame();

        if( !v->frame_rgba )
        {
            printf( "Error @ vineoOpen() @ avcodec_alloc_frame()\n" );
            return;
        }

        int b = avpicture_get_size( PIX_FMT_RGBA32, v->vid_codec_ctx->width, v->vid_codec_ctx->height );
        v->frame_buffer = av_malloc( b * sizeof(unsigned char) );

        if( !v->frame_buffer )
        {
            printf( "Error @ vineoOpen() @ av_malloc()\n" );
            return;
        }

        avpicture_fill( (AVPicture *)v->frame_rgba, v->frame_buffer, PIX_FMT_RGBA32, v->vid_codec_ctx->width, v->vid_codec_ctx->height );
    }


    // init audio
    if( v->idx_audio >= 0 )
    {
        v->aud_rate = v->aud_codec_ctx->sample_rate;
        v->aud_channels = v->aud_codec_ctx->channels;
        v->aud_bits = 16; // NOTE ffmpeg gebruikt altijd 16 bits
        v->aud_format = 0;

        if( v->aud_channels == 1 ) {
            v->aud_format = AL_FORMAT_MONO16;
        }

        if( v->aud_channels == 2 ) {
            v->aud_format = AL_FORMAT_STEREO16;
        }

        if( alIsExtensionPresent("AL_EXT_MCFORMATS") )
        {
            if( v->aud_channels == 4 ) {
                v->aud_format = alGetEnumValue("AL_FORMAT_QUAD16");
            }

            if( v->aud_channels == 6 ) {
                v->aud_format = alGetEnumValue("AL_FORMAT_51CHN16");
            }
        }

        if( v->aud_format == 0 )
        {
            printf( "Error @ vineoOpen() @ Unhandled format (%d channels, %d bits)\n", v->aud_channels, v->aud_bits );
            avcodec_close( v->aud_codec_ctx );
            v->idx_audio = -1;
            return;
        }
        else
        {
            v->buffer_playing = 0;
            v->data = NULL;
            v->data_size = 0;
            v->data_size_max = 0;
            v->dec_data = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
            v->dec_data_size = 0;

            if( !v->dec_data )
            {
                printf( "Error @ vineoOpen() @ av_malloc()\n" );
                return;
            }

            v->data_tmp = av_malloc( VINEO_AUDIO_BUFFER_SIZE );

            if( !v->data_tmp )
            {
                printf( "Error @ vineoOpen() @ av_malloc()\n" );
                return;
            }
        }
    }

    v->is_opened = 1;
}
Beispiel #23
0
bool SoundResource::load( const char *data, int size )
{
	if( !Resource::load( data, size ) )
		return false;

	SoundDecoder *decoder = SoundManager::instance()->getDecoder( data, (size_t)size );

	if( decoder == 0x0 )
		return raiseError( "failed to retrieve decoder" );

	const char *error;

	if( ( error = decoder->init( data, size, _soundInfo ) ) != 0x0 )
	{
		SoundManager::instance()->releaseDecoder( decoder );
		return raiseError( "failed to initialize decoder : " + std::string( error ) );
	}

	//calculate the size needed to store the decoded sound data
	size_t sizeNeeded = (size_t)( _soundInfo.runtime * ( _soundInfo.samplingRate * ( _soundInfo.bitDepth / 8 ) * _soundInfo.channels ) );

	char *decodedData = new char[sizeNeeded];
	size_t sizeDecoded = decoder->decodeData( decodedData, sizeNeeded );

	//we are done decoding, release the decoder
	SoundManager::instance()->releaseDecoder( decoder );

	ALenum format = 0;

	if( _soundInfo.bitDepth == 8 )
	{
		switch( _soundInfo.channels )
		{
		case 1:
			format = AL_FORMAT_MONO8;
			break;
		case 2:
			format = AL_FORMAT_STEREO8;
			break;
		case 4:
			format = alGetEnumValue( "AL_FORMAT_QUAD8" );
			break;
		case 6:
			format = alGetEnumValue( "AL_FORMAT_51CHN8" );
			break;
		case 7:
			format = alGetEnumValue( "AL_FORMAT_61CHN8" );
			break;
		case 8:
			format = alGetEnumValue( "AL_FORMAT_71CHN8" );
			break;
		}
	}
	else if( _soundInfo.bitDepth == 16 )
	{
		switch( _soundInfo.channels )
		{
		case 1:
			format = AL_FORMAT_MONO16;
			break;
		case 2:
			format = AL_FORMAT_STEREO16;
			break;
		case 4:
			format = alGetEnumValue( "AL_FORMAT_QUAD16" );
			break;
		case 6:
			format = alGetEnumValue( "AL_FORMAT_51CHN16" );
			break;
		case 7:
			format = alGetEnumValue( "AL_FORMAT_61CHN16" );
			break;
		case 8:
			format = alGetEnumValue( "AL_FORMAT_71CHN16" );
			break;
		}
	}

	if( !format )
	{
		delete[] decodedData;
		return raiseError( "sound has invalid bitdepth or unsupported number of channels" );
	}

	//fill the buffer with our decoded sound data
	alBufferData( _buffer, format, decodedData, (ALsizei)sizeDecoded, (ALsizei)_soundInfo.samplingRate );
	SoundManager::instance()->checkALError( "filling buffer with data for Sound resource '%s'", _name.c_str() );

	delete[] decodedData;

	return true;
}
Beispiel #24
0
static void *decode_to_pcm(const char *_fname, ALenum &format, ALsizei &size, ALuint &freq)
{
#ifdef __POWERPC__
    const int bigendian = 1;
#else
    const int bigendian = 0;
#endif

    // !!! FIXME: if it's not Ogg, we don't have a decoder. I'm lazy.  :/
    char *fname = (char *) alloca(strlen(_fname) + 16);
    strcpy(fname, _fname);
    char *ptr = strchr(fname, '.');
    if (ptr) *ptr = NULL;
    strcat(fname, ".ogg");

    // just in case...
    #undef fopen
    FILE *io = fopen(fname, "rb");
    if (io == NULL)
        return NULL;

    ALubyte *retval = NULL;

    #if 0  // untested, so disable this!
    // Can we just feed it to the AL compressed?
    if (alIsExtensionPresent((const ALubyte *) "AL_EXT_vorbis"))
    {
        format = alGetEnumValue((const ALubyte *) "AL_FORMAT_VORBIS_EXT");
        freq = 44100;
        fseek(io, 0, SEEK_END);
        size = ftell(io);
        fseek(io, 0, SEEK_SET);
        retval = (ALubyte *) malloc(size);
        size_t rc = fread(retval, size, 1, io);
        fclose(io);
        if (rc != 1)
        {
            free(retval);
            return NULL;
        }
        return retval;
    }
    #endif

    // Uncompress and feed to the AL.
    OggVorbis_File vf;
    memset(&vf, '\0', sizeof (vf));
    if (ov_open(io, &vf, NULL, 0) == 0)
    {
        int bitstream = 0;
        vorbis_info *info = ov_info(&vf, -1);
        size = 0;
        format = (info->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
        freq = info->rate;

        if ((info->channels != 1) && (info->channels != 2))
        {
            ov_clear(&vf);
            return NULL;
        }

        char buf[1024 * 16];
        long rc = 0;
        size_t allocated = 64 * 1024;
        retval = (ALubyte *) malloc(allocated);
        while ( (rc = ov_read(&vf, buf, sizeof (buf), bigendian, 2, 1, &bitstream)) != 0 )
        {
            if (rc > 0)
            {
                size += rc;
                if (size >= allocated)
                {
                    allocated *= 2;
                    ALubyte *tmp = (ALubyte *) realloc(retval, allocated);
                    if (tmp == NULL)
                    {
                        free(retval);
                        retval = NULL;
                        break;
                    }
                    retval = tmp;
                }
                memcpy(retval + (size - rc), buf, rc);
            }
        }
        ov_clear(&vf);
        return retval;
    }

    fclose(io);
    return NULL;
}
Beispiel #25
0
static void printEFXInfo(ALCdevice *device)
{
    ALCint major, minor, sends;
    static const ALchar filters[][32] = {
        "AL_FILTER_LOWPASS", "AL_FILTER_HIGHPASS", "AL_FILTER_BANDPASS", ""
    };
    char filterNames[] = "Low-pass,High-pass,Band-pass,";
    static const ALchar effects[][32] = {
        "AL_EFFECT_EAXREVERB", "AL_EFFECT_REVERB", "AL_EFFECT_CHORUS",
        "AL_EFFECT_DISTORTION", "AL_EFFECT_ECHO", "AL_EFFECT_FLANGER",
        "AL_EFFECT_FREQUENCY_SHIFTER", "AL_EFFECT_VOCAL_MORPHER",
        "AL_EFFECT_PITCH_SHIFTER", "AL_EFFECT_RING_MODULATOR",
        "AL_EFFECT_AUTOWAH", "AL_EFFECT_COMPRESSOR", "AL_EFFECT_EQUALIZER", ""
    };
    static const ALchar dedeffects[][64] = {
        "AL_EFFECT_DEDICATED_DIALOGUE",
        "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", ""
    };
    char effectNames[] = "EAX Reverb,Reverb,Chorus,Distortion,Echo,Flanger,"
                         "Frequency Shifter,Vocal Morpher,Pitch Shifter,"
                         "Ring Modulator,Autowah,Compressor,Equalizer,"
                         "Dedicated Dialog,Dedicated LFE,";
    char *current;
    int i;

    if(alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
    {
        printf("EFX not available\n");
        return;
    }

    alcGetIntegerv(device, ALC_EFX_MAJOR_VERSION, 1, &major);
    alcGetIntegerv(device, ALC_EFX_MINOR_VERSION, 1, &minor);
    if(checkALCErrors(device) == ALC_NO_ERROR)
        printf("EFX version: %d.%d\n", major, minor);
    alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
    if(checkALCErrors(device) == ALC_NO_ERROR)
        printf("Max auxiliary sends: %d\n", sends);

    current = filterNames;
    for(i = 0;filters[i][0];i++)
    {
        char *next = strchr(current, ',');
        ALenum val;

        val = alGetEnumValue(filters[i]);
        if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
            memmove(current, next+1, strlen(next));
        else
            current = next+1;
    }
    printf("Supported filters:");
    printList(filterNames, ',');

    current = effectNames;
    for(i = 0;effects[i][0];i++)
    {
        char *next = strchr(current, ',');
        ALenum val;

        val = alGetEnumValue(effects[i]);
        if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
            memmove(current, next+1, strlen(next));
        else
            current = next+1;
    }
    if(alcIsExtensionPresent(device, "ALC_EXT_DEDICATED"))
    {
        for(i = 0;dedeffects[i][0];i++)
        {
            char *next = strchr(current, ',');
            ALenum val;

            val = alGetEnumValue(dedeffects[i]);
            if(alGetError() != AL_NO_ERROR || val == 0 || val == -1)
                memmove(current, next+1, strlen(next));
            else
                current = next+1;
        }
    }
    else
    {
        for(i = 0;dedeffects[i][0];i++)
        {
            char *next = strchr(current, ',');
            memmove(current, next+1, strlen(next));
        }
    }
    printf("Supported effects:");
    printList(effectNames, ',');
}
Beispiel #26
0
/* The allocate_voice method should grab a voice from the system, and allocate
   any data common to streaming and non-streaming sources. */
static int _openal_allocate_voice(ALLEGRO_VOICE *voice)
{
   ALLEGRO_AL_DATA *ex_data;

   /* OpenAL doesn't support very much! */
   switch (voice->depth) {
      case ALLEGRO_AUDIO_DEPTH_UINT8:
         /* format supported */
         break;
      case ALLEGRO_AUDIO_DEPTH_INT8:
         ALLEGRO_WARN("OpenAL requires 8-bit data to be unsigned\n");
         return 1;
      case ALLEGRO_AUDIO_DEPTH_UINT16:
         ALLEGRO_WARN("OpenAL requires 16-bit data to be signed\n");
         return 1;
      case ALLEGRO_AUDIO_DEPTH_INT16:
         /* format supported */
         break;
      case ALLEGRO_AUDIO_DEPTH_UINT24:
         ALLEGRO_WARN("OpenAL does not support 24-bit data\n");
         return 1;
      case ALLEGRO_AUDIO_DEPTH_INT24:
         ALLEGRO_WARN("OpenAL does not support 24-bit data\n");
         return 1;
      case ALLEGRO_AUDIO_DEPTH_FLOAT32:
         ALLEGRO_WARN("OpenAL does not support 32-bit floating data\n");
         return 1;
      default:
         ALLEGRO_WARN("Cannot allocate unknown voice depth\n");
         return 1;
   }

   ex_data = al_calloc(1, sizeof(*ex_data));
   if (!ex_data) {
      ALLEGRO_ERROR("Could not allocate voice data memory\n");
      return 1;
   }

   switch (voice->chan_conf) {
      case ALLEGRO_CHANNEL_CONF_1:
         /* format supported */
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8)
            ex_data->format = AL_FORMAT_MONO8;
         else
            ex_data->format = AL_FORMAT_MONO16;
         break;
      case ALLEGRO_CHANNEL_CONF_2:
         /* format supported */
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8)
            ex_data->format = AL_FORMAT_STEREO8;
         else
            ex_data->format = AL_FORMAT_STEREO16;
         break;
      case ALLEGRO_CHANNEL_CONF_3:
         ALLEGRO_ERROR("OpenAL does not support voice with 3 channel configuration\n");
         al_free(ex_data);
         return 1;
      case ALLEGRO_CHANNEL_CONF_4:
         ex_data->format = alGetEnumValue("AL_FORMAT_QUAD16");
         if (ex_data->format) {
            ALLEGRO_ERROR("OpenAL cannot allocate voice with 4.0 channel configuration\n");
            al_free(ex_data);
            return 1;
         }
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) {
            ALLEGRO_ERROR("OpenAL requires 16-bit signed data for 4 channel configuration\n");
            al_free(ex_data);
            return 1;
         }
         /* else it is supported */
         break;
      case ALLEGRO_CHANNEL_CONF_5_1:
         ex_data->format = alGetEnumValue("AL_FORMAT_51CHN_16");
         if (!ex_data->format) {
            ALLEGRO_ERROR("Cannot allocate voice with 5.1 channel configuration\n");
            al_free(ex_data);
            return 1;
         }
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) {
            ALLEGRO_ERROR("5.1 channel requires 16-bit signed data\n");
            al_free(ex_data);
            return 1;
         }
         /* else it is supported */
         break;
      case ALLEGRO_CHANNEL_CONF_6_1:
         ex_data->format = alGetEnumValue("AL_FORMAT_61CHN_16");
         if (!ex_data->format) {
            ALLEGRO_ERROR("Cannot allocate voice with 6.1 channel configuration\n");
            al_free(ex_data);
            return 1;
         }
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) {
            ALLEGRO_ERROR("6.1 channel requires 16-bit signed data\n");
            al_free(ex_data);
            return 1;
         }
         /* else it is supported */
         break;
      case ALLEGRO_CHANNEL_CONF_7_1:
         ex_data->format = alGetEnumValue("AL_FORMAT_71CHN_16");
         if (!ex_data->format) {
            ALLEGRO_ERROR("Cannot allocate voice with 7.1 channel configuration\n");
            al_free(ex_data);
            return 1;
         }
         if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) {
            ALLEGRO_ERROR("7.1 channel requires 16-bit signed data\n");
            al_free(ex_data);
            return 1;
         }
         /* else it is supported */
         break;
      default:
         ALLEGRO_ERROR("Cannot allocate voice with unknown channel configuration\n");
         al_free(ex_data);
         return 1;
   }

   voice->extra = ex_data;
   ex_data->thread = NULL;
   ex_data->stopped = false;

   return 0;
}
Beispiel #27
0
bool CSound::loadFromFile(const CString& fileName)
{
    m_loaded = false;
    m_fileName = fileName;
    ALenum error;

    // Ouverture du fichier audio avec libsndfile
    SF_INFO file_infos;
    SNDFILE * file = sf_open(m_fileName.toCharArray(), SFM_READ, &file_infos);

    if (!file)
    {
        CApplication::getApp()->log(CString("CSound::loadFromFile : impossible d'ouvrir le fichier %1").arg(m_fileName), ILogger::Error);
        return false;
    }

    CApplication::getApp()->log(CString("Chargement du son %1").arg(m_fileName));

    // Lecture du nombre d'échantillons et du taux d'échantillonnage
    m_nbrSamples = static_cast<ALsizei>(file_infos.channels * file_infos.frames);
    m_sampleRate = static_cast<ALsizei>(file_infos.samplerate);

    // Lecture des échantillons audio au format entier 16 bits signé
    std::vector<ALshort> samples(m_nbrSamples);

    if (sf_read_short(file, &samples[0], m_nbrSamples) < m_nbrSamples)
    {
        return false;
    }

    // Fermeture du fichier
    sf_close(file);

    // Détermination du format en fonction du nombre de canaux
    ALenum format;

    switch (file_infos.channels)
    {
        case 1:
            format = AL_FORMAT_MONO16;
            break;

        case 2:
            format = AL_FORMAT_STEREO16;
            break;

        case 4:

            if (!CSoundEngine::isOALExtension("AL_EXT_MCFORMATS"))
            {
                return false;
            }

            format = alGetEnumValue("AL_FORMAT_QUAD16");
            break;

        case 6:

            if (!CSoundEngine::isOALExtension("AL_EXT_MCFORMATS"))
            {
                return false;
            }

            format = alGetEnumValue("AL_FORMAT_51CHN16");
            break;

        case 7:

            if (!CSoundEngine::isOALExtension("AL_EXT_MCFORMATS"))
            {
                return false;
            }

            format = alGetEnumValue("AL_FORMAT_61CHN16");
            break;

        case 8:

            if (!CSoundEngine::isOALExtension("AL_EXT_MCFORMATS"))
            {
                return false;
            }

            format = alGetEnumValue("AL_FORMAT_71CHN16");
            break;

        default:
            return false;
    }

    // Création du tampon OpenAL
    alGenBuffers(1, &m_buffer);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR || m_buffer == 0)
    {
        CSoundEngine::displayOpenALError(error, "alGenBuffers", __LINE__);
        return false;
    }

    // Remplissage avec les échantillons lus
    alBufferData(m_buffer, format, &samples[0], m_nbrSamples * sizeof(ALushort), m_sampleRate);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alBufferData", __LINE__);
        return false;
    }

    // Création d'une source
    alGenSources(1, &m_source);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR || m_source == 0)
    {
        CSoundEngine::displayOpenALError(error, "alGenSources", __LINE__);
        return false;
    }

    // Paramètres de la source
    alSourcei(m_source, AL_BUFFER, m_buffer);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alSourcei", __LINE__);
        return false;
    }

    alSourcei(m_source, AL_LOOPING, false);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alSourcei", __LINE__);
    }

    alSourcef(m_source, AL_PITCH, 1.0f);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alSourcef", __LINE__);
    }

    alSourcef(m_source, AL_GAIN, 1.0f);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alSourcef", __LINE__);
    }

    alSource3f(m_source, AL_POSITION, 0.0f, 0.0f, 0.0f);

    // Traitement des erreurs
    if ((error = alGetError()) != AL_NO_ERROR)
    {
        CSoundEngine::displayOpenALError(error, "alSource3f", __LINE__);
    }

    m_loaded = true;
    return true;
}
Beispiel #28
0
value lime_al_get_enum_value (value ename) {

    return alloc_int (alGetEnumValue (val_string (ename)));

}
/**
 * Initializes the audio device and creates sources.
 *
 * @warning:
 *
 * @return TRUE if initialization was successful, FALSE otherwise
 */
bool FALAudioDevice::InitializeHardware( void )
{
	// Make sure no interface classes contain any garbage
	Effects = NULL;
	DLLHandle = NULL;

	// Default to sensible channel count.
	if( MaxChannels < 1 )
	{
		MaxChannels = 32;
	}
	// Load ogg and vorbis dlls if they haven't been loaded yet
	//LoadVorbisLibraries();

	// Open device
	HardwareDevice = alcOpenDevice(nullptr);
	if( !HardwareDevice )
	{
		UE_LOG(LogALAudio, Log, TEXT( "ALAudio: no OpenAL devices found." ) );
		return  false  ;
	}

	// Display the audio device that was actually opened
	const ALCchar* OpenedDeviceName = alcGetString( HardwareDevice, ALC_DEVICE_SPECIFIER );
	UE_LOG(LogALAudio, Log, TEXT("ALAudio device opened : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(OpenedDeviceName)).Get());

	// Create a context
	int Caps[] =
	{
		ALC_FREQUENCY, 44100,
		ALC_STEREO_SOURCES, 4,
		0, 0
	};
#if PLATFORM_HTML5_WIN32 || PLATFORM_LINUX
	SoundContext = alcCreateContext( HardwareDevice, Caps );
#elif PLATFORM_HTML5
	SoundContext = alcCreateContext( HardwareDevice, 0 );
#endif

	if( !SoundContext )
	{
		return false ;
	}

	alcMakeContextCurrent(SoundContext);

	// Make sure everything happened correctly
	if( alError( TEXT( "Init" ) ) )
	{
		UE_LOG(LogALAudio, Warning, TEXT("ALAudio: alcMakeContextCurrent failed."));
		return false ;
	}

	UE_LOG(LogALAudio, Log, TEXT("AL_VENDOR      : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VENDOR))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_RENDERER    : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_RENDERER))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_VERSION     : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VERSION))).Get());
	UE_LOG(LogALAudio, Log, TEXT("AL_EXTENSIONS  : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_EXTENSIONS))).Get());

	// Get the enums for multichannel support
#if !PLATFORM_HTML5
	Surround40Format = alGetEnumValue( "AL_FORMAT_QUAD16" );
	Surround51Format = alGetEnumValue( "AL_FORMAT_51CHN16" );
	Surround61Format = alGetEnumValue( "AL_FORMAT_61CHN16" );
	Surround71Format = alGetEnumValue( "AL_FORMAT_71CHN16" );
#endif
	// Initialize channels.
	alError( TEXT( "Emptying error stack" ), 0 );
	for( int i = 0; i < (( MaxChannels >  MAX_AUDIOCHANNELS ) ? MAX_AUDIOCHANNELS : MaxChannels); i++ )
	{
		ALuint SourceId;
		alGenSources( 1, &SourceId );
		if( !alError( TEXT( "Init (creating sources)" ), 0 ) )
		{
			FALSoundSource* Source = new FALSoundSource( this );
			Source->SourceId = SourceId;
			Sources.Add( Source );
			FreeSources.Add( Source );
		}
		else
		{
			break;
		}
	}

	if( Sources.Num() < 1 )
	{
		UE_LOG(LogALAudio, Warning, TEXT("ALAudio: couldn't allocate any sources"));
		return false ;
	}

	// Update MaxChannels in case we couldn't create enough sources.
	MaxChannels = Sources.Num();
	UE_LOG(LogALAudio, Verbose, TEXT("ALAudioDevice: Allocated %i sources"), MaxChannels);

	// Use our own distance model.
	alDistanceModel( AL_NONE );

	// Set up a default (nop) effects manager
	Effects = new FAudioEffectsManager( this );

	return true ;
}
Beispiel #30
0
ALenum audio_output::get_al_format(const audio_blob &blob)
{
    ALenum format = 0;
    if (blob.sample_format == audio_blob::u8)
    {
        if (blob.channels == 1)
        {
            format = AL_FORMAT_MONO8;
        }
        else if (blob.channels == 2)
        {
            format = AL_FORMAT_STEREO8;
        }
        else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
        {
            if (blob.channels == 4)
            {
                format = alGetEnumValue("AL_FORMAT_QUAD8");
            }
            else if (blob.channels == 6)
            {
                format = alGetEnumValue("AL_FORMAT_51CHN8");
            }
            else if (blob.channels == 7)
            {
                format = alGetEnumValue("AL_FORMAT_71CHN8");
            }
            else if (blob.channels == 8)
            {
                format = alGetEnumValue("AL_FORMAT_81CHN8");
            }
        }
    }
    else if (blob.sample_format == audio_blob::s16)
    {
        if (blob.channels == 1)
        {
            format = AL_FORMAT_MONO16;
        }
        else if (blob.channels == 2)
        {
            format = AL_FORMAT_STEREO16;
        }
        else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
        {
            if (blob.channels == 4)
            {
                format = alGetEnumValue("AL_FORMAT_QUAD16");
            }
            else if (blob.channels == 6)
            {
                format = alGetEnumValue("AL_FORMAT_51CHN16");
            }
            else if (blob.channels == 7)
            {
                format = alGetEnumValue("AL_FORMAT_61CHN16");
            }
            else if (blob.channels == 8)
            {
                format = alGetEnumValue("AL_FORMAT_71CHN16");
            }
        }
    }
    else if (blob.sample_format == audio_blob::f32)
    {
        if (alIsExtensionPresent("AL_EXT_float32"))
        {
            if (blob.channels == 1)
            {
                format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
            }
            else if (blob.channels == 2)
            {
                format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
            }
            else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
            {
                if (blob.channels == 4)
                {
                    format = alGetEnumValue("AL_FORMAT_QUAD32");
                }
                else if (blob.channels == 6)
                {
                    format = alGetEnumValue("AL_FORMAT_51CHN32");
                }
                else if (blob.channels == 7)
                {
                    format = alGetEnumValue("AL_FORMAT_61CHN32");
                }
                else if (blob.channels == 8)
                {
                    format = alGetEnumValue("AL_FORMAT_71CHN32");
                }
            }
        }
    }
    else if (blob.sample_format == audio_blob::d64)
    {
        if (alIsExtensionPresent("AL_EXT_double"))
        {
            if (blob.channels == 1)
            {
                format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE_EXT");
            }
            else if (blob.channels == 2)
            {
                format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE_EXT");
            }
        }
    }
    if (format == 0)
    {
        throw exc(str::asprintf(_("No OpenAL format available for "
                        "audio data format %s."), blob.format_name().c_str()));
    }
    return format;
}