Hi,at the moment my project is at a minimal level :-)
I'll try to attach the minimal of the minimal
// the main
int main(int argc, char* argv[])
{
MainWindow mainWin;
mainWin.showMaximized();
// init audio system
QTimer::singleShot( 1, AudioDevice
::getInstance(),
SLOT(init
() ) );
return app.exec();
}
// the main
int main(int argc, char* argv[])
{
QApplication app( argc, argv );
MainWindow mainWin;
mainWin.showMaximized();
// init audio system
QTimer::singleShot( 1, AudioDevice::getInstance(), SLOT(init() ) );
return app.exec();
}
To copy to clipboard, switch view to plain text mode
I create a QMainWindow containing a centralWidget
#ifndef __MAINWINDOW_H__
#define __MAINWINDOW_H__
/* system include */
#include <iostream>
#include <vector>
/* qt include */
#include <QMainWindow>
/* interfaces include */
#include "CentralWidget.h"
#include "WaveWidget.h"
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
{
Q_OBJECT
public:
MainWindow
( QWidget *parent
= 0, Qt
::WindowFlags flags
= 0 );
protected:
private slots:
void openAudioFile();
void about();
private:
void createActions();
void createMenus();
void createStatusBar();
/* Menus */
/* Actions */
CentralWidget* mp_cW;
};
#endif //__MAINWINDOW_H__
#ifndef __MAINWINDOW_H__
#define __MAINWINDOW_H__
/* system include */
#include <iostream>
#include <vector>
/* qt include */
#include <QMainWindow>
/* interfaces include */
#include "CentralWidget.h"
#include "WaveWidget.h"
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow( QWidget *parent = 0, Qt::WindowFlags flags = 0 );
protected:
virtual void closeEvent(QCloseEvent *event);
virtual void paintEvent(QPaintEvent *event);
private slots:
void openAudioFile();
void about();
private:
void createActions();
void createMenus();
void createStatusBar();
/* Menus */
QMenu* fileMenu;
QMenu* helpMenu;
/* Actions */
QAction* openAct;
QAction* exitAct;
QAction* aboutAct;
QAction* aboutQtAct;
CentralWidget* mp_cW;
};
#endif //__MAINWINDOW_H__
To copy to clipboard, switch view to plain text mode
I post only some relevant methods of MainWindow and of the rest of the classes:
MainWindow
::MainWindow( QWidget *parent, Qt
::WindowFlags flags
){
setObjectName("MainWindow");
setWindowTitle("ECP Studio");
createActions();
createMenus();
createStatusBar();
mp_cW = new CentralWidget( this );
setCentralWidget( mp_cW );
}
// I pass the audio file to the centralWidget
void MainWindow::openAudioFile()
{
if( !fileName.isEmpty() )
{
mp_cW->setSoundFile( fileName );
}
}
MainWindow::MainWindow( QWidget *parent, Qt::WindowFlags flags )
: QMainWindow(parent, flags)
{
setObjectName("MainWindow");
setWindowTitle("ECP Studio");
createActions();
createMenus();
createStatusBar();
mp_cW = new CentralWidget( this );
setCentralWidget( mp_cW );
}
// I pass the audio file to the centralWidget
void MainWindow::openAudioFile()
{
QString fileName = QFileDialog::getOpenFileName( this );
if( !fileName.isEmpty() )
{
mp_cW->setSoundFile( fileName );
}
}
To copy to clipboard, switch view to plain text mode
The centralwidget:
#include "WaveWidget.h"
class CentralWidget
: public QWidget{
public:
// ctor
CentralWidget
( QWidget* parent
= 0 );
// set the path of the sound file
void setSoundFile
( QString soundName_
);
protected:
// override paintEvent
private:
WaveWidget* mp_wave;
};
#endif //__CENTRALWIDGET_H__
#include "WaveWidget.h"
class CentralWidget : public QWidget
{
public:
// ctor
CentralWidget( QWidget* parent = 0 );
// set the path of the sound file
void setSoundFile( QString soundName_ );
protected:
// override paintEvent
virtual void paintEvent( QPaintEvent * );
private:
QVBoxLayout* mp_vBox;
WaveWidget* mp_wave;
QString m_soundName;
};
#endif //__CENTRALWIDGET_H__
To copy to clipboard, switch view to plain text mode
Again only some methods:
CentralWidget
::CentralWidget( QWidget* parent
/* = 0 */ ) mp_vBox( 0 ),
mp_wave( 0 )
{
/*vertical layout */
/* waveform visualizer */
mp_wave = new WaveWidget( this );
layout->addWidget(mp_wave);
setLayout(layout);
}
void CentralWidget
::setSoundFile( QString soundName_
) {
m_soundName = soundName_;
mp_wave->setSoundFile( m_soundName );
}
CentralWidget::CentralWidget( QWidget* parent /* = 0 */ )
: QWidget(parent),
mp_vBox( 0 ),
mp_wave( 0 )
{
/*vertical layout */
QVBoxLayout *layout = new QVBoxLayout;
/* waveform visualizer */
mp_wave = new WaveWidget( this );
layout->addWidget(mp_wave);
setLayout(layout);
}
void CentralWidget::setSoundFile( QString soundName_ )
{
m_soundName = soundName_;
mp_wave->setSoundFile( m_soundName );
}
To copy to clipboard, switch view to plain text mode
Now the waveWidget, where I would display the waveform. Its a child of the centralwidget
#include <QWidget>
#include <QMouseEvent>
#include "SoundData.h"
{
Q_OBJECT
public:
void setSoundFile
( QString soundName_
);
void setWave( SoundData* );
protected:
private:
void updateWave();
SoundData* m_wave;
};
#endif //__WAVEWIDGET_H__
#include <QWidget>
#include <QMouseEvent>
#include "SoundData.h"
class WaveWidget : public QWidget
{
Q_OBJECT
public:
WaveWidget( QWidget* parent = 0 );
void setSoundFile( QString soundName_ );
void setWave( SoundData* );
protected:
virtual void paintEvent( QPaintEvent* event );
virtual void resizeEvent ( QResizeEvent* event );
virtual void mousePressEvent( QMouseEvent *event );
virtual void mouseMoveEvent( QMouseEvent *event );
virtual void mouseReleaseEvent( QMouseEvent *event );
private:
void updateWave();
QPixmap m_waveCachePixmap;
SoundData* m_wave;
};
#endif //__WAVEWIDGET_H__
To copy to clipboard, switch view to plain text mode
It contain SoundData that's a wrapper around the sound data.
Again only some relevant methods:
/************************************************************************/
/* Constructor */
/************************************************************************/
WaveWidget
::WaveWidget( QWidget* parent
/* = 0 */ ) m_wave( 0 )
{
}
/************************************************************************/
/* setSoundFile */
/************************************************************************/
void WaveWidget
::setSoundFile( QString soundName_
) {
m_wave = new SoundData();
m_wave->loadSoundData( soundName_ );
setWave( m_wave );
}
/************************************************************************/
/* setWave */
/************************************************************************/
void WaveWidget::setWave( SoundData* w )
{
m_wave = w;
m_waveCachePixmap
= QPixmap();
// Empty the cache as the wave data has changed
int samples = m_wave->getNumSamples();
resize( samples, 500 ); // NEW NEW NEW
update(); // This triggers a paint event later on, lets Qt decide
// how and when (if your widget is hidden, etc)
}
/************************************************************************/
/* updateWave */
/************************************************************************/
void WaveWidget::updateWave()
{
int h = height();
int w = width();
// I want another width and height here.
// Also, you might to clear the cache at resize events
p.fillRect( temp.rect(), Qt::white );
p.
setRenderHint( QPainter::Antialiasing );
QPen pen
( Qt
::blue,
1 );
// blue solid line, 1 pixels wide p.setPen( pen );
// Draw the waveform or no data thingie
if( m_wave )
{
unsigned int numSamples = m_wave->getNumSamples();
int channels = m_wave->getNumChannels();
FMOD_SOUND_TYPE soundType = m_wave->getSoundType();
FMOD_SOUND_FORMAT soundFormat = m_wave->getSoundFormat();
int sampleSize = channels * ( soundFormat == PCM8 ) ? 1 : 2;
//char* stream = sound->stream;
void* soundStream = m_wave->getSoundStream();
int maxHeight = (h / 2) / channels;
int increment = (h / 2);
switch( soundFormat )
{
case PCM8: //8 bits mono
{
qDebug("PCM8 sound file");
char* audio = reinterpret_cast<char*>(soundStream);
for( unsigned int i = 0; i < numSamples ; i++ )
{
char* current = (audio) + (i * sampleSize);
char audio = *current;
float reproc = audio / (float)(1 << 8);
//DrawLine( i, 0, i, height * reproc );
//QLine line( x, startY, x, startY + Y);
//p.drawLine(line);
//startY += increment;
}
break;
}
case PCM16: //16 bits stereo (LRLRLRLR...LRLR)
{
qDebug("PCM16 sound file");
short* audio = reinterpret_cast<short*>(soundStream);
for( unsigned int i = 0; i < numSamples; i++ )
{
int startY = maxHeight;
for( int k = 0; k < channels; k++ )
{
//short* value1 = reinterpret_cast<short*>(stream + k * 2);
short* value1 = audio + k * 2;
//short* value1 = audio + k;
int x = i / ( numSamples / w);//?
int y = *value1 * maxHeight / 0x0000FFFF * 2;
QLine line
( x, startY, x, startY
+ y
);
p.drawLine(line);
startY += increment;
}
//std::cout << audio[i] << "\n";
audio += sampleSize;
}
break;
}
default:
{
qDebug("Undefined sound type");
break;
}
}
}
else
{
// Inform the user that no file has been loaded - perhaps using a
// no-data icon or something
qDebug("No data");
}
m_waveCachePixmap = temp;
}
/************************************************************************/
/* Paint event */
/************************************************************************/
{
// chiamo la updateWave solo se e' necessario se no disegno quella in cache
if( m_waveCachePixmap.isNull() )
{
updateWave();
}
p.
setRenderHint( QPainter::Antialiasing );
p.drawPixmap( 0, 0, m_waveCachePixmap );
}
/************************************************************************/
/* Resize event */
/************************************************************************/
{
m_waveCachePixmap
= QPixmap();
// I invalidate the cache update();
event->accept();
}
/************************************************************************/
/* Constructor */
/************************************************************************/
WaveWidget::WaveWidget( QWidget* parent /* = 0 */ )
: QWidget( parent ),
m_wave( 0 )
{
}
/************************************************************************/
/* setSoundFile */
/************************************************************************/
void WaveWidget::setSoundFile( QString soundName_ )
{
m_wave = new SoundData();
m_wave->loadSoundData( soundName_ );
setWave( m_wave );
}
/************************************************************************/
/* setWave */
/************************************************************************/
void WaveWidget::setWave( SoundData* w )
{
m_wave = w;
m_waveCachePixmap = QPixmap(); // Empty the cache as the wave data has changed
int samples = m_wave->getNumSamples();
resize( samples, 500 ); // NEW NEW NEW
update(); // This triggers a paint event later on, lets Qt decide
// how and when (if your widget is hidden, etc)
}
/************************************************************************/
/* updateWave */
/************************************************************************/
void WaveWidget::updateWave()
{
int h = height();
int w = width();
// I want another width and height here.
// Also, you might to clear the cache at resize events
QPixmap temp = QPixmap( w, h );
QPainter p( &temp );
p.fillRect( temp.rect(), Qt::white );
p.setRenderHint( QPainter::Antialiasing );
QPen pen( Qt::blue, 1 ); // blue solid line, 1 pixels wide
p.setPen( pen );
// Draw the waveform or no data thingie
if( m_wave )
{
unsigned int numSamples = m_wave->getNumSamples();
int channels = m_wave->getNumChannels();
FMOD_SOUND_TYPE soundType = m_wave->getSoundType();
FMOD_SOUND_FORMAT soundFormat = m_wave->getSoundFormat();
int sampleSize = channels * ( soundFormat == PCM8 ) ? 1 : 2;
//char* stream = sound->stream;
void* soundStream = m_wave->getSoundStream();
int maxHeight = (h / 2) / channels;
int increment = (h / 2);
switch( soundFormat )
{
case PCM8: //8 bits mono
{
qDebug("PCM8 sound file");
char* audio = reinterpret_cast<char*>(soundStream);
for( unsigned int i = 0; i < numSamples ; i++ )
{
char* current = (audio) + (i * sampleSize);
char audio = *current;
float reproc = audio / (float)(1 << 8);
//DrawLine( i, 0, i, height * reproc );
//QLine line( x, startY, x, startY + Y);
//p.drawLine(line);
//startY += increment;
}
break;
}
case PCM16: //16 bits stereo (LRLRLRLR...LRLR)
{
qDebug("PCM16 sound file");
short* audio = reinterpret_cast<short*>(soundStream);
for( unsigned int i = 0; i < numSamples; i++ )
{
int startY = maxHeight;
for( int k = 0; k < channels; k++ )
{
//short* value1 = reinterpret_cast<short*>(stream + k * 2);
short* value1 = audio + k * 2;
//short* value1 = audio + k;
int x = i / ( numSamples / w);//?
int y = *value1 * maxHeight / 0x0000FFFF * 2;
QLine line( x, startY, x, startY + y );
p.drawLine(line);
startY += increment;
}
//std::cout << audio[i] << "\n";
audio += sampleSize;
}
break;
}
default:
{
qDebug("Undefined sound type");
break;
}
}
}
else
{
// Inform the user that no file has been loaded - perhaps using a
// no-data icon or something
qDebug("No data");
}
m_waveCachePixmap = temp;
}
/************************************************************************/
/* Paint event */
/************************************************************************/
void WaveWidget::paintEvent( QPaintEvent* pe )
{
// chiamo la updateWave solo se e' necessario se no disegno quella in cache
if( m_waveCachePixmap.isNull() )
{
updateWave();
}
QPainter p( this );
p.setRenderHint( QPainter::Antialiasing );
p.drawPixmap( 0, 0, m_waveCachePixmap );
}
/************************************************************************/
/* Resize event */
/************************************************************************/
void WaveWidget::resizeEvent ( QResizeEvent * event )
{
m_waveCachePixmap = QPixmap(); // I invalidate the cache
update();
event->accept();
}
To copy to clipboard, switch view to plain text mode
I hope is not too much code. But with less code I don't think how you can help me.
Let me know if you would also have the soundData class, is not a problem.
I really hope you can help me.
Best Regards,
Franco
Bookmarks