2a227085fc
LMMS is a music production program. This includes the creation of melodies and beats, the synthesis and mixing of sounds, and arrangement of samples. You can have fun with your MIDI keyboard and much more. Features: * Song Editor for composing songs * A Beat+Bassline Editor for creating beats and basslines * An easy to use Piano Roll for editing patterns and melodies * An FX mixer with 64 FX channels and arbitrary number of effects allow unlimited mixing possibilities * Many powerful instrument and effects plugins out of the box * Full user defined track based automation and computer controlled automation sources * Compatible with many standards such as SoundFont2, LADSPA, and full MIDI support * Import of MIDI and FLP (Frootyloops Project) files import requested by armani@, some midi bits improved by ratchov@, reviewed by ratchov@ and stsp@ "why isn't that imported yet" from several
208 lines
3.8 KiB
C++
208 lines
3.8 KiB
C++
#ifndef SINGLE_SOURCE_COMPILE
|
|
|
|
/* license */
|
|
|
|
#include "AudioSndio.h"
|
|
|
|
#ifdef LMMS_HAVE_SNDIO
|
|
|
|
#include <QtCore/QFileInfo>
|
|
#include <QtGui/QLabel>
|
|
#include <QtGui/QLineEdit>
|
|
|
|
#include "endian_handling.h"
|
|
#include "lcd_spinbox.h"
|
|
#include "engine.h"
|
|
#include "gui_templates.h"
|
|
#include "templates.h"
|
|
|
|
#ifdef LMMS_HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef LMMS_HAVE_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#include "config_mgr.h"
|
|
|
|
|
|
|
|
AudioSndio::AudioSndio(bool & _success_ful, mixer * _mixer) :
|
|
AudioDevice( tLimit<ch_cnt_t>(
|
|
configManager::inst()->value( "audiosndio", "channels" ).toInt(),
|
|
DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer )
|
|
{
|
|
_success_ful = FALSE;
|
|
|
|
QString dev = configManager::inst()->value( "audiosndio", "device" );
|
|
|
|
if (dev == "")
|
|
{
|
|
m_hdl = sio_open( NULL, SIO_PLAY, 0 );
|
|
}
|
|
else
|
|
{
|
|
m_hdl = sio_open( dev.toAscii().data(), SIO_PLAY, 0 );
|
|
}
|
|
|
|
if( m_hdl == NULL )
|
|
{
|
|
printf( "sndio: failed opening audio-device\n" );
|
|
return;
|
|
}
|
|
|
|
sio_initpar(&m_par);
|
|
|
|
m_par.pchan = channels();
|
|
m_par.bits = 16;
|
|
m_par.le = SIO_LE_NATIVE;
|
|
m_par.rate = sampleRate();
|
|
m_par.round = getMixer()->framesPerPeriod();
|
|
m_par.appbufsz = m_par.round * 2;
|
|
|
|
struct sio_par reqpar = m_par;
|
|
|
|
if (!sio_setpar(m_hdl, &m_par))
|
|
{
|
|
printf( "sndio: sio_setpar failed\n" );
|
|
return;
|
|
}
|
|
if (!sio_getpar(m_hdl, &m_par))
|
|
{
|
|
printf( "sndio: sio_getpar failed\n" );
|
|
return;
|
|
}
|
|
|
|
if (reqpar.pchan != m_par.pchan ||
|
|
reqpar.bits != m_par.bits ||
|
|
reqpar.le != m_par.le ||
|
|
(abs(reqpar.rate - m_par.rate) * 100)/reqpar.rate > 2)
|
|
{
|
|
printf( "sndio: returned params not as requested\n" );
|
|
return;
|
|
}
|
|
|
|
if (!sio_start(m_hdl))
|
|
{
|
|
printf( "sndio: sio_start failed\n" );
|
|
return;
|
|
}
|
|
|
|
_success_ful = TRUE;
|
|
}
|
|
|
|
|
|
AudioSndio::~AudioSndio()
|
|
{
|
|
stopProcessing();
|
|
if (m_hdl != NULL)
|
|
{
|
|
sio_close( m_hdl );
|
|
m_hdl = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void AudioSndio::startProcessing( void )
|
|
{
|
|
if( !isRunning() )
|
|
{
|
|
start( QThread::HighPriority );
|
|
}
|
|
}
|
|
|
|
|
|
void AudioSndio::stopProcessing( void )
|
|
{
|
|
if( isRunning() )
|
|
{
|
|
wait( 1000 );
|
|
terminate();
|
|
}
|
|
}
|
|
|
|
|
|
void AudioSndio::applyQualitySettings( void )
|
|
{
|
|
if( hqAudio() )
|
|
{
|
|
setSampleRate( engine::getMixer()->processingSampleRate() );
|
|
|
|
/* change sample rate to sampleRate() */
|
|
}
|
|
|
|
AudioDevice::applyQualitySettings();
|
|
}
|
|
|
|
|
|
void AudioSndio::run( void )
|
|
{
|
|
surroundSampleFrame * temp =
|
|
new surroundSampleFrame[getMixer()->framesPerPeriod()];
|
|
int_sample_t * outbuf =
|
|
new int_sample_t[getMixer()->framesPerPeriod() * channels()];
|
|
|
|
while( TRUE )
|
|
{
|
|
const fpp_t frames = getNextBuffer( temp );
|
|
if( !frames )
|
|
{
|
|
break;
|
|
}
|
|
|
|
uint bytes = convertToS16( temp, frames,
|
|
getMixer()->masterGain(), outbuf, FALSE );
|
|
if( sio_write( m_hdl, outbuf, bytes ) != bytes )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete[] temp;
|
|
delete[] outbuf;
|
|
}
|
|
|
|
|
|
AudioSndio::setupWidget::setupWidget( QWidget * _parent ) :
|
|
AudioDevice::setupWidget( AudioSndio::name(), _parent )
|
|
{
|
|
m_device = new QLineEdit( "", this );
|
|
m_device->setGeometry( 10, 20, 160, 20 );
|
|
|
|
QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this );
|
|
dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) );
|
|
dev_lbl->setGeometry( 10, 40, 160, 10 );
|
|
|
|
lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ );
|
|
m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS );
|
|
m->setStep( 2 );
|
|
m->setValue( configManager::inst()->value( "audiosndio",
|
|
"channels" ).toInt() );
|
|
|
|
m_channels = new lcdSpinBox( 1, this );
|
|
m_channels->setModel( m );
|
|
m_channels->setLabel( tr( "CHANNELS" ) );
|
|
m_channels->move( 180, 20 );
|
|
|
|
}
|
|
|
|
|
|
AudioSndio::setupWidget::~setupWidget()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void AudioSndio::setupWidget::saveSettings( void )
|
|
{
|
|
configManager::inst()->setValue( "audiosndio", "device",
|
|
m_device->text() );
|
|
configManager::inst()->setValue( "audiosndio", "channels",
|
|
QString::number( m_channels->value<int>() ) );
|
|
}
|
|
|
|
|
|
#endif /* LMMS_HAVE_SNDIO */
|
|
|
|
#endif /* SINGLE_SOURCE_COMPILE */
|