Skip to content
Snippets Groups Projects
Commit e57b46ff authored by SeeLook's avatar SeeLook :musical_note:
Browse files

Adjusted offline mode, stopping thread when goes TRUE, added method...

Adjusted offline mode, stopping thread when goes TRUE, added method copyToBufferOffline that detecting in this (calling) thread.
- memcpy swapped with std::copy
- do not take -1 from framesPerChunk when copied
- simplify coping previous chunk when resetting, copy it directly to channel
parent a60f4beb
No related branches found
No related tags found
No related merge requests found
......@@ -33,7 +33,7 @@
TpitchFinder::TpitchFinder(QObject* parent) :
QObject(parent),
m_thread(new QThread),
m_filteredChunk(0), m_prevChunk(0),
m_filteredChunk(0),
m_floatBuffer(0),
m_doReset(false), m_isOffline(false),
m_channel(0),
......@@ -100,7 +100,6 @@ TpitchFinder::~TpitchFinder()
m_mutex.unlock();
if (m_filteredChunk)
delete m_filteredChunk;
delete m_prevChunk;
delete m_floatBuffer;
delete m_transforms;
if (m_channel)
......@@ -117,6 +116,11 @@ TpitchFinder::~TpitchFinder()
void TpitchFinder::setOffLine(bool off) {
if (off != m_isOffline) {
m_isOffline = off;
if (m_isOffline) {
m_doProcess = false; // terminate the thread
m_mutex.lock();
m_mutex.unlock();
}
}
}
......@@ -148,13 +152,11 @@ void TpitchFinder::setSampleRate(unsigned int sRate, int range) {
bool doReset = false;
if (oldRate != m_aGl->rate || oldFramesPerChunk != m_aGl->framesPerChunk) {
m_aGl->windowSize = 2 * m_aGl->framesPerChunk;
delete m_prevChunk;
delete m_filteredChunk;
m_filteredChunk = 0;
delete m_floatBuffer;
if (aGl()->equalLoudness)
m_filteredChunk = new float[aGl()->framesPerChunk];
m_prevChunk = new float[aGl()->framesPerChunk];
m_floatBuffer = new float[aGl()->framesPerChunk];
doReset = true;
m_chunkTime = static_cast<qreal>(aGl()->framesPerChunk) / static_cast<qreal>(aGl()->rate);
......@@ -173,7 +175,6 @@ void TpitchFinder::stop(bool resetAfter) {
m_doReset = resetAfter;
m_state = e_silence;
m_prevState = e_silence;
// emit volume(m_volume);
}
......@@ -201,7 +202,8 @@ void TpitchFinder::copyToBuffer(void* data, unsigned int nBufferFrames) {
if (m_writePos + nBufferFrames >= BUFF_SIZE)
framesToCopy = BUFF_SIZE - m_writePos;
if (framesToCopy) {
memcpy(m_tokenBuffer + m_writePos, dataPtr, framesToCopy * 2); // 2 bytes are size of qint16
std::copy(dataPtr, dataPtr + framesToCopy * 2, m_tokenBuffer + m_writePos); // 2 bytes are size of qint16
// memcpy(m_tokenBuffer + m_writePos, dataPtr, framesToCopy * 2); // 2 bytes are size of qint16
m_writePos += framesToCopy;
// qDebug() << "copied" << framesToCopy << "position" << m_writePos;
}
......@@ -209,18 +211,31 @@ void TpitchFinder::copyToBuffer(void* data, unsigned int nBufferFrames) {
m_writePos = 0;
if (framesToCopy < nBufferFrames) {
framesToCopy = nBufferFrames - framesToCopy;
memcpy(m_tokenBuffer + m_writePos, dataPtr, framesToCopy * 2); // 2 bytes are size of qint16
std::copy(dataPtr, dataPtr + framesToCopy * 2, m_tokenBuffer + m_writePos); // 2 bytes are size of qint16
// memcpy(m_tokenBuffer + m_writePos, dataPtr, framesToCopy * 2); // 2 bytes are size of qint16
m_writePos += framesToCopy;
}
}
m_framesReady += nBufferFrames;
}
void TpitchFinder::copyToBufferOffline(qint16* data) {
std::copy(data, data + aGl()->framesPerChunk * 2, m_tokenBuffer); // 2 bytes are size of qint16
// memcpy(m_tokenBuffer, data, aGl()->framesPerChunk * 2); // 2 bytes are size of qint16
m_framesReady = m_aGl->framesPerChunk;
m_doProcess = true;
detectingThread();
}
//##########################################################################################################
//########################## PROTECTED SLOTS ######################################################
//##########################################################################################################
void TpitchFinder::detectingThread() {
m_mutex.lock();
if (!m_isOffline)
m_mutex.lock();
while (m_doProcess) {
int loops = 0;
while (m_framesReady >= aGl()->framesPerChunk && loops < BUFF_SIZE / aGl()->framesPerChunk) {
......@@ -232,43 +247,49 @@ void TpitchFinder::detectingThread() {
m_workVol = qMax<float>(m_workVol, sample);
}
m_framesReady -= aGl()->framesPerChunk;
m_readPos += aGl()->framesPerChunk;
if (m_readPos >= BUFF_SIZE)
m_readPos = 0;
if (!m_isOffline) {
m_readPos += aGl()->framesPerChunk;
if (m_readPos >= BUFF_SIZE)
m_readPos = 0;
}
startPitchDetection();
processed();
loops++;
}
m_thread->usleep(500);
if (m_doReset && m_framesReady == 0 && m_chunkNum > 0)
resetFinder();
if (m_isOffline)
m_doProcess = false;
else {
m_thread->usleep(500);
if (m_doReset && m_framesReady == 0 && m_chunkNum > 0)
resetFinder();
}
}
m_mutex.unlock();
m_thread->quit();
if (!m_isOffline)
m_mutex.unlock();
if (m_thread->isRunning())
m_thread->quit();
}
void TpitchFinder::startPitchDetection() {
m_isBussy = true;
if (m_doReset) { // copy last chunk to keep capturing data continuous
if (aGl()->equalLoudness)
std::copy(m_filteredChunk, m_filteredChunk + aGl()->framesPerChunk - 1, m_prevChunk);
else
std::copy(m_workChunk, m_workChunk + aGl()->framesPerChunk - 1, m_prevChunk);
if (m_doReset) { // copy last chunk to keep capturing data continuous
resetFinder();
std::copy(m_prevChunk, m_prevChunk + aGl()->framesPerChunk - 1, m_channel->end() - aGl()->framesPerChunk);
}
m_workChunk = m_floatBuffer;
if (aGl()->equalLoudness) // initialize channel with previous data
std::copy(m_filteredChunk, m_filteredChunk + aGl()->framesPerChunk, m_channel->end() - aGl()->framesPerChunk);
else
std::copy(m_floatBuffer, m_floatBuffer + aGl()->framesPerChunk, m_channel->end() - aGl()->framesPerChunk);
}
m_channel->shift_left(aGl()->framesPerChunk); // make room in channel for new audio data
if (aGl()->equalLoudness) { // filter it and copy to channel
m_channel->highPassFilter->filter(m_workChunk, m_filteredChunk, aGl()->framesPerChunk);
for(int i = 0; i < aGl()->framesPerChunk; i++)
m_filteredChunk[i] = bound(m_filteredChunk[i], -1.0f, 1.0f);
std::copy(m_filteredChunk, m_filteredChunk + aGl()->framesPerChunk - 1, m_channel->end() - aGl()->framesPerChunk);
} else // copy without filtering
std::copy(m_workChunk, m_workChunk + aGl()->framesPerChunk - 1, m_channel->end() - aGl()->framesPerChunk);
m_channel->highPassFilter->filter(m_floatBuffer, m_filteredChunk, aGl()->framesPerChunk);
for(int i = 0; i < aGl()->framesPerChunk; i++)
m_filteredChunk[i] = bound(m_filteredChunk[i], -1.0f, 1.0f);
std::copy(m_filteredChunk, m_filteredChunk + aGl()->framesPerChunk, m_channel->end() - aGl()->framesPerChunk);
} else // copy without filtering
std::copy(m_floatBuffer, m_floatBuffer + aGl()->framesPerChunk, m_channel->end() - aGl()->framesPerChunk);
detect();
}
......
......@@ -110,6 +110,13 @@ public:
*/
void copyToBuffer(void* data, unsigned int nBufferFrames);
/**
* This method copies @p framesPerChunk from given @p data
* and performs pitch detection routines (in this thread)
* then sends appropriate signals (also in this thread)
*/
void copyToBufferOffline(qint16* data);
/**
* Informs @p TpitchFinder that audio input stops.
* Given Boolean switch decides about resetting.
......@@ -185,10 +192,11 @@ private:
private:
QThread *m_thread;
MyTransforms *m_transforms;
float *m_filteredChunk, *m_workChunk, *m_prevChunk;
float *m_floatBuffer;
qint16 *m_tokenBuffer;
unsigned int m_writePos, m_readPos;
float *m_filteredChunk; /**< audio data after high pass filter */
float *m_floatBuffer; /**< raw audio data */
qint16 *m_tokenBuffer; /**< 16k buffer to keep incoming audio data, feed in input audio thread */
unsigned int m_readPos; /** Position to read from token buffer */
unsigned int m_writePos; /** Position to write to token buffer */
volatile quint32 m_framesReady; /**< Number of frames ready for processing */
volatile bool m_doProcess, m_doReset; /**< When @p TRUE when detecting thread p */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment