You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
408 lines
15 KiB
408 lines
15 KiB
/***************************************************************************
|
|
begin : Mon Jun 17 2002
|
|
copyright : (C) 2002 by Arnold Krille
|
|
email : arnold@arnoldarts.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; version 2 of the License. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "krecord.h"
|
|
#include "krecord_private.h"
|
|
|
|
#include "artsactions.h"
|
|
// VolumeControl
|
|
#include "artsmoduleseffects.h"
|
|
|
|
#include "krecfile.h"
|
|
#include "krecglobal.h"
|
|
#include "krecexport_template.h"
|
|
|
|
#include <arts/kaudioplaystream.h>
|
|
#include <arts/kaudiorecordstream.h>
|
|
#include <kfiledialog.h>
|
|
#include <kmessagebox.h>
|
|
#include <klocale.h>
|
|
#include <kdebug.h>
|
|
#include <kapplication.h>
|
|
#include <kaction.h>
|
|
#include <kconfig.h>
|
|
#include <tqlayout.h>
|
|
#include <tqtimer.h>
|
|
#include <ksettings/dialog.h>
|
|
#include <ktip.h>
|
|
|
|
KRecPrivate::KRecPrivate( KRecord* p, const char* n )
|
|
: TQObject( p,n )
|
|
, _confdlg( 0 )
|
|
, server( new KArtsServer( 0 ) )
|
|
, dispatcher( new KArtsDispatcher( 0 ) )
|
|
, m_playStream( new KAudioPlayStream( server, "KRec::Out", server ) )
|
|
, m_recStream( new KAudioRecordStream( server, "KRec::In", server ) )
|
|
, w( 0 )
|
|
, b_arts( true ), b_comp( true )
|
|
, _impl( p )
|
|
, mainwidget( new KRecMainWidget( p ) )
|
|
, _currentFile( 0 )
|
|
, _exportitem( 0 )
|
|
{
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
m_recStream->usePolling( false );
|
|
if( m_recStream->effectStack().isNull() )
|
|
kdFatal() << "Couldn't get Object 'StereoEffectStack' from KAudioRecordStream!!!" << endl;
|
|
volumecontrol = Arts::DynamicCast( server->server().createObject( "Arts::StereoVolumeControl" ) );
|
|
if( volumecontrol.isNull() )
|
|
kdFatal()<<"Couldn't create Object 'StereoVolumeControl' !!!"<<endl;
|
|
comp = Arts::DynamicCast( server->server().createObject( "Arts::Synth_STEREO_COMPRESSOR" ) );
|
|
if( comp.isNull() )
|
|
b_comp = false;
|
|
|
|
volumecontrol.start();
|
|
if( b_comp ) comp.start();
|
|
vc_id = m_recStream->effectStack().insertBottom( volumecontrol, "VolumeControl" );
|
|
if( b_comp ) comp_id = m_recStream->effectStack().insertTop( comp, "Compressor" );
|
|
|
|
Arts::StereoVolumeControlGui gui = Arts::StereoVolumeControlGui( volumecontrol );
|
|
gui.title( i18n( "Recording level" ).utf8().data() );
|
|
mainwidget->_artswidget = gui;
|
|
mainwidget->_kaw_volumecontrol->setContent( mainwidget->_artswidget );
|
|
|
|
}
|
|
|
|
KRecPrivate::~KRecPrivate() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
mainwidget->_artswidget = Arts::StereoVolumeControlGui::null();
|
|
delete _currentFile;
|
|
_currentFile = 0;
|
|
//kdDebug( 60005 ) << k_funcinfo << "done." << endl;
|
|
}
|
|
|
|
void KRecPrivate::showConfDialog() {
|
|
if ( !_confdlg )
|
|
_confdlg = new KSettings::Dialog( _impl );
|
|
_confdlg->show();
|
|
}
|
|
|
|
void KRecPrivate::newFile() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) closeFile();
|
|
if ( !_currentFile ) {
|
|
pNewFile( new KRecFile( this ) );
|
|
}
|
|
}
|
|
void KRecPrivate::openFile() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) closeFile();
|
|
if ( !_currentFile ) {
|
|
TQString filename = KFileDialog::getOpenFileName( "", "*.krec", _impl );
|
|
//kdDebug( 60005 ) << k_funcinfo << filename << endl;
|
|
if ( !filename.isNull() )
|
|
pNewFile( new KRecFile( filename, this ) );
|
|
}
|
|
}
|
|
void KRecPrivate::pNewFile( KRecFile* file ) {
|
|
_currentFile = file;
|
|
connect( m_recStream, TQT_SIGNAL( data( TQByteArray& ) ), _currentFile, TQT_SLOT( writeData( TQByteArray& ) ) );
|
|
connect( m_playStream, TQT_SIGNAL( requestData( TQByteArray& ) ), _currentFile, TQT_SLOT( getData( TQByteArray& ) ) );
|
|
mainwidget->_fileview->setFile( _currentFile );
|
|
checkActions();
|
|
}
|
|
|
|
void KRecPrivate::saveFile() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) pSaveFile( _currentFile->filename() );
|
|
}
|
|
void KRecPrivate::saveAsFile() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) pSaveFile( TQString() );
|
|
}
|
|
void KRecPrivate::pSaveFile( const TQString &filename ) {
|
|
if ( !_currentFile )
|
|
return;
|
|
|
|
if ( !filename.isNull() )
|
|
_currentFile->save( filename );
|
|
else {
|
|
TQString userFilename = KFileDialog::getSaveFileName( "", "*.krec", _impl, i18n( "Save File As" ) );
|
|
if ( !userFilename.isNull() )
|
|
_currentFile->save( userFilename );
|
|
}
|
|
}
|
|
|
|
bool KRecPrivate::closeFile() {
|
|
//kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) {
|
|
if ( !_currentFile->saved() ) {
|
|
int choice = KMessageBox::questionYesNoCancel( _impl, i18n( "The document \"%1\" has been modified.\nDo you want to save it?" ).arg( _currentFile->filename() ), TQString(), KStdGuiItem::save(), KStdGuiItem::discard() );
|
|
if ( choice == KMessageBox::Yes ) saveFile();
|
|
if ( choice == KMessageBox::Cancel ) return false;
|
|
// go on if KMessageBox::No
|
|
}
|
|
delete _currentFile;
|
|
_currentFile = 0;
|
|
mainwidget->_fileview->setFile( _currentFile );
|
|
}
|
|
checkActions();
|
|
return true;
|
|
}
|
|
|
|
void KRecPrivate::exportFile() {
|
|
kdDebug( 60005 ) << k_funcinfo << endl;
|
|
if ( _currentFile ) {
|
|
TQString filename = KFileDialog::getSaveFileName( "", KRecGlobal::the()->exportFormatEndings(), _impl, "Export File As" );
|
|
if ( !filename.isNull() ) {
|
|
int lastdot = filename.find( '.', -5 );
|
|
TQString ending = filename.right( filename.length()-lastdot-1 );
|
|
_exportitem = KRecGlobal::the()->getExportItemForEnding( ending );
|
|
if ( _exportitem ) {
|
|
_exportitem->initialize( _currentFile->samplerate(), _currentFile->bits(), _currentFile->channels() );
|
|
if ( _exportitem->initialize( filename ) ) {
|
|
connect( _exportitem, TQT_SIGNAL( getData( TQByteArray& ) ), _currentFile, TQT_SLOT( getData( TQByteArray& ) ) );
|
|
connect( _currentFile, TQT_SIGNAL( endReached() ), _exportitem, TQT_SLOT( stop() ) );
|
|
connect( _currentFile, TQT_SIGNAL( endReached() ), TQT_TQOBJECT(this), TQT_SLOT( endExportFile() ) );
|
|
_exportitem->start();
|
|
}
|
|
} else
|
|
KMessageBox::detailedSorry( _impl,
|
|
i18n( "Sorry, an encoding method could not be determined." ),
|
|
i18n( "<qt>This can have several reasons:<ul>" \
|
|
"<li>You did not specify an ending.</li>" \
|
|
"<li>You specified an ending but there is no plugin available " \
|
|
"for this ending. In both cases be sure to choose an ending of " \
|
|
"the list presented in the previous dialog.</li>" \
|
|
"<li>The plugin loading mechanism isn't working. If you are sure " \
|
|
"you did everything right, please file a bugreport saying what " \
|
|
"you where about to do and please quote the following line:<br />" \
|
|
"%1</li>" \
|
|
"</ul></qt>" ).arg( KRecGlobal::the()->exportFormatEndings() ),
|
|
i18n( "Could not determine encodingmethod" ) );
|
|
}
|
|
} else KRecGlobal::the()->message( i18n( "There is nothing to export." ) );
|
|
checkActions();
|
|
}
|
|
void KRecPrivate::endExportFile() { TQTimer::singleShot( 20, TQT_TQOBJECT(this), TQT_SLOT( endExportFile2() ) ); }
|
|
void KRecPrivate::endExportFile2() {
|
|
_exportitem->finalize();
|
|
disconnect( _currentFile, 0, _exportitem, 0 );
|
|
disconnect( _exportitem, 0, 0, 0 );
|
|
checkActions();
|
|
}
|
|
|
|
void KRecPrivate::playthru( bool yes ){
|
|
kdDebug( 60005 ) << k_funcinfo << yes << endl;
|
|
if(yes) {
|
|
Arts::connect( m_recStream->effectStack(), m_playStream->effectStack() );
|
|
kdDebug( 60005 ) << "Making a connection between recStream and playStream :-)" << endl;
|
|
} else {
|
|
Arts::disconnect( m_recStream->effectStack(), m_playStream->effectStack() );
|
|
kdDebug( 60005 ) << "Disconnecting recStream and playStream :-(" << endl;
|
|
}
|
|
}
|
|
|
|
void KRecPrivate::checkActions(){
|
|
_impl->actionCollection()->action( "player_record" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "player_play" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "player_stop" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "player_gobegin" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "player_goend" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "export_file" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "file_save" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "file_save_as" )->setEnabled( false );
|
|
_impl->actionCollection()->action( "file_close" )->setEnabled( false );
|
|
if ( _currentFile ) {
|
|
if ( !_exportitem || ( _exportitem && !_exportitem->running() ) ) {
|
|
if ( !m_recStream->running() && !m_playStream->running() ) {
|
|
_impl->actionCollection()->action( "player_record" )->setEnabled( true );
|
|
_impl->actionCollection()->action( "player_play" )->setEnabled( true );
|
|
}
|
|
if ( m_playStream->running() || m_recStream->running() )
|
|
_impl->actionCollection()->action( "player_stop" )->setEnabled( true );
|
|
if ( _currentFile->position() != 0 )
|
|
_impl->actionCollection()->action( "player_gobegin" )->setEnabled( true );
|
|
if ( _currentFile->position() != _currentFile->size() )
|
|
_impl->actionCollection()->action( "player_goend" )->setEnabled( true );
|
|
}
|
|
_impl->actionCollection()->action( "export_file" )->setEnabled( true );
|
|
_impl->actionCollection()->action( "file_close" )->setEnabled( true );
|
|
//if ( !_currentFile->saved() ) {
|
|
_impl->actionCollection()->action( "file_save" )->setEnabled( true );
|
|
_impl->actionCollection()->action( "file_save_as" )->setEnabled( true );
|
|
//}
|
|
}
|
|
}
|
|
|
|
void KRecPrivate::toBegin() {
|
|
if ( _currentFile )
|
|
_currentFile->newPos( 0 );
|
|
checkActions();
|
|
}
|
|
void KRecPrivate::toEnd() {
|
|
if ( _currentFile )
|
|
_currentFile->newPos( _currentFile->size() );
|
|
checkActions();
|
|
}
|
|
|
|
void KRecPrivate::forceTipOfDay() {
|
|
KTipDialog::showTip( _impl, TQString(), true );
|
|
}
|
|
|
|
void KRecPrivate::execaRtsControl() {
|
|
kapp->kdeinitExec( "artscontrol" );
|
|
}
|
|
void KRecPrivate::execKMix() {
|
|
kapp->kdeinitExec( "kmix" );
|
|
}
|
|
|
|
/**
|
|
|
|
KRecord:
|
|
|
|
*/
|
|
|
|
KRecord::KRecord(TQWidget *parent, const char *name )
|
|
: KMainWindow(parent,name)
|
|
, d( new KRecPrivate( this ) )
|
|
{
|
|
kdDebug( 60005 ) << k_funcinfo << endl;
|
|
//kdDebug( 60005 )<<"KRecord::KRecord( TQWidget *"<<parent<<", const char* "<<name<<" )"<<endl; // (DEBUG)
|
|
|
|
KRecGlobal::the()->setMainWidget( this );
|
|
KRecGlobal::the()->setStatusBar( statusBar() );
|
|
|
|
// * * * Startup-Window * * *
|
|
KTipDialog::showTip( this );
|
|
|
|
// * * * Mainwidget * * *
|
|
setCentralWidget( d->mainwidget );
|
|
|
|
// * * * Actions * * *
|
|
d->artsactions = new ArtsActions( d->server, actionCollection(), this );
|
|
|
|
KStdAction::preferences( d, TQT_SLOT( showConfDialog() ), actionCollection() );
|
|
|
|
KStdAction::openNew( d, TQT_SLOT( newFile() ), actionCollection() );
|
|
KStdAction::open( d, TQT_SLOT( openFile() ), actionCollection() );
|
|
KStdAction::save( d, TQT_SLOT( saveFile() ), actionCollection() );
|
|
KStdAction::saveAs( d, TQT_SLOT( saveAsFile() ), actionCollection() );
|
|
KStdAction::close( d, TQT_SLOT( closeFile() ), actionCollection() );
|
|
KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT( close() ), actionCollection() );
|
|
|
|
KStdAction::tipOfDay( d, TQT_SLOT( forceTipOfDay() ), actionCollection() );
|
|
|
|
d->aExportFile = new KAction( i18n( "Export..." ), KShortcut(),
|
|
d, TQT_SLOT( exportFile() ), actionCollection(), "export_file" );
|
|
|
|
d->aRecord = new KAction( i18n( "&Record" ), KShortcut( Key_R ),
|
|
TQT_TQOBJECT(this), TQT_SLOT( startRec() ), actionCollection(), "player_record" );
|
|
d->aPlay = new KAction( i18n( "&Play" ), KShortcut( Key_P ),
|
|
TQT_TQOBJECT(this), TQT_SLOT( startPlay() ), actionCollection(), "player_play" );
|
|
d->aStop = new KAction( i18n( "&Stop" ), KShortcut( Key_S ),
|
|
TQT_TQOBJECT(this), TQT_SLOT( stopRec() ), actionCollection(), "player_stop" );
|
|
d->aThru = new KToggleAction( i18n( "Play Through" ), KShortcut( CTRL + Key_P), actionCollection(), "play_thru" );
|
|
connect( d->aThru, TQT_SIGNAL( toggled( bool ) ), d, TQT_SLOT( playthru( bool ) ) );
|
|
|
|
d->aBegin = new KAction( i18n( "Go to &Beginning" ), KShortcut( SHIFT + Key_Left ),
|
|
d, TQT_SLOT( toBegin() ), actionCollection(), "player_gobegin" );
|
|
d->aEnd = new KAction( i18n( "Go to &End" ), KShortcut( SHIFT + Key_Right ),
|
|
d, TQT_SLOT( toEnd() ), actionCollection(), "player_goend" );
|
|
|
|
( void* ) d->artsactions->actionAudioManager();
|
|
|
|
d->aExecaRtsControl = new KAction( i18n( "Start aRts Control Tool" ), KShortcut(),
|
|
d, TQT_SLOT( execaRtsControl() ), actionCollection(), "exec_artscontrol" );
|
|
d->aExecKMix = new KAction( i18n( "Start KMix" ), KShortcut(),
|
|
d, TQT_SLOT( execKMix() ), actionCollection(), "exec_kmix" );
|
|
|
|
// * * * GUI * * *
|
|
// TODO Fix toolbar config so this line can just be setupGUI()
|
|
setupGUI(KMainWindow::Keys | StatusBar | Save | Create );
|
|
setStandardToolBarMenuEnabled( true );
|
|
// TODO Fix the arts toolbar to know it own minium size, this app shouldn't care!
|
|
setMinimumWidth( 400 );
|
|
|
|
if( d->b_comp )
|
|
{
|
|
Arts::GenericGuiFactory factory;
|
|
Arts::Widget aw = factory.createGui( d->comp );
|
|
d->w = new KArtsWidget( aw, toolBar("compressor") );
|
|
d->w->setName( "kde toolbar widget" );
|
|
|
|
toolBar( "compressor" )->insertWidget( 1, 400, d->w );
|
|
toolBar( "compressor" )->setBarPos( KToolBar::Bottom );
|
|
}
|
|
else
|
|
{
|
|
toolBar( "compressor" )->close();
|
|
KMessageBox::detailedSorry( this,
|
|
i18n( "Your system is missing the Synth_STEREO_COMPRESSOR aRts module.\nYou will be able to use KRec but without the great functions of the compressor." ),
|
|
i18n( "Possible reasons are:\n- You installed KRec on its own without the rest of kdemultimedia.\n- You installed everything correctly, but did not restart the aRts daemon\n and therefore it is not aware of the new effects.\n- This is a bug." ),
|
|
i18n( "Unable to Find Compressor" ) );
|
|
}
|
|
|
|
d->checkActions();
|
|
}
|
|
|
|
KRecord::~KRecord(){
|
|
kdDebug( 60005 ) << k_funcinfo << endl; // (DEBUG)
|
|
stopRec();
|
|
|
|
d->m_recStream->effectStack().remove( d->vc_id );
|
|
if( d->b_comp ) d->m_recStream->effectStack().remove( d->comp_id );
|
|
d->volumecontrol.stop();
|
|
if( d->b_comp ) d->comp.stop();
|
|
|
|
d->volumecontrol = Arts::StereoVolumeControl::null();
|
|
if( d->b_comp ) d->comp = Arts::StereoEffect::null();
|
|
|
|
KRecGlobal::kconfig()->sync();
|
|
delete d;
|
|
kdDebug( 60005 ) << k_funcinfo << "done. Bye!" << endl;
|
|
}
|
|
|
|
void KRecord::startRec(){
|
|
if( !d->m_recStream->running() && d->_currentFile ) {
|
|
//kdDebug( 60005 )<<"KRecord::startRec()"<<endl; // (DEBUG)
|
|
d->_currentFile->newBuffer();
|
|
d->m_recStream->start( d->_currentFile->samplerate(),
|
|
d->_currentFile->bits(),
|
|
d->_currentFile->channels() );
|
|
}
|
|
d->checkActions();
|
|
d->mainwidget->_fileview->updateGUI();
|
|
}
|
|
|
|
void KRecord::startPlay(){
|
|
if ( !d->m_playStream->running() && d->_currentFile ) {
|
|
d->m_playStream->start( d->_currentFile->samplerate(),
|
|
d->_currentFile->bits(),
|
|
d->_currentFile->channels() );
|
|
}
|
|
d->checkActions();
|
|
d->mainwidget->_fileview->updateGUI();
|
|
}
|
|
|
|
void KRecord::stopRec(){
|
|
if ( d->m_recStream->running() )
|
|
d->m_recStream->stop();
|
|
if ( d->m_playStream->running() )
|
|
d->m_playStream->stop();
|
|
d->checkActions();
|
|
d->mainwidget->_fileview->updateGUI();
|
|
}
|
|
|
|
|
|
bool KRecord::queryClose() {
|
|
kdDebug( 60005 ) << k_funcinfo << endl;
|
|
return d->closeFile();
|
|
}
|
|
|
|
#include "krecord.moc"
|
|
#include "krecord_private.moc"
|
|
|
|
// vim:sw=4:ts=4
|