Audaspace: porting changes from upstream.
- Silence some warnings. - Fix: Python API memory leak. - Fix for T54490: VSE breaks when I insert or remove headphones
This commit is contained in:
parent
16fac2149b
commit
d3e856cdfc
|
@ -212,7 +212,7 @@ AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_
|
|||
std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, specs, static_cast<Container>(container), static_cast<Codec>(codec), bitrate);
|
||||
FileWriter::writeReader(reader, writer, 0, buffersize);
|
||||
}
|
||||
catch(Exception& e)
|
||||
catch(Exception&)
|
||||
{
|
||||
return "An exception occured while writing.";
|
||||
}
|
||||
|
|
|
@ -140,8 +140,6 @@ Sound_data(Sound* self)
|
|||
|
||||
std::memcpy(data, buffer->getBuffer(), buffer->getSize());
|
||||
|
||||
Py_INCREF(array);
|
||||
|
||||
return reinterpret_cast<PyObject*>(array);
|
||||
}
|
||||
|
||||
|
|
|
@ -261,6 +261,8 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
|
|||
case CHANNELS_SURROUND71:
|
||||
channel_layout = AV_CH_LAYOUT_7POINT1;
|
||||
break;
|
||||
default:
|
||||
AUD_THROW(FileException, "File couldn't be written, channel layout not supported.");
|
||||
}
|
||||
|
||||
try
|
||||
|
|
|
@ -61,10 +61,58 @@ bool OpenALDevice::OpenALHandle::pause(bool keep)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool OpenALDevice::OpenALHandle::reinitialize()
|
||||
{
|
||||
DeviceSpecs specs = m_device->m_specs;
|
||||
specs.specs = m_reader->getSpecs();
|
||||
|
||||
ALenum format;
|
||||
|
||||
if(!m_device->getFormat(format, specs.specs))
|
||||
return true;
|
||||
|
||||
m_format = format;
|
||||
|
||||
// OpenAL playback code
|
||||
alGenBuffers(CYCLE_BUFFERS, m_buffers);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
return true;
|
||||
|
||||
m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
|
||||
int length;
|
||||
bool eos;
|
||||
|
||||
for(m_current = 0; m_current < CYCLE_BUFFERS; m_current++)
|
||||
{
|
||||
length = m_device->m_buffersize;
|
||||
m_reader->read(length, eos, m_device->m_buffer.getBuffer());
|
||||
|
||||
if(length == 0)
|
||||
break;
|
||||
|
||||
alBufferData(m_buffers[m_current], m_format, m_device->m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
|
||||
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
return true;
|
||||
}
|
||||
|
||||
alGenSources(1, &m_source);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
return true;
|
||||
|
||||
alSourceQueueBuffers(m_source, m_current, m_buffers);
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
return true;
|
||||
|
||||
alSourcei(m_source, AL_SOURCE_RELATIVE, m_relative);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenALDevice::OpenALHandle::OpenALHandle(OpenALDevice* device, ALenum format, std::shared_ptr<IReader> reader, bool keep) :
|
||||
m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format),
|
||||
m_eos(false), m_loopcount(0), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING),
|
||||
m_device(device)
|
||||
m_relative(1), m_device(device)
|
||||
{
|
||||
DeviceSpecs specs = m_device->m_specs;
|
||||
specs.specs = m_reader->getSpecs();
|
||||
|
@ -162,6 +210,9 @@ bool OpenALDevice::OpenALHandle::stop()
|
|||
if(!m_status)
|
||||
return false;
|
||||
|
||||
if(m_stop)
|
||||
m_stop(m_stop_data);
|
||||
|
||||
m_status = STATUS_INVALID;
|
||||
|
||||
alDeleteSources(1, &m_source);
|
||||
|
@ -525,8 +576,6 @@ bool OpenALDevice::OpenALHandle::setOrientation(const Quaternion& orientation)
|
|||
|
||||
bool OpenALDevice::OpenALHandle::isRelative()
|
||||
{
|
||||
int result;
|
||||
|
||||
if(!m_status)
|
||||
return false;
|
||||
|
||||
|
@ -535,9 +584,9 @@ bool OpenALDevice::OpenALHandle::isRelative()
|
|||
if(!m_status)
|
||||
return false;
|
||||
|
||||
alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
|
||||
alGetSourcei(m_source, AL_SOURCE_RELATIVE, &m_relative);
|
||||
|
||||
return result;
|
||||
return m_relative;
|
||||
}
|
||||
|
||||
bool OpenALDevice::OpenALHandle::setRelative(bool relative)
|
||||
|
@ -550,7 +599,9 @@ bool OpenALDevice::OpenALHandle::setRelative(bool relative)
|
|||
if(!m_status)
|
||||
return false;
|
||||
|
||||
alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
|
||||
m_relative = relative;
|
||||
|
||||
alSourcei(m_source, AL_SOURCE_RELATIVE, m_relative);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -852,6 +903,80 @@ void OpenALDevice::updateStreams()
|
|||
{
|
||||
lock();
|
||||
|
||||
if(m_checkDisconnect)
|
||||
{
|
||||
ALCint connected;
|
||||
alcGetIntegerv(m_device, alcGetEnumValue(m_device, "ALC_CONNECTED"), 1, &connected);
|
||||
|
||||
if(!connected)
|
||||
{
|
||||
// quit OpenAL
|
||||
alcMakeContextCurrent(nullptr);
|
||||
alcDestroyContext(m_context);
|
||||
alcCloseDevice(m_device);
|
||||
|
||||
// restart
|
||||
if(m_name.empty())
|
||||
m_device = alcOpenDevice(nullptr);
|
||||
else
|
||||
m_device = alcOpenDevice(m_name.c_str());
|
||||
|
||||
// if device opening failed, there's really nothing we can do
|
||||
if(m_device)
|
||||
{
|
||||
// at least try to set the frequency
|
||||
|
||||
ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 };
|
||||
ALCint* attributes = attribs;
|
||||
if(specs.rate == RATE_INVALID)
|
||||
attributes = nullptr;
|
||||
|
||||
m_context = alcCreateContext(m_device, attributes);
|
||||
alcMakeContextCurrent(m_context);
|
||||
|
||||
m_checkDisconnect = alcIsExtensionPresent(m_device, "ALC_EXT_disconnect");
|
||||
|
||||
alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
|
||||
|
||||
// check for specific formats and channel counts to be played back
|
||||
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
|
||||
specs.format = FORMAT_FLOAT32;
|
||||
else
|
||||
specs.format = FORMAT_S16;
|
||||
|
||||
// if the format of the device changed, all handles are invalidated
|
||||
// this is unlikely to happen though
|
||||
if(specs.format != m_specs.format)
|
||||
stopAll();
|
||||
|
||||
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
|
||||
|
||||
if((!m_useMC && specs.channels > CHANNELS_STEREO) ||
|
||||
specs.channels == CHANNELS_STEREO_LFE ||
|
||||
specs.channels == CHANNELS_SURROUND5)
|
||||
specs.channels = CHANNELS_STEREO;
|
||||
|
||||
alGetError();
|
||||
alcGetError(m_device);
|
||||
|
||||
m_specs = specs;
|
||||
|
||||
std::list<std::shared_ptr<OpenALHandle> > stopSounds;
|
||||
|
||||
for(auto& handle : m_playingSounds)
|
||||
if(handle->reinitialize())
|
||||
stopSounds.push_back(handle);
|
||||
|
||||
for(auto& handle : m_pausedSounds)
|
||||
if(handle->reinitialize())
|
||||
stopSounds.push_back(handle);
|
||||
|
||||
for(auto& sound : stopSounds)
|
||||
sound->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alcSuspendContext(m_context);
|
||||
cerr = alcGetError(m_device);
|
||||
if(cerr == ALC_NO_ERROR)
|
||||
|
@ -957,12 +1082,14 @@ void OpenALDevice::updateStreams()
|
|||
// if it really stopped
|
||||
if(sound->m_eos && info != AL_INITIAL)
|
||||
{
|
||||
if(sound->m_stop)
|
||||
sound->m_stop(sound->m_stop_data);
|
||||
|
||||
// pause or
|
||||
if(sound->m_keep)
|
||||
{
|
||||
if(sound->m_stop)
|
||||
sound->m_stop(sound->m_stop_data);
|
||||
|
||||
pauseSounds.push_back(sound);
|
||||
}
|
||||
// stop
|
||||
else
|
||||
stopSounds.push_back(sound);
|
||||
|
@ -1005,16 +1132,16 @@ void OpenALDevice::updateStreams()
|
|||
/******************************************************************************/
|
||||
|
||||
OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name) :
|
||||
m_playing(false), m_buffersize(buffersize)
|
||||
m_name(name), m_playing(false), m_buffersize(buffersize)
|
||||
{
|
||||
// cannot determine how many channels or which format OpenAL uses, but
|
||||
// it at least is able to play 16 bit stereo audio
|
||||
specs.format = FORMAT_S16;
|
||||
|
||||
if(name.empty())
|
||||
if(m_name.empty())
|
||||
m_device = alcOpenDevice(nullptr);
|
||||
else
|
||||
m_device = alcOpenDevice(name.c_str());
|
||||
m_device = alcOpenDevice(m_name.c_str());
|
||||
|
||||
if(!m_device)
|
||||
AUD_THROW(DeviceException, "The audio device couldn't be opened with OpenAL.");
|
||||
|
@ -1028,6 +1155,8 @@ OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name)
|
|||
m_context = alcCreateContext(m_device, attributes);
|
||||
alcMakeContextCurrent(m_context);
|
||||
|
||||
m_checkDisconnect = alcIsExtensionPresent(m_device, "ALC_EXT_disconnect");
|
||||
|
||||
alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
|
||||
|
||||
// check for specific formats and channel counts to be played back
|
||||
|
|
|
@ -95,11 +95,16 @@ private:
|
|||
/// Current status of the handle
|
||||
Status m_status;
|
||||
|
||||
/// Whether the source is relative or not.
|
||||
ALint m_relative;
|
||||
|
||||
/// Own device.
|
||||
OpenALDevice* m_device;
|
||||
|
||||
AUD_LOCAL bool pause(bool keep);
|
||||
|
||||
AUD_LOCAL bool reinitialize();
|
||||
|
||||
// delete copy constructor and operator=
|
||||
OpenALHandle(const OpenALHandle&) = delete;
|
||||
OpenALHandle& operator=(const OpenALHandle&) = delete;
|
||||
|
@ -173,11 +178,21 @@ private:
|
|||
*/
|
||||
DeviceSpecs m_specs;
|
||||
|
||||
/**
|
||||
* The device name.
|
||||
*/
|
||||
std::string m_name;
|
||||
|
||||
/**
|
||||
* Whether the device has the AL_EXT_MCFORMATS extension.
|
||||
*/
|
||||
bool m_useMC;
|
||||
|
||||
/**
|
||||
* Whether the ALC_EXT_disconnect extension is present and device disconnect should be checked repeatedly.
|
||||
*/
|
||||
bool m_checkDisconnect;
|
||||
|
||||
/**
|
||||
* The list of sounds that are currently playing.
|
||||
*/
|
||||
|
|
|
@ -296,72 +296,77 @@ const Channel* ChannelMapperReader::CHANNEL_MAPS[] =
|
|||
ChannelMapperReader::SURROUND71_MAP
|
||||
};
|
||||
|
||||
constexpr float deg2rad(double angle)
|
||||
{
|
||||
return float(angle * M_PI / 180.0);
|
||||
}
|
||||
|
||||
const float ChannelMapperReader::MONO_ANGLES[] =
|
||||
{
|
||||
0.0f * M_PI / 180.0f
|
||||
deg2rad(0.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::STEREO_ANGLES[] =
|
||||
{
|
||||
-90.0f * M_PI / 180.0f,
|
||||
90.0f * M_PI / 180.0f
|
||||
deg2rad(-90.0),
|
||||
deg2rad( 90.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::STEREO_LFE_ANGLES[] =
|
||||
{
|
||||
-90.0f * M_PI / 180.0f,
|
||||
90.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f
|
||||
deg2rad(-90.0),
|
||||
deg2rad( 90.0),
|
||||
deg2rad( 0.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::SURROUND4_ANGLES[] =
|
||||
{
|
||||
-45.0f * M_PI / 180.0f,
|
||||
45.0f * M_PI / 180.0f,
|
||||
-135.0f * M_PI / 180.0f,
|
||||
135.0f * M_PI / 180.0f
|
||||
deg2rad( -45.0),
|
||||
deg2rad( 45.0),
|
||||
deg2rad(-135.0),
|
||||
deg2rad( 135.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::SURROUND5_ANGLES[] =
|
||||
{
|
||||
-30.0f * M_PI / 180.0f,
|
||||
30.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
-110.0f * M_PI / 180.0f,
|
||||
110.0f * M_PI / 180.0f
|
||||
deg2rad( -30.0),
|
||||
deg2rad( 30.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad(-110.0),
|
||||
deg2rad( 110.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::SURROUND51_ANGLES[] =
|
||||
{
|
||||
-30.0f * M_PI / 180.0f,
|
||||
30.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
-110.0f * M_PI / 180.0f,
|
||||
110.0f * M_PI / 180.0f
|
||||
deg2rad( -30.0),
|
||||
deg2rad( 30.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad(-110.0),
|
||||
deg2rad( 110.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::SURROUND61_ANGLES[] =
|
||||
{
|
||||
-30.0f * M_PI / 180.0f,
|
||||
30.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
180.0f * M_PI / 180.0f,
|
||||
-110.0f * M_PI / 180.0f,
|
||||
110.0f * M_PI / 180.0f
|
||||
deg2rad( -30.0),
|
||||
deg2rad( 30.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad( 180.0),
|
||||
deg2rad(-110.0),
|
||||
deg2rad( 110.0)
|
||||
};
|
||||
|
||||
const float ChannelMapperReader::SURROUND71_ANGLES[] =
|
||||
{
|
||||
-30.0f * M_PI / 180.0f,
|
||||
30.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
0.0f * M_PI / 180.0f,
|
||||
-110.0f * M_PI / 180.0f,
|
||||
110.0f * M_PI / 180.0f,
|
||||
-150.0f * M_PI / 180.0f,
|
||||
150.0f * M_PI / 180.0f
|
||||
deg2rad( -30.0),
|
||||
deg2rad( 30.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad( 0.0),
|
||||
deg2rad(-110.0),
|
||||
deg2rad( 110.0),
|
||||
deg2rad(-150.0),
|
||||
deg2rad( 150.0)
|
||||
};
|
||||
|
||||
const float* ChannelMapperReader::CHANNEL_ANGLES[] =
|
||||
|
|
Loading…
Reference in New Issue