Skip to content

Commit

Permalink
Finish audioport rehaul, get vol/pan knobs working again, also some b…
Browse files Browse the repository at this point in the history
…ugfixes

We're now doing the vol/pan stuff in audioport, since this way we avoid the pointless repetition of doing it in the playhandles
  • Loading branch information
diizy committed Aug 28, 2014
1 parent 722235b commit ef52363
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 59 deletions.
7 changes: 6 additions & 1 deletion include/AudioPort.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
#include "PlayHandle.h"

class EffectChain;
class FloatModel;

class AudioPort : public ThreadableJob
{
MM_OPERATORS
public:
AudioPort( const QString & _name, bool _has_effect_chain = true );
AudioPort( const QString & _name, bool _has_effect_chain = true,
FloatModel * volumeModel = NULL, FloatModel * panningModel = NULL );
virtual ~AudioPort();

inline sampleFrame * buffer()
Expand Down Expand Up @@ -120,6 +122,9 @@ class AudioPort : public ThreadableJob

PlayHandleList m_playHandles;
QMutex m_playHandleLock;

FloatModel * m_volumeModel;
FloatModel * m_panningModel;

friend class Mixer;
friend class MixerWorkerThread;
Expand Down
4 changes: 3 additions & 1 deletion include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ protected slots:


private:
AudioPort m_audioPort;
MidiPort m_midiPort;

NotePlayHandle* m_notes[NumKeys];
Expand All @@ -244,6 +243,9 @@ protected slots:

FloatModel m_volumeModel;
FloatModel m_panningModel;

AudioPort m_audioPort;

FloatModel m_pitchModel;
IntModel m_pitchRangeModel;
IntModel m_effectChannelModel;
Expand Down
14 changes: 7 additions & 7 deletions include/SampleBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#ifndef SAMPLE_BUFFER_H
#define SAMPLE_BUFFER_H

#include <QtCore/QMutex>
#include <QtCore/QReadWriteLock>
#include <QtCore/QObject>
#include <QtCore/QRect>

Expand Down Expand Up @@ -151,21 +151,21 @@ class EXPORT SampleBuffer : public QObject, public sharedObject

void setLoopStartFrame( f_cnt_t _start )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_loopStartFrame = _start;
m_varLock.unlock();
}

void setLoopEndFrame( f_cnt_t _end )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_loopEndFrame = _end;
m_varLock.unlock();
}

void setAllPointFrames( f_cnt_t _start, f_cnt_t _end, f_cnt_t _loopstart, f_cnt_t _loopend )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_startFrame = _start;
m_endFrame = _end;
m_loopStartFrame = _loopstart;
Expand Down Expand Up @@ -205,14 +205,14 @@ class EXPORT SampleBuffer : public QObject, public sharedObject

inline void setFrequency( float _freq )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_frequency = _freq;
m_varLock.unlock();
}

inline void setSampleRate( sample_rate_t _rate )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_sampleRate = _rate;
m_varLock.unlock();
}
Expand Down Expand Up @@ -291,7 +291,7 @@ public slots:
sampleFrame * m_origData;
f_cnt_t m_origFrames;
sampleFrame * m_data;
QMutex m_varLock;
QReadWriteLock m_varLock;
f_cnt_t m_frames;
f_cnt_t m_startFrame;
f_cnt_t m_endFrame;
Expand Down
2 changes: 1 addition & 1 deletion include/SampleTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ class SampleTrack : public track


private:
AudioPort m_audioPort;
FloatModel m_volumeModel;
AudioPort m_audioPort;


friend class SampleTrackView;
Expand Down
1 change: 1 addition & 0 deletions plugins/audio_file_processor/audio_file_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ void audioFileProcessor::playNote( NotePlayHandle * _n,
}
else
{
memset( _working_buffer, 0, ( frames + offset ) * sizeof( sampleFrame ) );
emit isPlaying( 0 );
}
}
Expand Down
17 changes: 10 additions & 7 deletions src/core/SampleBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void SampleBuffer::update( bool _keep_settings )
const bool lock = ( m_data != NULL );
if( lock )
{
engine::mixer()->lock();
m_varLock.lockForWrite();
MM_FREE( m_data );
}

Expand Down Expand Up @@ -262,7 +262,7 @@ void SampleBuffer::update( bool _keep_settings )

if( lock )
{
engine::mixer()->unlock();
m_varLock.unlock();
}

emit sampleUpdated();
Expand Down Expand Up @@ -598,7 +598,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
const float _freq,
const LoopMode _loopmode )
{
QMutexLocker ml( &m_varLock );
m_varLock.lockForRead();

f_cnt_t startFrame = m_startFrame;
f_cnt_t endFrame = m_endFrame;
Expand All @@ -607,6 +607,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,

if( endFrame == 0 || _frames == 0 )
{
m_varLock.unlock();
return false;
}

Expand All @@ -623,6 +624,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,

if( total_frames_for_current_pitch == 0 )
{
m_varLock.unlock();
return false;
}

Expand All @@ -639,6 +641,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
{
if( play_frame >= endFrame )
{
m_varLock.unlock();
return false;
}

Expand All @@ -655,6 +658,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
play_frame = getPingPongIndex( play_frame, loopStartFrame, loopEndFrame );
}

f_cnt_t fragment_size = (f_cnt_t)( _frames * freq_factor ) + MARGIN[ _state->interpolationMode() ];

sampleFrame * tmp = NULL;

Expand All @@ -663,7 +667,6 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
{
SRC_DATA src_data;
// Generate output
f_cnt_t fragment_size = (f_cnt_t)( _frames * freq_factor ) + MARGIN[ _state->interpolationMode() ];
src_data.data_in =
getSampleFragment( play_frame, fragment_size, _loopmode, &tmp, &is_backwards,
loopStartFrame, loopEndFrame, endFrame )[0];
Expand Down Expand Up @@ -767,8 +770,8 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
_ab[i][1] *= m_amplification;
}

m_varLock.unlock();
return true;

}


Expand Down Expand Up @@ -1364,7 +1367,7 @@ void SampleBuffer::loadFromBase64( const QString & _data )

void SampleBuffer::setStartFrame( const f_cnt_t _s )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_startFrame = _s;
m_varLock.unlock();
}
Expand All @@ -1374,7 +1377,7 @@ void SampleBuffer::setStartFrame( const f_cnt_t _s )

void SampleBuffer::setEndFrame( const f_cnt_t _e )
{
m_varLock.lock();
m_varLock.lockForWrite();
m_endFrame = _e;
m_varLock.unlock();
}
Expand Down
101 changes: 98 additions & 3 deletions src/core/audio/AudioPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@
#include "engine.h"
#include "MixHelpers.h"
#include "BufferManager.h"
#include "ValueBuffer.h"
#include "panning.h"


AudioPort::AudioPort( const QString & _name, bool _has_effect_chain ) :
AudioPort::AudioPort( const QString & _name, bool _has_effect_chain,
FloatModel * volumeModel, FloatModel * panningModel ) :
m_bufferUsage( false ),
m_portBuffer( NULL ),
m_extOutputEnabled( false ),
m_nextFxChannel( 0 ),
m_name( "unnamed port" ),
m_effects( _has_effect_chain ? new EffectChain( NULL ) : NULL )
m_effects( _has_effect_chain ? new EffectChain( NULL ) : NULL ),
m_volumeModel( volumeModel ),
m_panningModel( panningModel )
{
engine::mixer()->addAudioPort( this );
setExtOutputEnabled( true );
Expand Down Expand Up @@ -120,10 +125,100 @@ void AudioPort::doProcessing()
}
}

if( m_bufferUsage )
{
// handle volume and panning
// has both vol and pan models
if( m_volumeModel && m_panningModel )
{
ValueBuffer * volBuf = m_volumeModel->valueBuffer();
ValueBuffer * panBuf = m_panningModel->valueBuffer();

// both vol and pan have s.ex.data:
if( volBuf && panBuf )
{
for( f_cnt_t f = 0; f < fpp; ++f )
{
float v = volBuf->values()[ f ] * 0.01f;
float p = panBuf->values()[ f ] * 0.01f;
m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
}
}

// only vol has s.ex.data:
else if( volBuf )
{
float p = m_panningModel->value() * 0.01f;
float l = ( p <= 0 ? 1.0f : 1.0f - p );
float r = ( p >= 0 ? 1.0f : 1.0f + p );
for( f_cnt_t f = 0; f < fpp; ++f )
{
float v = volBuf->values()[ f ] * 0.01f;
m_portBuffer[f][0] *= v * l;
m_portBuffer[f][1] *= v * r;
}
}

// only pan has s.ex.data:
else if( panBuf )
{
float v = m_volumeModel->value() * 0.01f;
for( f_cnt_t f = 0; f < fpp; ++f )
{
float p = panBuf->values()[ f ] * 0.01f;
m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
}
}

// neither has s.ex.data:
else
{
float p = m_panningModel->value() * 0.01f;
float v = m_volumeModel->value() * 0.01f;
for( f_cnt_t f = 0; f < fpp; ++f )
{
m_portBuffer[f][0] *= ( p <= 0 ? 1.0f : 1.0f - p ) * v;
m_portBuffer[f][1] *= ( p >= 0 ? 1.0f : 1.0f + p ) * v;
}
}
}

// has vol model only
else if( m_volumeModel )
{
ValueBuffer * volBuf = m_volumeModel->valueBuffer();

if( volBuf )
{
for( f_cnt_t f = 0; f < fpp; ++f )
{
float v = volBuf->values()[ f ] * 0.01f;
m_portBuffer[f][0] *= v;
m_portBuffer[f][1] *= v;
}
}
else
{
float v = m_volumeModel->value() * 0.01f;
for( f_cnt_t f = 0; f < fpp; ++f )
{
m_portBuffer[f][0] *= v;
m_portBuffer[f][1] *= v;
}
}
}
}
// as of now there's no situation where we only have panning model but no volume model
// if we have neither, we don't have to do anything here - just pass the audio as is

// handle effects
const bool me = processEffects();
if( me || m_bufferUsage )
{
engine::fxMixer()->mixToChannel( m_portBuffer, m_nextFxChannel );
engine::fxMixer()->mixToChannel( m_portBuffer, m_nextFxChannel ); // send output to fx mixer
// TODO: improve the flow here - convert to pull model
m_bufferUsage = false;
}

Expand Down
Loading

0 comments on commit ef52363

Please sign in to comment.