AudioSdl: Add support for full SDL2 with float samples and recording
(with backward compatibility for SDL1).
This commit is contained in:
@@ -78,17 +78,35 @@ private:
|
||||
static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len );
|
||||
void sdlAudioCallback( Uint8 * _buf, int _len );
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
static void sdlInputAudioCallback( void * _udata, Uint8 * _buf, int _len );
|
||||
void sdlInputAudioCallback( Uint8 * _buf, int _len );
|
||||
#endif
|
||||
|
||||
SDL_AudioSpec m_audioHandle;
|
||||
|
||||
surroundSampleFrame * m_outBuf;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
uint64_t m_currentBufferFramePos;
|
||||
uint64_t m_currentBufferFramesCount;
|
||||
#else
|
||||
Uint8 * m_convertedBuf;
|
||||
int m_convertedBufPos;
|
||||
int m_convertedBufSize;
|
||||
bool m_outConvertEndian;
|
||||
#endif
|
||||
|
||||
bool m_convertEndian;
|
||||
|
||||
bool m_stopped;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
SDL_AudioDeviceID m_outputDevice;
|
||||
|
||||
SDL_AudioSpec m_inputAudioHandle;
|
||||
SDL_AudioDeviceID m_inputDevice;
|
||||
#endif
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,19 +34,21 @@
|
||||
#include "gui_templates.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
|
||||
AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) :
|
||||
AudioDevice( DEFAULT_CHANNELS, _mixer ),
|
||||
m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ),
|
||||
m_convertedBufPos( 0 ),
|
||||
m_convertEndian( false )
|
||||
m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] )
|
||||
{
|
||||
_success_ful = false;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
m_currentBufferFramesCount = 0;
|
||||
m_currentBufferFramePos = 0;
|
||||
#else
|
||||
m_convertedBufSize = mixer()->framesPerPeriod() * channels()
|
||||
* sizeof( int_sample_t );
|
||||
m_convertedBufPos = 0;
|
||||
m_convertedBuf = new Uint8[m_convertedBufSize];
|
||||
|
||||
#endif
|
||||
|
||||
if( SDL_Init( SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE ) < 0 )
|
||||
{
|
||||
@@ -55,9 +57,15 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) :
|
||||
}
|
||||
|
||||
m_audioHandle.freq = sampleRate();
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
m_audioHandle.format = AUDIO_F32SYS; // we want it in byte-order
|
||||
// of system, so we don't have
|
||||
// to convert the buffers
|
||||
#else
|
||||
m_audioHandle.format = AUDIO_S16SYS; // we want it in byte-order
|
||||
// of system, so we don't have
|
||||
// to convert the buffers
|
||||
#endif
|
||||
m_audioHandle.channels = channels();
|
||||
m_audioHandle.samples = qMax( 1024, mixer()->framesPerPeriod()*2 );
|
||||
|
||||
@@ -66,15 +74,47 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) :
|
||||
|
||||
SDL_AudioSpec actual;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
m_outputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 2),
|
||||
0,
|
||||
&m_audioHandle,
|
||||
&actual,
|
||||
0);
|
||||
if (m_outputDevice == 0) {
|
||||
qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() );
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// open the audio device, forcing the desired format
|
||||
if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 )
|
||||
{
|
||||
qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() );
|
||||
return;
|
||||
}
|
||||
m_convertEndian = ( m_audioHandle.format != actual.format );
|
||||
|
||||
m_outConvertEndian = ( m_audioHandle.format != actual.format );
|
||||
#endif
|
||||
|
||||
|
||||
_success_ful = true;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
m_inputAudioHandle = m_audioHandle;
|
||||
m_inputAudioHandle.callback = sdlInputAudioCallback;
|
||||
|
||||
m_inputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 1),
|
||||
1,
|
||||
&m_inputAudioHandle,
|
||||
&actual,
|
||||
0);
|
||||
if (m_inputDevice != 0) {
|
||||
m_supportsCapture = true;
|
||||
} else {
|
||||
m_supportsCapture = false;
|
||||
qWarning ( "Couldn't open SDL capture device: %s\n", SDL_GetError ());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +124,18 @@ AudioSdl::~AudioSdl()
|
||||
{
|
||||
stopProcessing();
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
if (m_inputDevice != 0)
|
||||
SDL_CloseAudioDevice(m_inputDevice);
|
||||
if (m_outputDevice != 0)
|
||||
SDL_CloseAudioDevice(m_outputDevice);
|
||||
#else
|
||||
SDL_CloseAudio();
|
||||
SDL_Quit();
|
||||
delete[] m_convertedBuf;
|
||||
#endif
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
delete[] m_outBuf;
|
||||
}
|
||||
|
||||
@@ -97,7 +146,12 @@ void AudioSdl::startProcessing()
|
||||
{
|
||||
m_stopped = false;
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
SDL_PauseAudioDevice (m_outputDevice, 0);
|
||||
SDL_PauseAudioDevice (m_inputDevice, 0);
|
||||
#else
|
||||
SDL_PauseAudio( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -107,10 +161,24 @@ void AudioSdl::stopProcessing()
|
||||
{
|
||||
if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING )
|
||||
{
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
SDL_LockAudioDevice (m_inputDevice);
|
||||
SDL_LockAudioDevice (m_outputDevice);
|
||||
|
||||
m_stopped = true;
|
||||
|
||||
SDL_PauseAudioDevice (m_inputDevice, 1);
|
||||
SDL_PauseAudioDevice (m_outputDevice, 1);
|
||||
|
||||
SDL_UnlockAudioDevice (m_inputDevice);
|
||||
SDL_UnlockAudioDevice (m_outputDevice);
|
||||
#else
|
||||
SDL_LockAudio();
|
||||
m_stopped = true;
|
||||
SDL_PauseAudio( 1 );
|
||||
SDL_UnlockAudio();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +187,8 @@ void AudioSdl::stopProcessing()
|
||||
|
||||
void AudioSdl::applyQualitySettings()
|
||||
{
|
||||
// Better than if (0)
|
||||
#if 0
|
||||
if( 0 )//hqAudio() )
|
||||
{
|
||||
SDL_CloseAudio();
|
||||
@@ -135,6 +205,7 @@ void AudioSdl::applyQualitySettings()
|
||||
qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
AudioDevice::applyQualitySettings();
|
||||
}
|
||||
@@ -160,6 +231,41 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len )
|
||||
return;
|
||||
}
|
||||
|
||||
// SDL2: process float samples
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
while( _len )
|
||||
{
|
||||
if( m_currentBufferFramePos == 0 )
|
||||
{
|
||||
// frames depend on the sample rate
|
||||
const fpp_t frames = getNextBuffer( m_outBuf );
|
||||
if( !frames )
|
||||
{
|
||||
memset( _buf, 0, _len );
|
||||
return;
|
||||
}
|
||||
m_currentBufferFramesCount = frames;
|
||||
|
||||
}
|
||||
const uint min_frames_count = qMin( _len/sizeof(sampleFrame),
|
||||
m_currentBufferFramesCount
|
||||
- m_currentBufferFramePos );
|
||||
|
||||
const float gain = mixer()->masterGain();
|
||||
for (uint f = 0; f < min_frames_count; f++)
|
||||
{
|
||||
(m_outBuf + m_currentBufferFramePos)[f][0] *= gain;
|
||||
(m_outBuf + m_currentBufferFramePos)[f][1] *= gain;
|
||||
}
|
||||
|
||||
memcpy( _buf, m_outBuf + m_currentBufferFramePos, min_frames_count*sizeof(sampleFrame) );
|
||||
_buf += min_frames_count*sizeof(sampleFrame);
|
||||
_len -= min_frames_count*sizeof(sampleFrame);
|
||||
m_currentBufferFramePos += min_frames_count;
|
||||
|
||||
m_currentBufferFramePos %= m_currentBufferFramesCount;
|
||||
}
|
||||
#else
|
||||
while( _len )
|
||||
{
|
||||
if( m_convertedBufPos == 0 )
|
||||
@@ -177,7 +283,7 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len )
|
||||
convertToS16( m_outBuf, frames,
|
||||
mixer()->masterGain(),
|
||||
(int_sample_t *)m_convertedBuf,
|
||||
m_convertEndian );
|
||||
m_outConvertEndian );
|
||||
}
|
||||
const int min_len = qMin( _len, m_convertedBufSize
|
||||
- m_convertedBufPos );
|
||||
@@ -187,10 +293,26 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len )
|
||||
m_convertedBufPos += min_len;
|
||||
m_convertedBufPos %= m_convertedBufSize;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LMMS_HAVE_SDL2
|
||||
|
||||
void AudioSdl::sdlInputAudioCallback(void *_udata, Uint8 *_buf, int _len) {
|
||||
AudioSdl * _this = static_cast<AudioSdl *>( _udata );
|
||||
|
||||
_this->sdlInputAudioCallback( _buf, _len );
|
||||
}
|
||||
|
||||
void AudioSdl::sdlInputAudioCallback(Uint8 *_buf, int _len) {
|
||||
sampleFrame *samples_buffer = (sampleFrame *) _buf;
|
||||
fpp_t frames = _len / sizeof ( sampleFrame );
|
||||
|
||||
mixer()->pushInputFrames (samples_buffer, frames,
|
||||
true /* applyGain */);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AudioSdl::setupWidget::setupWidget( QWidget * _parent ) :
|
||||
AudioDeviceSetupWidget( AudioSdl::name(), _parent )
|
||||
|
||||
Reference in New Issue
Block a user