⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mediarecorder.cpp

📁 Qtopia下的多媒体录音源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 2000-2006 TROLLTECH ASA. All rights reserved.**** This file is part of the Phone Edition of the Qtopia Toolkit.**** Licensees holding a valid license agreement from Trolltech or any of its** authorized distributors may use this file in accordance with** the License Agreement provided with the Licensed Software.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for**   information about Trolltech's Commercial License Agreements.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.********** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "mediarecorder.h"#include "samplebuffer.h"#include "pluginlist.h"#include "timeprogressbar.h"#include "confrecorder.h"#include "waveform.h"#include <qtopia/qdocumentselector.h>#include <qtopia/qcontent.h>#include <qsettings.h>#include <qtopia/qstorage.h>#include <qtopia/qstoragedeviceselector.h>#include <qtopia/qtopiaapplication.h>#include <qtopia/qmimetype.h>#include <qtopia/qdocumentselector.h>#include <qtopia/qcategorymanager.h>#include <qtopiaaudio/qaudioinput.h>#ifdef Q_WS_QWS#include <qtopia/qcopenvelope.h>#endif#include <qaction.h>#include <qbuttongroup.h>#include <qcombobox.h>#include <qmessagebox.h>#include <qfile.h>#include <qtoolbar.h>#include <qmenubar.h>#include <qmenu.h>#include <qevent.h>#include <QDebug>#ifdef QTOPIA_PHONE#include <qtopia/qsoftmenubar.h>#endif#include <stdlib.h>#define MR_BUFSIZE  1024MediaRecorder::MediaRecorder(QWidget *parent, Qt::WFlags f):    QMainWindow(parent, f),    contentsWidget(NULL),    config( 0 ),    recorderPlugins(NULL),    m_audioInput(new QAudioInput),    audioDeviceIsReady(false),    startWhenAudioDeviceReady(false),    m_sound(NULL),    recordingsCategory("_Recordings"),    requestMode(false),    m_position(0){    // We remove some of the UI if the screen is too small to hold it.    smallScreen = height() < 120;    // Adjust window decorations    setWindowTitle(tr("Voice Notes"));    setWindowIcon(QIcon( ":image/SoundPlayer"));    // We don't need an input method with this application.    QtopiaApplication::setInputMethodHint(this, QtopiaApplication::AlwaysOff);    // Make sure that the "Recordings" category is registered.    QCategoryManager    cats("Documents", 0);    if (!cats.contains(recordingsCategory)) {        if (!cats.add(recordingsCategory, tr("Recordings")))            recordingsCategory = cats.addTr(tr("Recordings"));    }    // Create stack widget    stack = new QStackedWidget(this);    stack->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));    setCentralWidget(stack);    // Add the Document selector    selector = new QDocumentSelector("audio/*", QCategoryFilter(recordingsCategory), stack);    selector->setNewEnabled(true);    selector->setSortMode(QDocumentSelector::ReverseChronological);    selector->setFocus( Qt::OtherFocusReason );    stack->addWidget(selector);    connect(selector,            SIGNAL(documentSelected(const QContent&)),	        this,            SLOT(documentSelected(const QContent&)));    connect(selector,            SIGNAL(newSelected()),	        this,            SLOT(newSelected()));    // Listen for app messages, particularly the "recordSound" request.    connect(qApp,            SIGNAL(appMessage(const QString&,const QByteArray&)),            this,            SLOT(appMessage(const QString&,const QByteArray&)));    // Listen for "VoiceRecording" service messages.    new VoiceRecordingService(this);    // extra config    sampleBuffer = 0;    recordTime = 0;    recording = false;    playing = false;    io = 0;    recordLightState = false;#ifdef RECORD_THEN_SAVE    samples = 0;#endif#ifndef QTOPIA_PHONE    // Make a timer to flash the light    lightTimer = new QTimer(this);    connect(lightTimer,            SIGNAL(timeout()),	        this,            SLOT(recordLightBlink()));    // 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("Tray", this);    connect(trayChannel,            SIGNAL(received(const QString&,const QByteArray&)),	        this,            SLOT(traySocket(const QString&,const QByteArray&)));#endif}MediaRecorder::~MediaRecorder(){    delete m_audioInput;    delete recorderPlugins;#ifdef RECORD_THEN_SAVE    if ( samples )        delete samples;#endif    if (sampleBuffer)        delete[] sampleBuffer;    if (io )        delete io;#ifndef QTOPIA_PHONE    delete lightTimer;#endif    delete m_sound;}void MediaRecorder::initializeContents(){    // The progress bar initially has no time display.  This will be fixed    // up when we start recording.    contents->progress->setMaximum( 10 );    contents->progress->setValue( -1 );    // Cannot replay yet, because there is no recorded sound.    setReplayEnabled(false);    setDeleteEnabled(false);    if (recorderPlugins == NULL)        recorderPlugins = new MediaRecorderPluginList();    // Load the initial quality settings.    config = new ConfigureRecorder(qualities, recorderPlugins, this);    contents->qualityCombo->setCurrentIndex(config->currentQuality());    setQualityDisplay(qualities[config->currentQuality()]);    connect( contents->qualityCombo, SIGNAL( activated(int) ),	     this, SLOT( qualityChanged(int) ) );    connect( contents->storageLocation, SIGNAL(newPath()),	     this, SLOT(newLocation()) );    recomputeMaxTime();#ifdef QTOPIA_PHONE    // Create a menu with "Help" on the dialog.    QSoftMenuBar::menuFor( config );    // Disable the settings boxes in phone mode.    contents->GroupBox1->hide();    contents->GroupBox2->hide();#else    if ( smallScreen )	contents->GroupBox1->hide();#endif}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);    }    contents->details->setText( str );}void MediaRecorder::recomputeMaxTime(){    // Determine the maximum available space on the device.    const QFileSystem *fs = contents->storageLocation->fileSystem();    long availBlocks;    long blockSize;    if ( fs ) {	availBlocks = fs->availBlocks();	blockSize = fs->blockSize();    } else {	availBlocks = 0;	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);    }#ifndef QTOPIA_PHONE        // will never be seen    // 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.    contents->maxTime->setText( str );#endif    maxRecordTime = maxSecs;}void MediaRecorder::qualityChanged( int id ){    config->setQuality( id );    config->saveConfig();    setQualityDisplay( qualities[id] );    recomputeMaxTime();}void MediaRecorder::newLocation(){    recomputeMaxTime();}bool MediaRecorder::startSave(){    // Find the plugin to use to save the data.    encoder = recorderPlugins->fromType(recordQuality.mimeType,                                        recordQuality.formatTag);    // Open the document.    QContent    doc;    QString     name = tr("%1 %2","date,time")	    .arg(QTimeString::localYMD(QDate::currentDate(),QTimeString::Short))	    .arg(QTimeString::localHM(QTime::currentTime()));    doc.setName(name);    doc.setType( encoder->pluginMimeType() );    QList<QString>  cats;    cats.append(recordingsCategory);    doc.setCategories(cats);	io = doc.open(QIODevice::WriteOnly);	// Write the sample data using the encoder.	encoder->begin(io, recordQuality.formatTag);	encoder->setAudioChannels(m_audioInput->channels());	encoder->setAudioFrequency(m_audioInput->frequency());	// Record the location of the file that we are saving.	lastSaved = doc.file();    doc.commit();	return true;}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();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -