📄 1
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************///#define QTOPIA_INTERNAL_MIMEEXT#include "mediarecorder.h"#include "mediarecorderbase.h"#include "audioinput.h"#include "audiodevice.h"#include "samplebuffer.h"#include "pluginlist.h"#include "timeprogressbar.h"#include "confrecorder.h"#include "waveform.h"#include <qtopia/global.h>#include <qtopia/fileselector.h>#include <qtopia/applnk.h>#include <qtopia/resource.h>#include <qtopia/config.h>#include <qtopia/storage.h>#include <qtopia/locationcombo.h>#include <qtopia/qpeapplication.h>#include <qtopia/qpemenubar.h>#include <qtopia/qpetoolbar.h>#include <qtopia/mimetype.h>#ifdef Q_WS_QWS#include <qtopia/qcopenvelope_qws.h>#endif#include <qaction.h>#include <qbuttongroup.h>#include <qcombobox.h>#include <qmessagebox.h>#include <qdir.h>#include <qfile.h>#include <qstring.h>#include <stdlib.h>MediaRecorder::MediaRecorder( QWidget *parent, const char *name, WFlags f ) : QMainWindow( parent, name, f ){ // Load the media plugins. recorderPlugins = new MediaRecorderPluginList(); playerPlugins = new MediaPlayerPluginList(); setToolBarsMovable( FALSE ); setBackgroundMode( PaletteButton );// setCaption( QString::fromLocal8Bit("") );// setIcon( Resource::loadPixmap( "SoundPlayer" ) ); QPEToolBar *bar = new QPEToolBar( this ); bar->setHorizontalStretchable( TRUE ); menu = bar; QPEMenuBar *mb = new QPEMenuBar( bar ); QPopupMenu *options = new QPopupMenu( this ); mb->insertItem( tr( "Options" ), options ); configureAction = new QAction( tr( "Configure Qualities ..." ), QString::null, 0, this, 0 ); connect( configureAction, SIGNAL( activated() ), this, SLOT( configure() ) ); configureAction->setWhatsThis( tr("Configure the recording quality settings.") ); configureAction->addTo( options ); configureAction->setEnabled( TRUE ); stack = new QWidgetStack( this ); stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); setCentralWidget( stack ); contents = new MediaRecorderBase( this ); stack->addWidget( contents, 0 ); initializeContents(); stack->raiseWidget( contents ); audioInput = 0; audioOutput = 0;#ifdef RECORD_THEN_SAVE samples = 0;#endif sampleBuffer = 0; recordTime = 0; recording = FALSE; playing = FALSE; io = 0; recordLightState = FALSE; lightTimer = new QTimer( this ); // findplayfile = new Findplayfile(this); // Hook up interesting signals. connect( contents->recordButton, SIGNAL( clicked() ), this, SLOT( recordClicked() ) );// connect(contents->choosefileButton,SIGNAL(clicked() ),// this,SLOT(choosefileClicked() ) ); connect( contents->playButton, SIGNAL( clicked() ), this, SLOT( replayClicked() ) ); connect( contents->delButton, SIGNAL( clicked() ), this, SLOT( deleteClicked() ) ); connect( lightTimer, SIGNAL( timeout() ), this, SLOT( recordLightBlink() ) ); connect( contents->quitButton, SIGNAL( clicked() ), this, SLOT( stopRecording() ) ); connect( contents->stopButton,SIGNAL( clicked() ), this, SLOT( stopPlaying() ) ); // Listen on the system tray for clicks on the record light so that // we can raise the application when the user clicks on it. trayChannel = new QCopChannel( "Qt/Tray", this ); connect( trayChannel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(traySocket(const QCString&, const QByteArray&)) ); //init this->showMaximized(); countnow = 0; // Force the MIME type handling system to preload the list // of extensions. If we don't do this, then "startRecording" // ends up being _very_ slow. MimeType type("audio/x-wav");}MediaRecorder::~MediaRecorder(){ delete recorderPlugins; delete playerPlugins; if ( audioInput ) delete audioInput; if ( audioOutput ) delete audioOutput;#ifdef RECORD_THEN_SAVE if ( samples ) delete samples;#endif if ( sampleBuffer ) delete[] sampleBuffer; if ( io ) delete io; if ( lightTimer ) delete lightTimer;}void MediaRecorder::initializeContents(){ // Cannot replay yet, because there is no recorded sound.// contents->playButton->setEnabled( FALSE );// contents->delButton->setEnabled( FALSE ); contents->stopButton->setEnabled( FALSE ); // Load the initial quality settings. config = new ConfigureRecorder( qualities, recorderPlugins, this ); setQualityDisplay( qualities[config->currentQuality()] ); recomputeMaxTime(); }void MediaRecorder::setQualityDisplay( const QualitySetting& quality ){ QString str; QString format; int index; // Map the MIME type to a format name. Do the best we can with // the MIME type and tag if that is all we have. index = recorderPlugins->indexFromType ( quality.mimeType, quality.formatTag ); if( index >= 0 ) { format = recorderPlugins->formatNameAt( (uint)index ); } else if( quality.mimeType.startsWith( "audio/" ) ) { format = quality.mimeType.mid(6) + " [" + quality.formatTag + "]"; } else { format = quality.mimeType + " [" + quality.formatTag + "]"; } // Format the details and display them. int khz = (quality.frequency / 1000); if ( quality.channels == 1 ) { str = tr("%1 kHz Mono - %2").arg(khz).arg(format); } else { str = tr("%1 kHz Stereo - %2").arg(khz).arg(format); }}void MediaRecorder::recomputeMaxTime(){ // Determine the maximum available space on the device. long availBlocks; long blockSize; // if ( fs ) {// availBlocks = fs->availBlocks();// blockSize = fs->blockSize();// } else { availBlocks = 4500; blockSize = 512;// } // Calculate the number of bytes per second for the current quality, // by asking the plugin for an estimate. MediaRecorderEncoder *encoder = recorderPlugins->fromType ( qualities[config->currentQuality()].mimeType, qualities[config->currentQuality()].formatTag ); long bytesPerSec; if( encoder ) { bytesPerSec = encoder->estimateAudioBps ( qualities[config->currentQuality()].frequency, qualities[config->currentQuality()].channels, qualities[config->currentQuality()].formatTag ); if ( bytesPerSec <= 0) bytesPerSec = 1; } else { // We don't have an encoder, so make an estimate based on // assuming that the format is wav. bytesPerSec = qualities[config->currentQuality()].frequency * qualities[config->currentQuality()].channels * 2; } // Get an estimate of the maximum number of seconds that we can record. // Use "double" to avoid truncation errors with 32-bit arithmetic. long maxSecs = (long)(((double)availBlocks) * ((double)blockSize) / (double)bytesPerSec); // Truncate the maximum to a reasonable human-grokkable time boundary, // as there is no point displaying things like "5 hrs 23 mins 6 secs". if ( maxSecs >= (60 * 60 * 24) ) { // Truncate to a 1 hour boundary. maxSecs -= (maxSecs % (60 * 60)); } else if ( maxSecs >= (60 * 60 * 10) ) { // Truncate to a 15 minute boundary. maxSecs -= (maxSecs % (15 * 60)); } else if ( maxSecs >= (60 * 10) ) { // Tuncate to a 1 minute boundary. maxSecs -= (maxSecs % 60); } else if ( maxSecs > 60 ) { // Truncate to a 15 second boundary. maxSecs -= (maxSecs % 15); } // Format the string for the max time field. QString str; if ( maxSecs >= (60 * 60 * 24) ) { if ( (maxSecs % (60 * 60 * 24)) == 0 ) { str = tr("%1 days").arg((int)(maxSecs / (60 * 60 * 24))); } else { str = tr("%1 days %2 hrs") .arg((int)(maxSecs / (60 * 60 * 24))) .arg((int)((maxSecs / (60 * 60)) % 24)); } } else if ( maxSecs >= (60 * 60) ) { if ( (maxSecs % (60 * 60)) == 0 ) { str = tr("%1 hrs").arg((int)(maxSecs / (60 * 60))); } else { str = tr("%1 hrs %2 mins") .arg((int)(maxSecs / (60 * 60))) .arg((int)((maxSecs / 60) % 60)); } } else if ( maxSecs >= 60 ) { if ( (maxSecs % 60) == 0 ) { str = tr("%1 mins").arg((int)(maxSecs / 60)); } else { str = tr("%1 mins %2 secs").arg((int)(maxSecs / 60)).arg((int)(maxSecs % 60)); } } else { str = tr("%1 secs").arg((int)maxSecs); } // Update the max time field. maxRecordTime = maxSecs;}void MediaRecorder::qualityChanged( int id ){ config->setQuality( id ); config->saveConfig(); setQualityDisplay( qualities[id] ); recomputeMaxTime();}void MediaRecorder::newLocation(){ recomputeMaxTime();}void MediaRecorder::startSave(){ // Find the plugin to use to save the data. encoder = recorderPlugins->fromType ( qualities[config->currentQuality()].mimeType, qualities[config->currentQuality()].formatTag ); // Open the document. DocLnk doc; FileManager fm; QString name = "man" + QDateTime::currentDateTime().toString();// tr("S%1","date").arg(TimeString::localYMDHMS(QDateTime::currentDateTime())); // QMessageBox::critical( this, tr( "No playback plugin found" ),tr(name)); doc.setName( name ); doc.setType( encoder->pluginMimeType() );// doc.setLocation( contents->storageLocation->documentPath() ); io = fm.saveFile( doc ); // Write the sample data using the encoder. encoder->begin( io, qualities[config->currentQuality()].formatTag ); encoder->setAudioChannels( audioInput->channels() ); encoder->setAudioFrequency( audioInput->frequency() ); // Record the location of the file that we are saving. lastSaved = doc.file(); lastSavedLink = doc.linkFile();// QMessageBox::critical( this, tr( "No playback plugin found" ),tr(lastSavedLink));}void MediaRecorder::endSave(){ // Flush the samples if we recorded to memory.#ifdef RECORD_THEN_SAVE samples->rewind(); short *buf; unsigned int length; while ( samples->nextReadBuffer( buf, length ) ) { if ( !encoder->writeAudioSamples( buf, (long)length ) ) break; }#endif // Terminate the encode process. encoder->end(); // Close the document. io->close(); delete io; io = 0; // Clear the data for another recording. clearData();}void MediaRecorder::startRecording(){ QualitySetting *qual = &(qualities[config->currentQuality()]); // Bail out if we don't have a plugin for the selected format. if( recorderPlugins->fromType( qual->mimeType, qual->formatTag ) == 0) { noPluginError(); return; } // Disable power save while recording so that the device // doesn't suspend while a long-term recording session // is in progress.#ifdef Q_WS_QWS QPEApplication::setTempScreenSaverMode( QPEApplication::DisableSuspend );#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -