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.
tdemultimedia/krec/krecord.cpp

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