2
* AudioJack.cpp - support for JACK-transport
4
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public
19
* License along with this program (see COPYING); if not, write to the
20
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
* Boston, MA 02110-1301 USA.
25
#include "AudioJack.h"
29
#include <QtGui/QLineEdit>
30
#include <QtGui/QLabel>
31
#include <QtGui/QMessageBox>
37
#include "templates.h"
38
#include "gui_templates.h"
39
#include "config_mgr.h"
40
#include "lcd_spinbox.h"
41
#include "AudioPort.h"
42
#include "MainWindow.h"
47
AudioJack::AudioJack( bool & _success_ful, mixer * _mixer ) :
48
AudioDevice( tLimit<int>( configManager::inst()->value(
49
"audiojack", "channels" ).toInt(),
50
DEFAULT_CHANNELS, SURROUND_CHANNELS ),
55
m_tempOutBufs( new jack_default_audio_sample_t *[channels()] ),
56
m_outBuf( new surroundSampleFrame[getMixer()->framesPerPeriod()] ),
57
m_framesDoneInCurBuf( 0 ),
58
m_framesToDoInCurBuf( 0 )
60
_success_ful = initJackClient();
63
m_stopSemaphore.acquire();
65
connect( this, SIGNAL( zombified() ),
66
this, SLOT( restartAfterZombified() ),
67
Qt::QueuedConnection );
75
AudioJack::~AudioJack()
77
m_stopSemaphore.release();
79
#ifdef AUDIO_PORT_SUPPORT
80
while( m_portMap.size() )
82
unregisterPort( m_portMap.begin().key() );
86
if( m_client != NULL )
90
jack_deactivate( m_client );
92
jack_client_close( m_client );
95
delete[] m_tempOutBufs;
103
void AudioJack::restartAfterZombified()
105
if( initJackClient() )
109
QMessageBox::information( engine::mainWindow(),
110
tr( "JACK client restarted" ),
111
tr( "LMMS was kicked by JACK for some reason. "
112
"Therefore the JACK backend of LMMS has been "
113
"restarted. You will have to make manual "
114
"connections again." ) );
118
QMessageBox::information( engine::mainWindow(),
119
tr( "JACK server down" ),
120
tr( "The JACK server seems to have been shutdown "
121
"and starting a new instance failed. "
122
"Therefore LMMS is unable to proceed. "
123
"You should save your project and restart "
124
"JACK and LMMS." ) );
132
bool AudioJack::initJackClient()
134
QString clientName = configManager::inst()->value( "audiojack",
136
if( clientName.isEmpty() )
141
const char * serverName = NULL;
142
jack_status_t status;
143
m_client = jack_client_open( clientName.toAscii().constData(),
144
JackNullOption, &status,
146
if( m_client == NULL )
148
printf( "jack_client_open() failed, status 0x%2.0x\n", status );
149
if( status & JackServerFailed )
151
printf( "Could not connect to JACK server.\n" );
155
if( status & JackNameNotUnique )
157
printf( "there's already a client with name '%s', so unique "
158
"name '%s' was assigned\n", clientName.
159
toAscii().constData(),
160
jack_get_client_name( m_client ) );
163
// set process-callback
164
jack_set_process_callback( m_client, staticProcessCallback, this );
166
// set shutdown-callback
167
jack_on_shutdown( m_client, shutdownCallback, this );
171
if( jack_get_sample_rate( m_client ) != sampleRate() )
173
setSampleRate( jack_get_sample_rate( m_client ) );
176
for( ch_cnt_t ch = 0; ch < channels(); ++ch )
178
QString name = QString( "master out " ) +
179
( ( ch % 2 ) ? "R" : "L" ) +
180
QString::number( ch / 2 + 1 );
181
m_outputPorts.push_back( jack_port_register( m_client,
182
name.toAscii().constData(),
183
JACK_DEFAULT_AUDIO_TYPE,
184
JackPortIsOutput, 0 ) );
185
if( m_outputPorts.back() == NULL )
187
printf( "no more JACK-ports available!\n" );
198
void AudioJack::startProcessing()
202
if( m_active || m_client == NULL )
207
if( jack_activate( m_client ) )
209
printf( "cannot activate client\n" );
216
// try to sync JACK's and LMMS's buffer-size
217
// jack_set_buffer_size( m_client, getMixer()->framesPerPeriod() );
221
const char * * ports = jack_get_ports( m_client, NULL, NULL,
226
printf( "no physical playback ports. you'll have to do "
227
"connections at your own!\n" );
231
for( ch_cnt_t ch = 0; ch < channels(); ++ch )
233
if( jack_connect( m_client, jack_port_name(
237
printf( "cannot connect output ports. you'll "
238
"have to do connections at your own!\n"
250
void AudioJack::stopProcessing()
252
m_stopSemaphore.acquire();
258
void AudioJack::applyQualitySettings()
262
setSampleRate( engine::getMixer()->processingSampleRate() );
264
if( jack_get_sample_rate( m_client ) != sampleRate() )
266
setSampleRate( jack_get_sample_rate( m_client ) );
270
AudioDevice::applyQualitySettings();
276
void AudioJack::registerPort( AudioPort * _port )
278
#ifdef AUDIO_PORT_SUPPORT
279
// make sure, port is not already registered
280
unregisterPort( _port );
281
const QString name[2] = { _port->name() + " L",
282
_port->name() + " R" } ;
284
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
286
m_portMap[_port].ports[ch] = jack_port_register( m_client,
287
name[ch].toAscii().constData(),
288
JACK_DEFAULT_AUDIO_TYPE,
289
JackPortIsOutput, 0 );
297
void AudioJack::unregisterPort( AudioPort * _port )
299
#ifdef AUDIO_PORT_SUPPORT
300
if( m_portMap.contains( _port ) )
302
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
304
if( m_portMap[_port].ports[ch] != NULL )
306
jack_port_unregister( m_client,
307
m_portMap[_port].ports[ch] );
310
m_portMap.erase( m_portMap.find( _port ) );
318
void AudioJack::renamePort( AudioPort * _port )
320
#ifdef AUDIO_PORT_SUPPORT
321
if( m_portMap.contains( _port ) )
323
const QString name[2] = { _port->name() + " L",
324
_port->name() + " R" };
325
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
327
jack_port_set_name( m_portMap[_port].ports[ch],
328
name[ch].toAscii().constData() );
337
int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata )
339
for( int c = 0; c < channels(); ++c )
342
(jack_default_audio_sample_t *) jack_port_get_buffer(
343
m_outputPorts[c], _nframes );
346
#ifdef AUDIO_PORT_SUPPORT
347
const Uint32 frames = qMin<Uint32>( _nframes,
348
getMixer()->framesPerPeriod() );
349
for( jackPortMap::iterator it = m_portMap.begin();
350
it != m_portMap.end(); ++it )
352
for( ch_cnt_t ch = 0; ch < channels(); ++ch )
354
if( it.data().ports[ch] == NULL )
358
jack_default_audio_sample_t * buf =
359
(jack_default_audio_sample_t *) jack_port_get_buffer(
362
for( Uint32 frame = 0; frame < frames; ++frame )
364
buf[frame] = it.key()->firstBuffer()[frame][ch];
370
jack_nframes_t done = 0;
371
while( done < _nframes && m_stopped == false )
373
jack_nframes_t todo = qMin<jack_nframes_t>(
375
m_framesToDoInCurBuf -
376
m_framesDoneInCurBuf );
377
const float gain = getMixer()->masterGain();
378
for( int c = 0; c < channels(); ++c )
380
jack_default_audio_sample_t * o = m_tempOutBufs[c];
381
for( jack_nframes_t frame = 0; frame < todo; ++frame )
383
o[done+frame] = m_outBuf[m_framesDoneInCurBuf+frame][c] * gain;
387
m_framesDoneInCurBuf += todo;
388
if( m_framesDoneInCurBuf == m_framesToDoInCurBuf )
390
m_framesToDoInCurBuf = getNextBuffer( m_outBuf );
391
if( !m_framesToDoInCurBuf )
394
m_stopSemaphore.release();
396
m_framesDoneInCurBuf = 0;
400
if( m_stopped == true )
402
for( int c = 0; c < channels(); ++c )
404
jack_default_audio_sample_t * b = m_tempOutBufs[c] + done;
405
memset( b, 0, sizeof( *b ) * ( _nframes - done ) );
415
int AudioJack::staticProcessCallback( jack_nframes_t _nframes, void * _udata )
417
return static_cast<AudioJack *>( _udata )->
418
processCallback( _nframes, _udata );
424
void AudioJack::shutdownCallback( void * _udata )
426
AudioJack * _this = static_cast<AudioJack *>( _udata );
427
_this->m_client = NULL;
435
AudioJack::setupWidget::setupWidget( QWidget * _parent ) :
436
AudioDevice::setupWidget( AudioJack::name(), _parent )
438
QString cn = configManager::inst()->value( "audiojack", "clientname" );
443
m_clientName = new QLineEdit( cn, this );
444
m_clientName->setGeometry( 10, 20, 160, 20 );
446
QLabel * cn_lbl = new QLabel( tr( "CLIENT-NAME" ), this );
447
cn_lbl->setFont( pointSize<6>( cn_lbl->font() ) );
448
cn_lbl->setGeometry( 10, 40, 160, 10 );
450
lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ );
451
m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS );
453
m->setValue( configManager::inst()->value( "audiojack",
454
"channels" ).toInt() );
456
m_channels = new lcdSpinBox( 1, this );
457
m_channels->setModel( m );
458
m_channels->setLabel( tr( "CHANNELS" ) );
459
m_channels->move( 180, 20 );
466
AudioJack::setupWidget::~setupWidget()
473
void AudioJack::setupWidget::saveSettings()
475
configManager::inst()->setValue( "audiojack", "clientname",
476
m_clientName->text() );
477
configManager::inst()->setValue( "audiojack", "channels",
478
QString::number( m_channels->value<int>() ) );
483
#include "moc_AudioJack.cxx"