/************************************************************************/
/* drawStandardPCM16 */
/************************************************************************/
void WaveDisplay::drawStandardPCM16( QPainter& painter, int numSamples )
{
int h = height();
int w = width();
// Calculate magical constants that should be left untouched unless dealing with
// other variants of PCM-Streams.
int channels = m_wave->getChannels();
int bits = m_wave->getBits();
int pcm_length = m_wave->getPcmLength();
int freq = m_wave->getFrequency();
int sample_size = channels * bits / 8;
int samples = pcm_length / sample_size; //pcm_length bytes totali del sound
int maxHeight = (h / 2) / channels;
int increment = (h / 2);
float modifier = (float)maxHeight / 0x0000FFFF * 2;
int* minValues = new int[channels];
int* maxValues = new int[channels];
//Adjust these values to obtain a different drawing scheme. Offset defines the initial sample
//where to begin drawing (it takes into account channel, sample size, bit size etc). maxSamplesOnscreen
//defines the amount of samples displayed on the screen.
int startOffset = 0;
int maxSamplesOnscreen = samples;
// Calculate the starting position in the stream where start fetching our data. And calculate
// the width between samples. By default the width truncated to the nearest integer for drawing.
// Note: doubles are needed for this calculation due floating point in-precision. Floating point
// operations have the same speed either so it's quite valid.
char* stream = (char*)m_wave->getSoundStream() + (startOffset * sample_size);
double samplesInc = 1.0f / ( maxSamplesOnscreen / (double)w);
double samplesCur = 0.0f;
//Correct the maximum samples displayed on the screen, if this step is not done we'ld be
//drawing outside the boundaries of the data stream.
maxSamplesOnscreen = (samples - startOffset) > maxSamplesOnscreen ? maxSamplesOnscreen : (samples - startOffset);
"Abort process", 0, maxSamplesOnscreen, this);
progress->setWindowModality(Qt::WindowModal);
//Iterate over each sample that lies withing the lower and upper boundaries that we precomputed. For
//every sample we draw the maximum value, and minimum value. Store the value in a temp. array and process that
//array once we detect our x is changed.
for( int i = startOffset, maxI = i + maxSamplesOnscreen, oldX = 0, x = 0; i < maxI; i++, stream += sample_size, samplesCur += samplesInc, x = samplesCur)
{
if( i % (60 * freq) == 0 ) //every minute
{
m_timePosition.append(i);// qua dovrei anche aggiungere i minuti, magari con una map
}
//Analyze the raw stream of data to determine the min and max amplitude of the sound.
for( int k = 0, j = 0; k < channels; k++, j += 2 )
{
signed short* value1 = reinterpret_cast<signed short*>(stream + j);
int y = *value1 * modifier;
maxValues[k] = y > maxValues[k] ? y : maxValues[k];
minValues[k] = y < minValues[k] ? y : minValues[k];
}
//Early out of x is the same
if( oldX == x)
continue;
oldX = x;
progress->setValue(i);
//Draw the peaks from midpoint to upper peak, and from midpoint to lower peaks
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
painter.
drawLine( midPoint,
QPoint(x, startY
+ maxValues
[k
]) );
painter.
drawLine( midPoint,
QPoint(x, startY
+ minValues
[k
]) );
maxValues[k] = minValues[k] = 0;
startY += increment;
}
}
progress->setValue( maxSamplesOnscreen );
progress->deleteLater();
//Draw a mid-based line for each channel around, so there is always 'signal displayed' used against
//double point in-precision.
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
startY += increment;
}
//Clean up the outline tables for min and max values.
delete minValues;
delete maxValues;
}
/************************************************************************/
/* drawStandardPCM16 */
/************************************************************************/
void WaveDisplay::drawStandardPCM16( QPainter& painter, int numSamples )
{
int h = height();
int w = width();
// Calculate magical constants that should be left untouched unless dealing with
// other variants of PCM-Streams.
int channels = m_wave->getChannels();
int bits = m_wave->getBits();
int pcm_length = m_wave->getPcmLength();
int freq = m_wave->getFrequency();
int sample_size = channels * bits / 8;
int samples = pcm_length / sample_size; //pcm_length bytes totali del sound
int maxHeight = (h / 2) / channels;
int increment = (h / 2);
float modifier = (float)maxHeight / 0x0000FFFF * 2;
int* minValues = new int[channels];
int* maxValues = new int[channels];
//Adjust these values to obtain a different drawing scheme. Offset defines the initial sample
//where to begin drawing (it takes into account channel, sample size, bit size etc). maxSamplesOnscreen
//defines the amount of samples displayed on the screen.
int startOffset = 0;
int maxSamplesOnscreen = samples;
// Calculate the starting position in the stream where start fetching our data. And calculate
// the width between samples. By default the width truncated to the nearest integer for drawing.
// Note: doubles are needed for this calculation due floating point in-precision. Floating point
// operations have the same speed either so it's quite valid.
char* stream = (char*)m_wave->getSoundStream() + (startOffset * sample_size);
double samplesInc = 1.0f / ( maxSamplesOnscreen / (double)w);
double samplesCur = 0.0f;
//Correct the maximum samples displayed on the screen, if this step is not done we'ld be
//drawing outside the boundaries of the data stream.
maxSamplesOnscreen = (samples - startOffset) > maxSamplesOnscreen ? maxSamplesOnscreen : (samples - startOffset);
QProgressDialog *progress = new QProgressDialog("Creating waveform...",
"Abort process", 0, maxSamplesOnscreen, this);
progress->setWindowModality(Qt::WindowModal);
//Iterate over each sample that lies withing the lower and upper boundaries that we precomputed. For
//every sample we draw the maximum value, and minimum value. Store the value in a temp. array and process that
//array once we detect our x is changed.
for( int i = startOffset, maxI = i + maxSamplesOnscreen, oldX = 0, x = 0; i < maxI; i++, stream += sample_size, samplesCur += samplesInc, x = samplesCur)
{
if( i % (60 * freq) == 0 ) //every minute
{
m_timePosition.append(i);// qua dovrei anche aggiungere i minuti, magari con una map
}
//Analyze the raw stream of data to determine the min and max amplitude of the sound.
for( int k = 0, j = 0; k < channels; k++, j += 2 )
{
signed short* value1 = reinterpret_cast<signed short*>(stream + j);
int y = *value1 * modifier;
maxValues[k] = y > maxValues[k] ? y : maxValues[k];
minValues[k] = y < minValues[k] ? y : minValues[k];
}
//Early out of x is the same
if( oldX == x)
continue;
oldX = x;
progress->setValue(i);
//Draw the peaks from midpoint to upper peak, and from midpoint to lower peaks
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
QPoint midPoint = QPoint(x, startY);
painter.drawLine( midPoint, QPoint(x, startY + maxValues[k]) );
painter.drawLine( midPoint, QPoint(x, startY + minValues[k]) );
maxValues[k] = minValues[k] = 0;
startY += increment;
}
}
progress->setValue( maxSamplesOnscreen );
progress->deleteLater();
//Draw a mid-based line for each channel around, so there is always 'signal displayed' used against
//double point in-precision.
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
painter.drawLine( QPoint(0, startY), QPoint(w, startY) );
startY += increment;
}
//Clean up the outline tables for min and max values.
delete minValues;
delete maxValues;
}
To copy to clipboard, switch view to plain text mode
Bookmarks