summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2003-11-13 06:23:48 (UTC)
committer llornkcor <llornkcor>2003-11-13 06:23:48 (UTC)
commit452f0cc3d9fdd792d2050ceaffd33b3d1611fcc3 (patch) (side-by-side diff)
treed391cef8c2c278f335c18344e4c6bf01589eaa50
parenta539861cbebf3517472d01ee6e9b34e9f763156e (diff)
downloadopie-452f0cc3d9fdd792d2050ceaffd33b3d1611fcc3.zip
opie-452f0cc3d9fdd792d2050ceaffd33b3d1611fcc3.tar.gz
opie-452f0cc3d9fdd792d2050ceaffd33b3d1611fcc3.tar.bz2
added waveform
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opierec/qtrec.cpp14
-rw-r--r--noncore/multimedia/opierec/waveform.cpp160
-rw-r--r--noncore/multimedia/opierec/waveform.h63
3 files changed, 230 insertions, 7 deletions
diff --git a/noncore/multimedia/opierec/qtrec.cpp b/noncore/multimedia/opierec/qtrec.cpp
index 2bf795f..1e36c96 100644
--- a/noncore/multimedia/opierec/qtrec.cpp
+++ b/noncore/multimedia/opierec/qtrec.cpp
@@ -1,488 +1,488 @@
/****************************************************************************
// qtrec.cpp
Created: Thu Jan 17 11:19:58 2002
copyright 2002 by L.J. Potter <ljp@llornkcor.com>
****************************************************************************/
#define DEV_VERSION
#include "pixmaps.h"
#include "qtrec.h"
#include <pthread.h>
extern "C" {
#include "adpcm.h"
}
#include <sys/soundcard.h>
// #if defined (QTOPIA_INTERNAL_FSLP)
// #include <qpe/lnkproperties.h>
// #endif
#include <qpe/config.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/qpeapplication.h>
#include <qpe/resource.h>
#include <qpe/storage.h>
#include <qcheckbox.h>
#include <qcombobox.h>
//#include <qdatetime.h>
#include <qdir.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qlistview.h>
#include <qmessagebox.h>
#include <qpopupmenu.h>
#include <qpushbutton.h>
#include <qslider.h>
#include <qtabwidget.h>
#include <qtimer.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <unistd.h>
#include<sys/wait.h>
#include <sys/signal.h>
//#define ZAURUS 0
struct adpcm_state encoder_state;
struct adpcm_state decoder_state;
long findPeak(long input );
//char deviceRates[];
typedef struct {
int sampleRate;
/* int fragSize; */
/* int blockSize; */
int resolution; //bitrate
int channels; //number of channels
int fd; //file descriptor
int sd; //sound device descriptor
int numberSamples; //total number of samples
int SecondsToRecord; // number of seconds that should be recorded
float numberOfRecordedSeconds; //total number of samples recorded
int samplesToRecord; //number of samples to be recorded
int inVol; //input volume
int outVol; //output volume
int format; //wavfile format PCM.. ADPCM
const char *fileName; //name of fiel to be played/recorded
} fileParameters;
fileParameters filePara;
bool monitoring, recording;
bool stopped;
QLabel *timeLabel;
QSlider *timeSlider;
int sd;
-#if defined(QT_QWS_EBX)
-#define DSPSTROUT "/dev/dsp"
-#define DSPSTRIN "/dev/dsp1"
-#define DSPSTRMIXEROUT "/dev/mixer"
-#define DSPSTRMIXERIN "/dev/mixer1"
-#else
+// #if defined(QT_QWS_EBX)
+// #define DSPSTROUT "/dev/dsp"
+// #define DSPSTRIN "/dev/dsp1"
+// #define DSPSTRMIXEROUT "/dev/mixer"
+// #define DSPSTRMIXERIN "/dev/mixer1"
+// #else
#define DSPSTROUT "/dev/dsp"
#define DSPSTRIN "/dev/dsp"
#define DSPSTRMIXERIN "/dev/mixer"
#define DSPSTRMIXEROUT "/dev/mixer"
-#endif
+//#endif
// threaded recording
void quickRec() {
//void QtRec::quickRec() {
int total = 0; // Total number of bytes read in so far.
int bytesWritten, number;
count_info info;
bytesWritten=0;
number=0;
QString num, timeString;
int level=0;
int threshold=0;
// if(limit != 0)
// t->start( ( limit +.3) , true);
recording = true;
//rate=filePara.sampleRate;
// int bits = filePara.resolution;
audio_buf_info inInfo;
ioctl( filePara.fd, SNDCTL_DSP_GETISPACE, &inInfo);
// qDebug("ispace is frags %d, total %d", inInfo.fragments, inInfo.fragstotal);
if( filePara.resolution == 16 ) { //AFMT_S16_LE)
level=7;
threshold=0;
timeString.sprintf("%.2f", filePara.numberOfRecordedSeconds);
timeLabel->setText( timeString+ " seconds");
if( filePara.format==WAVE_FORMAT_DVI_ADPCM) {
// qDebug("start recording WAVE_FORMAT_DVI_ADPCM");
char abuf[BUFSIZE/2];
short sbuf[BUFSIZE];
short sbuf2[BUFSIZE];
memset( abuf,0,BUFSIZE/2);
memset( sbuf,0,BUFSIZE);
memset( sbuf2,0,BUFSIZE);
for(;;) {
if (stopped) {
break; // stop if playing was set to false
}
number=::read( filePara.sd, sbuf, BUFSIZE);
if(number <= 0) {
perror("recording error ");
// qDebug( "%s %d", filePara.fileName, number);
// errorStop();
recording=stopped=false;
// QMessageBox::message("Note", "Error recording to file\n%s",filePara.fileName);
return;
}
//if(stereo == 2) {
// adpcm_coder( sbuf2, abuf, number/2, &encoder_state);
adpcm_coder( sbuf, abuf, number/2, &encoder_state);
bytesWritten = ::write( filePara.fd , abuf, number/4);
long peak;
for (int i = 0; i < number; i++)
{ //since Z is mono do normally
peak = findPeak((long)sbuf[i]);
printf("peak %ld\r",peak);
fflush(stdout);
}
//------------->>>> out to file
// if(filePara.channels==1)
// total += bytesWritten/2; //mono
// else
total += bytesWritten;
filePara.numberSamples = total;
// if( total >= filePara.samplesToRecord)
// timeSlider->setValue(0);
// else if( filePara.SecondsToRecord !=0)
timeSlider->setValue( total);
filePara.numberOfRecordedSeconds = (float)total / (float)filePara.sampleRate * (float)2;
ioctl( filePara.sd, SNDCTL_DSP_GETIPTR, &info);
timeString.sprintf("%.2f", filePara.numberOfRecordedSeconds);
timeLabel->setText( timeString + " seconds");
qApp->processEvents();
if( total >= filePara.samplesToRecord)
break;
}
} else {
// qDebug("start recording WAVE_FORMAT_PCM");
short inbuffer[BUFSIZE], outbuffer[BUFSIZE];
memset( inbuffer,0,BUFSIZE);
memset( outbuffer,0,BUFSIZE);
for(;;) {
if (stopped) {
break; // stop if playing was set to false
}
number=::read( filePara.sd, inbuffer, BUFSIZE);
if(number <= 0) {
perror("recording error ");
recording=stopped=false;
// errorStop();
return;// false;
}
/* for (int i=0;i< number;i++) { //2*i is left channel
outbuffer[i]=inbuffer[i]>>1; // no clippy, please
}*/
bytesWritten = ::write( filePara.fd , inbuffer, number);
//------------->>>> out to file
if(bytesWritten < 0) {
// errorStop();
perror("File writing error ");
return;// false;
}
// if(filePara.channels==1)
// total += bytesWritten/2; //mono
// else
total += bytesWritten;
long peak;
for (int i = 0; i < number; i++)
{ //since Z is mono do normally
peak = findPeak((long)inbuffer[i]);
printf("peak %ld\r",peak);
fflush(stdout);
}
filePara.numberSamples = total;
if(filePara.SecondsToRecord !=0)
timeSlider->setValue( total);
// printf("Writing number %d, bytes %d,total %d\r",number, bytesWritten , total);
// fflush(stdout);
ioctl( filePara.sd, SNDCTL_DSP_GETIPTR, &info);
// qDebug("%d, %d", info.bytes, ( info.bytes / filePara.sampleRate) / 2);
filePara.numberOfRecordedSeconds = (float)total / (float)filePara.sampleRate / (float)2;
timeString.sprintf("%.2f", filePara.numberOfRecordedSeconds);
timeLabel->setText( timeString + " seconds");
qApp->processEvents();
if( total >= filePara.samplesToRecord)
break;
}
} //end main loop
} else { // <<<<<<<<<<<<<<<<<<<<<<< format = AFMT_U8;
unsigned char unsigned_inbuffer[BUFSIZE], unsigned_outbuffer[BUFSIZE];
memset( unsigned_inbuffer, 0, BUFSIZE);
memset( unsigned_outbuffer, 0, BUFSIZE);
for(;;) {
if (stopped) {
// qDebug("quickRec:: stopped");
break; // stop if playing was set to false
}
number=::read( filePara.sd, unsigned_inbuffer, BUFSIZE);
//-------------<<<< in from device
// val = (data ^ 0x80) << 8;
//unsigned_outbuffer = (unsigned_inbuffer ^ 0x80) << 8;
// if(number <= 0) {
// perror("recording error ");
// qDebug(filePara.fileName);
// // errorStop();
// QMessageBox::message("Note","error recording");
// return;// false;
// }
// for (int i=0;i< number;i++) { //2*i is left channel
// unsigned_outbuffer[i]=unsigned_inbuffer[i]>>1; // no clippy, please
// }
bytesWritten = ::write( filePara.fd , unsigned_inbuffer, number);
//------------->>>> out to file
if(bytesWritten < 0) {
recording=stopped=false;
// errorStop();
QMessageBox::message("Note","There was a problem\nwriting to the file");
perror("File writing error ");
return;// false;
}
total += bytesWritten;
filePara.numberSamples = total;
// printf("\nWriting number %d, bytes %d,total %d \r",number, bytesWritten , total);
// fflush(stdout);
if(filePara.SecondsToRecord !=0)
timeSlider->setValue( total);
filePara.numberOfRecordedSeconds = (float)total / (float)filePara.sampleRate;
timeString.sprintf("%.2f",filePara.numberOfRecordedSeconds);
timeLabel->setText( timeString + " seconds");
qApp->processEvents();
if( total >= filePara.samplesToRecord)
break;
} //end main loop
}
// qDebug("Final %d, %d", filePara.samplesToRecord , filePara.numberOfRecordedSeconds);
} /// END quickRec()
// threaded play
void playIt() {
}
/////////////////<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>
QtRec::QtRec( QWidget* parent, const char* name, WFlags fl )
: QWidget( parent, name, fl ) {
// QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << true; // mute device
// autoMute=TRUE;
// QPEApplication::grabKeyboard();
if ( !name )
setName( "OpieRec" );
init();
initConfig();
initConnections();
renameBox = 0;
// open sound device to get volumes
soundDevice = new Device( this, DSPSTROUT, DSPSTRMIXEROUT, false);
// soundDevice->setDeviceFormat(AFMT_S16_LE);
// soundDevice->setDeviceChannels(1);
// soundDevice->setDeviceRate( 22050);
getInVol();
getOutVol();
soundDevice->closeDevice( true);
soundDevice->sd=-1;
soundDevice=0;
wavFile=0;
if(soundDevice) delete soundDevice;
initIconView();
if(autoMute)
doMute(true);
ListView1->setFocus();
playing=false;
}
QtRec::~QtRec() {
}
void QtRec::cleanUp() {
if(!stopped) {
stopped=true;
endRecording();
}
ListView1->clear();
if(autoMute)
doMute(false);
if(wavFile) delete wavFile;
// if(soundDevice) delete soundDevice;
// QPEApplication::grabKeyboard();
// QPEApplication::ungrabKeyboard();
}
void QtRec::init() {
needsStereoOut=false;
QPixmap image3( ( const char** ) image3_data );
QPixmap image4( ( const char** ) image4_data );
QPixmap image6( ( const char** ) image6_data );
stopped=true;
setCaption( tr( "OpieRecord " ) + QString::number(VERSION) );
QGridLayout *layout = new QGridLayout( this );
layout->setSpacing( 2);
layout->setMargin( 2);
TabWidget = new QTabWidget( this, "TabWidget" );
layout->addMultiCellWidget(TabWidget, 0, 7, 0, 7);
// TabWidget->setTabShape(QTabWidget::Triangular);
///**********<<<<<<<<<<<<>>>>>>>>>>>>***************
tab = new QWidget( TabWidget, "tab" );
QGridLayout *layout1 = new QGridLayout( tab);
layout1->setSpacing( 2);
layout1->setMargin( 2);
timeSlider = new QSlider( 0,100,10,0, QSlider::Horizontal, tab, (const char *) "timeSlider" );
// timeSlider->setFixedWidth(150);
layout1->addMultiCellWidget( timeSlider, 1, 1, 0, 3);
// timeSlider->setTickmarks(QSlider::Above);
timeLabel = new QLabel( tab, "TimeLabel" );
layout1->addMultiCellWidget( timeLabel, 0, 0, 0, 3);
playLabel2 = new QLabel(tab, "PlayLabel2" );
playLabel2->setText(tr("Play") );
playLabel2->setFixedHeight(18);
layout1->addMultiCellWidget( playLabel2, 0, 0, 4, 4);
Stop_PushButton = new QPushButton( tab, "Stop_PushButton" );
layout1->addMultiCellWidget( Stop_PushButton, 1, 1, 4, 4);
Stop_PushButton->setFixedSize(22,22);
Stop_PushButton->setPixmap( image4 );
toBeginningButton = new QPushButton( tab, "Beginning_PushButton" );
layout1->addMultiCellWidget(toBeginningButton, 1, 1, 5, 5);
toBeginningButton->setFixedSize(22,22);
toBeginningButton->setPixmap( Resource::loadPixmap("fastback") );
toEndButton = new QPushButton( tab, "End_PushButton" );
layout1->addMultiCellWidget( toEndButton, 1, 1, 6, 6);
toEndButton->setFixedSize(22,22);
toEndButton->setPixmap( Resource::loadPixmap( "fastforward" ) );
QLabel *recLabel2;
recLabel2 = new QLabel( tab, "recLabel2" );
recLabel2->setText(tr("Rec"));
recLabel2->setFixedHeight(18);
layout1->addMultiCellWidget( recLabel2, 0, 0, 7, 7);
Rec_PushButton = new QPushButton( tab, "Rec_PushButton" );
layout1->addMultiCellWidget( Rec_PushButton, 1, 1, 7, 7);
Rec_PushButton->setFixedSize(22,22);
Rec_PushButton->setPixmap( image6 );
t = new QTimer( this );
connect( t, SIGNAL( timeout() ), SLOT( timerBreak() ) );
rewindTimer = new QTimer( this );
connect( rewindTimer, SIGNAL( timeout() ), SLOT( rewindTimerTimeout() ) );
forwardTimer = new QTimer( this );
connect( forwardTimer, SIGNAL( timeout() ), SLOT( forwardTimerTimeout() ) );
deleteSoundButton = new QPushButton( tab, "deleteSoundButton" );
layout1->addMultiCellWidget( deleteSoundButton, 1, 1, 8, 8);
deleteSoundButton->setText( tr( "Delete" ) );
ListView1 = new QListView( tab, "IconView1" );
layout1->addMultiCellWidget( ListView1, 2, 2, 0, 8);
ListView1->addColumn( tr( "Name" ) );
ListView1->setColumnWidth(0,140);
ListView1->setSorting( 1, false);
ListView1->addColumn( tr( "Time" ) ); //in seconds
ListView1->setColumnWidth(1,50);
ListView1->addColumn( tr("Location") );
ListView1->setColumnWidth(2,50);
ListView1->addColumn( tr("Date") );
ListView1->setColumnWidth(3,63);
ListView1->setColumnWidthMode(0,QListView::Manual);
ListView1->setColumnAlignment(1,QListView::AlignCenter);
ListView1->setColumnAlignment(2,QListView::AlignRight);
ListView1->setColumnAlignment(3,QListView::AlignLeft);
ListView1->setAllColumnsShowFocus( true );
QPEApplication::setStylusOperation( ListView1->viewport(),QPEApplication::RightOnHold);
TabWidget->insertTab( tab, tr( "Files" ) );
///**********<<<<<<<<<<<<>>>>>>>>>>>>***************
tab_3 = new QWidget( TabWidget, "tab_3" );
////////////////////////////////////
Layout19 = new QHBoxLayout( tab_3);
Layout19->setSpacing( 2 );
Layout19->setMargin( 0 );
Layout18 = new QVBoxLayout(this);
Layout18->setSpacing( 2 );
Layout18->setMargin( 0 );
Layout17 = new QHBoxLayout(this);
Layout17->setSpacing( 2 );
Layout17->setMargin( 0 );
sampleGroup = new QGroupBox( tab_3, "samplegroup" );
sampleGroup->setTitle( tr( "Sample Rate" ) );
sampleGroup->setFixedSize( 95,50);
sampleRateComboBox = new QComboBox( false, sampleGroup, "SampleRateComboBox" );
diff --git a/noncore/multimedia/opierec/waveform.cpp b/noncore/multimedia/opierec/waveform.cpp
new file mode 100644
index 0000000..05be373
--- a/dev/null
+++ b/noncore/multimedia/opierec/waveform.cpp
@@ -0,0 +1,160 @@
+/**********************************************************************
+ ** 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.
+ **
+ **********************************************************************/
+#include "waveform.h"
+
+#include <qlabel.h>
+#include <qpainter.h>
+
+
+Waveform::Waveform( QWidget *parent, const char *name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ pixmap = 0;
+ windowSize = 100;
+ samplesPerPixel = 8000 / (5 * windowSize);
+ currentValue = 0;
+ numSamples = 0;
+ windowPosn = 0;
+ window = 0;
+}
+
+
+void Waveform::changeSettings( int frequency, int channels )
+{
+ makePixmap();
+// qWarning("change waveform %d, %d", frequency, channels);
+ samplesPerPixel = frequency * channels / (5 * windowSize);
+ qWarning("Waveform::changeSettings %d", samplesPerPixel);
+ if ( !samplesPerPixel )
+ samplesPerPixel = 1;
+ currentValue = 0;
+ numSamples = 0;
+ windowPosn = 0;
+ draw();
+}
+
+
+Waveform::~Waveform()
+{
+ if ( window )
+ delete[] window;
+ if ( pixmap )
+ delete pixmap;
+}
+
+
+void Waveform::reset()
+{
+ makePixmap();
+ currentValue = 0;
+ numSamples = 0;
+ windowPosn = 0;
+ draw();
+}
+
+
+void Waveform::newSamples( const short *buf, int len )
+{
+ // Cache the object values in local variables.
+ int samplesPerPixel = this->samplesPerPixel;
+ int currentValue = this->currentValue;
+ int numSamples = this->numSamples;
+ short *window = this->window;
+ int windowPosn = this->windowPosn;
+ int windowSize = this->windowSize;
+
+ // Average the incoming samples to scale them to the window.
+ while ( len > 0 ) {
+ currentValue += *buf++;
+ --len;
+ if ( ++numSamples >= samplesPerPixel ) {
+ window[windowPosn++] = (short)(currentValue / numSamples);
+ if ( windowPosn >= windowSize ) {
+ this->windowPosn = windowPosn;
+ draw();
+ windowPosn = 0;
+ }
+ numSamples = 0;
+ currentValue = 0;
+ }
+ }
+
+ // Copy the final state back to the object.
+//qWarning("%d, %d, %d", currentValue, numSamples, windowPosn);
+ this->currentValue = currentValue;
+ this->numSamples = numSamples;
+ this->windowPosn = windowPosn;
+}
+
+
+void Waveform::makePixmap()
+{
+ if ( !pixmap ) {
+ pixmap = new QPixmap( size() );
+ windowSize = pixmap->width();
+ window = new short [windowSize];
+ }
+}
+
+
+void Waveform::draw()
+{
+ pixmap->fill( Qt::black );
+ QPainter painter;
+ painter.begin( pixmap );
+ painter.setPen( Qt::green );
+
+ int middle = pixmap->height() / 2;
+ int mag;
+ short *window = this->window;
+ int posn;
+ int size = windowPosn;
+ for( posn = 0; posn < size; ++posn )
+ {
+ mag = (window[posn] * middle / 32768);
+ painter.drawLine(posn, middle - mag, posn, middle + mag);
+ }
+ if ( windowPosn < windowSize )
+ {
+ painter.drawLine(windowPosn, middle, windowSize, middle);
+ }
+
+ painter.end();
+
+ paintEvent( 0 );
+}
+
+
+void Waveform::paintEvent( QPaintEvent * )
+{
+ QPainter painter;
+ painter.begin( this );
+
+ if ( pixmap ) {
+ painter.drawPixmap( 0, 0, *pixmap );
+ } else {
+ painter.setPen( Qt::green );
+ QSize sz = size();
+ painter.drawLine(0, sz.height() / 2, sz.width(), sz.height() / 2);
+ }
+
+ painter.end();
+}
+
diff --git a/noncore/multimedia/opierec/waveform.h b/noncore/multimedia/opierec/waveform.h
new file mode 100644
index 0000000..b9a4c70
--- a/dev/null
+++ b/noncore/multimedia/opierec/waveform.h
@@ -0,0 +1,63 @@
+/**********************************************************************
+** 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.
+**
+**********************************************************************/
+#ifndef WAVEFORM_H
+#define WAVEFORM_H
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+
+class QLabel;
+
+
+class Waveform : public QWidget
+{
+public:
+ Waveform( QWidget *parent=0, const char *name=0, WFlags fl=0 );
+ ~Waveform();
+
+public:
+ void changeSettings( int frequency, int channels );
+ void reset();
+ void newSamples( const short *buf, int len );
+
+private:
+
+ void makePixmap();
+ void draw();
+
+protected:
+
+ void paintEvent( QPaintEvent *event );
+
+private:
+ int samplesPerPixel;
+ int currentValue;
+ int numSamples;
+ short *window;
+ int windowPosn;
+ int windowSize;
+ QPixmap *pixmap;
+
+};
+
+
+#endif
+