void SpectrumAnalyserThread::calculateSpectrum(const QByteArray &buffer,
        int inputFrequency,
        int bytesPerSample, bool isSample,char phoneme)
{
#ifndef DISABLE_FFT
    //Q_ASSERT(buffer.size() == m_numSamples * bytesPerSample);

    // Initialize data array
    const char *ptr = buffer.constData();
    for (int i=0; i<m_numSamples; ++i) {
        const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
        // Scale down to range [-1.0, 1.0]
        const DataType realSample = pcmToReal(pcmSample);
        const DataType windowedSample = realSample * m_window[i];
        m_input[i] = windowedSample;
        ptr += bytesPerSample;
    }

    // Calculate the FFT
    m_fft->calculateFFT(m_output.data(), m_input.data());

    // Analyze output to obtain amplitude and phase for each frequency

    FrequencySpectrum spectrum(SpectrumLengthSamples);
    if (isSample)
    {
        spectrum.setPhoneme(phoneme);
    }
    for (int i=2; i<=m_numSamples/2; ++i) {
        // Calculate frequency of this complex sample
        spectrum[i].frequency = qreal(i * inputFrequency) / (m_numSamples);

        const qreal real = m_output[i];
        qreal imag = 0.0;
        if (i>0 && i<m_numSamples/2)
            imag = m_output[m_numSamples/2 + i];

        const qreal magnitude = sqrt(real*real + imag*imag);
        qreal amplitude = SpectrumAnalyserMultiplier * log(magnitude);

        // Bound amplitude to [0.0, 1.0]
        spectrum[i].clipped = (amplitude > 1.0);
        amplitude = qMax(qreal(0.0), amplitude);
        amplitude = qMin(qreal(1.0), amplitude);
        spectrum[i].amplitude = amplitude;
    }

#endif
    if (!isSample)
    {
        emit calculationComplete(spectrum);
    }
    else
    {
        emit sampleLoaded(spectrum);
    }
}
Esempio n. 2
0
//计算频谱
void SpectrumAnalyserThread::calculateSpectrum(const QByteArray &buffer, int inputFrequency, int bytesPerSample)
{
#ifndef DISABLE_FFT
    Q_ASSERT(buffer.size() == m_numSamples * bytesPerSample);

    // Initialize data array
    const char *ptr = buffer.constData();
    for (int i=0; i<m_numSamples; ++i)
    {
        const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
        // Scale down to range [-1.0, 1.0]
        const DataType realSample = pcmToReal(pcmSample);
        const DataType windowedSample = realSample * m_window[i];
        m_input[i] = windowedSample;
        ptr += bytesPerSample;
    }

    // Calculate the FFT快速傅里叶变换
    m_fft ->calculateFFT(m_output.data(), m_input.data());

    // Analyze output to obtain amplitude and phase for each frequency
    for (int i = 2; i <= m_numSamples / 2; ++i)
    {
        // Calculate frequency of this complex sample
        m_spectrum[i].frequency = double(i * inputFrequency) / (m_numSamples);

        const double real = m_output[i];
        double imag = 0.0;
        if (i > 0 && i < m_numSamples / 2)
        {
            imag = m_output[m_numSamples / 2 + i];
        }

        const double magnitude = sqrt(real * real + imag * imag);
        double amplitude = SpectrumAnalyserMultiplier * log(magnitude);

        // Bound amplitude to [0.0, 1.0]
        m_spectrum[i].clipped = (amplitude > 1.0);
        amplitude = qMax(double(0.0), amplitude);
        amplitude = qMin(double(1.0), amplitude);
        m_spectrum[i].amplitude = amplitude;
    }
#endif

    emit calculationComplete(m_spectrum);	//发射计算完成信号
}
void SpectrumAnalyserThread::calculateSpectrum(const QByteArray &buffer, int inputFrequency, int bytesPerSample) {

    Q_ASSERT(buffer.size() == m_numSamples * bytesPerSample);

    // Initialize data array
    const char *ptr = buffer.constData();
    for (int i = 0; i < m_numSamples; ++i) {
		
		const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
        // Scale down to range [-1.0, 1.0]
        const DataType realSample = pcmToReal(pcmSample);
        const DataType windowedSample = realSample * m_window[i];
        m_input[i] = windowedSample;
		m_cpxInput[i].re = windowedSample;
		m_cpxInput[i].im = 0.0f;
        ptr += bytesPerSample;
    }

    // Calculate the FFT
    m_fft->DoFFTWForward(m_cpxInput, m_cpxOutput, SpectrumLengthSamples);

    // Analyze output to obtain amplitude and phase for each frequency
    for (int i = 2; i <= m_numSamples / 2; ++i) {
        // Calculate frequency of this complex sample
        m_spectrum[i].frequency = qreal(i * inputFrequency) / (m_numSamples);

        //const qreal real = m_output[i];
		const qreal real = m_cpxOutput[i].re;
        qreal imag = 0.0;
        if (i > 0 && i < m_numSamples / 2)
            //imag = m_output[m_numSamples/2 + i];
			imag = m_cpxOutput[m_numSamples/2 + i].re;

        const qreal magnitude = sqrt(real*real + imag*imag);
        qreal amplitude = SpectrumAnalyserMultiplier * log(magnitude);

        // Bound amplitude to [0.0, 1.0]
        m_spectrum[i].clipped = (amplitude > 1.0);
        amplitude = qMax(qreal(0.0), amplitude);
        amplitude = qMin(qreal(1.0), amplitude);
        m_spectrum[i].amplitude = amplitude;
    }

    emit calculationComplete(m_spectrum);
}
Esempio n. 4
0
void Waveform::paintTile(int index)
{
    const qint64 tileStart = m_tileArrayStart + index * m_tileLength;

    WAVEFORM_DEBUG << "Waveform::paintTile"
                   << "index" << index
                   << "bufferPosition" << m_bufferPosition
                   << "bufferLength" << m_bufferLength
                   << "start" << tileStart
                   << "end" << tileStart + m_tileLength;

    Q_ASSERT(m_bufferPosition <= tileStart);
    Q_ASSERT(m_bufferPosition + m_bufferLength >= tileStart + m_tileLength);

    Tile &tile = m_tiles[index];
    Q_ASSERT(!tile.painted);

    const qint16* base = reinterpret_cast<const qint16*>(m_buffer.constData());
    const qint16* buffer = base + ((tileStart - m_bufferPosition) / 2);
    const int numSamples = m_tileLength / (2 * m_format.channelCount());

    QPainter painter(tile.pixmap);

    painter.fillRect(tile.pixmap->rect(), Qt::black);

    QPen pen(Qt::white);
    painter.setPen(pen);

    // Calculate initial PCM value
    qint16 previousPcmValue = 0;
    if (buffer > base)
        previousPcmValue = *(buffer - m_format.channelCount());

    // Calculate initial point
    const qreal previousRealValue = pcmToReal(previousPcmValue);
    const int originY = ((previousRealValue + 1.0) / 2) * m_pixmapSize.height();
    const QPoint origin(0, originY);

    QLine line(origin, origin);

    for (int i=0; i<numSamples; ++i) {
        const qint16* ptr = buffer + i * m_format.channelCount();

        const int offset = reinterpret_cast<const char*>(ptr) - m_buffer.constData();
        Q_ASSERT(offset >= 0);
        Q_ASSERT(offset < m_bufferLength);
        Q_UNUSED(offset);

        const qint16 pcmValue = *ptr;
        const qreal realValue = pcmToReal(pcmValue);

        const int x = tilePixelOffset(i * 2 * m_format.channelCount());
        const int y = ((realValue + 1.0) / 2) * m_pixmapSize.height();

        line.setP2(QPoint(x, y));
        painter.drawLine(line);
        line.setP1(line.p2());
    }

    tile.painted = true;
}
void SpectrumAnalyserThread::calculateTotalSpectrum(const QByteArray &buffer, int inputFrequency, int bytesPerSample) {

	if (m_spectrumList.count() > 0)
		m_spectrumList.clear();

	int samples = bytesPerSample * m_numSamples;
	int buffers = qRound((float) buffer.size() / samples);

	// cycle over all buffers
	for (int i = 0; i < buffers; i++) {
		
		//if (i == buffers-1 && overhead > 0)
		m_tmp = QByteArray::fromRawData(buffer.constData() + i * samples, samples);
		
		//Q_ASSERT(m_tmp.size() == m_numSamples * bytesPerSample);

		// Initialize data array
		const char *ptr = m_tmp.constData();
		
		for (int j = 0; j < m_numSamples; ++j) {

			const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
			// Scale down to range [-1.0, 1.0]
			const DataType realSample = pcmToReal(pcmSample);
			const DataType windowedSample = realSample * m_window[j];
	
			m_cpxInput[j].re = windowedSample;
			m_cpxInput[j].im = 0.0f;
			
			ptr += bytesPerSample;
		}

		// calculate the FFT
		m_fft->DoFFTWForward(m_cpxInput, m_cpxOutput, SpectrumLengthSamples);

		/*for (int i = 0; i < BUFFER_SIZE; i += 32) {
			qDebug() << "m_cpxOutput.re =" << m_cpxOutput[i].re << "m_cpxOutput.im =" << m_cpxOutput[i].im;
		}*/

		// Analyze output to obtain amplitude and phase for each frequency
		for (int i = 2; i <= m_numSamples / 2; ++i) {
			
			// Calculate frequency of this complex sample
			m_spectrum[i].frequency = qreal(i * inputFrequency) / (m_numSamples);
			
			//const qreal real = m_output[i];
			const qreal real = m_cpxOutput[i].re;
			qreal imag = 0.0;
			
			if (i > 0 && i < m_numSamples / 2)				
				imag = m_cpxOutput[m_numSamples/2 + i].re;

			const qreal magnitude = sqrt(real*real + imag*imag);
			qreal amplitude = SpectrumAnalyserMultiplier * log(magnitude);
			
			// Bound amplitude to [0.0, 1.0]
			m_spectrum[i].clipped = (amplitude > 1.0);
			amplitude = qMax(qreal(0.0), amplitude);
			amplitude = qMin(qreal(1.0), amplitude);
			m_spectrum[i].amplitude = amplitude;
		}
		m_spectrumList.append(m_spectrum);
	}
	emit calculationTotalComplete(m_spectrumList);
}