mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-05 17:11:40 -05:00
-debugging strange audio distortion
This commit is contained in:
parent
58d75b16a0
commit
3c765ba4cb
12 changed files with 116 additions and 62 deletions
|
@ -2,13 +2,15 @@
|
||||||
#ifndef LUPPP_AUDIO_PROCESSOR_H
|
#ifndef LUPPP_AUDIO_PROCESSOR_H
|
||||||
#define LUPPP_AUDIO_PROCESSOR_H
|
#define LUPPP_AUDIO_PROCESSOR_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
class AudioProcessor
|
class AudioProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AudioProcessor(){}
|
AudioProcessor(){}
|
||||||
|
|
||||||
/// copies the track output to master buffer, sidechain & post-side buffer
|
/// copies the track output to master buffer, sidechain & post-side buffer
|
||||||
virtual void process(int nframes, Buffers* buffers){}
|
virtual void process(int nframes, Buffers* buffers){printf("AudioProcessor::process() not derived\n");}
|
||||||
|
|
||||||
/// set main mix, 0-1
|
/// set main mix, 0-1
|
||||||
virtual void setMaster(float value){}
|
virtual void setMaster(float value){}
|
||||||
|
|
|
@ -383,12 +383,12 @@ class ClipSelector : public Fl_Button
|
||||||
writeToDspRingbuffer( &e );
|
writeToDspRingbuffer( &e );
|
||||||
clips[clipNum].record();
|
clips[clipNum].record();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else if ( clipNum == stopQueuedClip )
|
else if ( clipNum == stopQueuedClip )
|
||||||
{
|
{
|
||||||
playingClip = -1;
|
playingClip = -1;
|
||||||
}
|
}
|
||||||
*
|
|
||||||
else if ( clips[clipNum].loaded() )
|
else if ( clips[clipNum].loaded() )
|
||||||
{
|
{
|
||||||
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_PLAY_QUEUED);
|
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_PLAY_QUEUED);
|
||||||
|
|
|
@ -117,7 +117,7 @@ class RadialStatus : public Fl_Slider
|
||||||
}
|
}
|
||||||
|
|
||||||
// inside circle
|
// inside circle
|
||||||
cairo_set_source_rgba(cr,0.3,0.3,0.3, 0.8);
|
cairo_set_source_rgba(cr,0.3,0.3,0.3, 1);
|
||||||
cairo_arc(cr, x + xc, y + yc, 10, 0, 2 * 3.1415);
|
cairo_arc(cr, x + xc, y + yc, 10, 0, 2 * 3.1415);
|
||||||
cairo_set_line_width(cr, 4.2);
|
cairo_set_line_width(cr, 4.2);
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
|
|
|
@ -10,8 +10,13 @@ class Buffers
|
||||||
public:
|
public:
|
||||||
Buffers()
|
Buffers()
|
||||||
{
|
{
|
||||||
memset( audio, 0, sizeof(float*)*32);
|
for(int i = 0; i < 32; i++)
|
||||||
memset( midi , 0, sizeof(void *)*32);
|
{
|
||||||
|
audio[i] = 0;
|
||||||
|
midi [i] = 0;
|
||||||
|
}
|
||||||
|
//memset( audio, 0, sizeof(float*)*32);
|
||||||
|
//memset( midi , 0, sizeof(void *)*32);
|
||||||
}
|
}
|
||||||
float* audio[32];
|
float* audio[32];
|
||||||
void* midi [32];
|
void* midi [32];
|
||||||
|
|
|
@ -63,6 +63,7 @@ void handleGuiEvents()
|
||||||
if ( availableRead >= sizeof(EventLooperProgress) ) {
|
if ( availableRead >= sizeof(EventLooperProgress) ) {
|
||||||
EventLooperProgress ev;
|
EventLooperProgress ev;
|
||||||
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) );
|
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) );
|
||||||
|
printf("progress on %i, %f\n", ev.track, ev.progress);
|
||||||
gui->getTrack(ev.track)->radial.value(ev.progress);
|
gui->getTrack(ev.track)->radial.value(ev.progress);
|
||||||
//jack->setLooperLoopLength( ev.track, ev.scale );
|
//jack->setLooperLoopLength( ev.track, ev.scale );
|
||||||
} break; }
|
} break; }
|
||||||
|
|
|
@ -19,7 +19,6 @@ int AudioBuffer::privateID = 0;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
extern Gui* gui;
|
extern Gui* gui;
|
||||||
extern Jack* jack;
|
|
||||||
|
|
||||||
|
|
||||||
void luppp_tooltip(std::string s)
|
void luppp_tooltip(std::string s)
|
||||||
|
@ -48,12 +47,6 @@ static void gui_static_read_rb(void* inst)
|
||||||
Fl::repeat_timeout( 1 / 30.f, &gui_static_read_rb, inst);
|
Fl::repeat_timeout( 1 / 30.f, &gui_static_read_rb, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gui_jack_activate(void* inst)
|
|
||||||
{
|
|
||||||
cout << "GUI: Jack activate called now\n" << endl;
|
|
||||||
jack->activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
Gui::Gui() :
|
Gui::Gui() :
|
||||||
window(1110,650)
|
window(1110,650)
|
||||||
{
|
{
|
||||||
|
@ -97,8 +90,6 @@ int Gui::show()
|
||||||
|
|
||||||
gui_static_read_rb( this );
|
gui_static_read_rb( this );
|
||||||
|
|
||||||
Fl::repeat_timeout( 1, &gui_jack_activate, 0 );
|
|
||||||
|
|
||||||
return Fl::run();
|
return Fl::run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
49
src/jack.cxx
49
src/jack.cxx
|
@ -54,22 +54,21 @@ Jack::Jack()
|
||||||
|
|
||||||
|
|
||||||
/// prepare internal buffers
|
/// prepare internal buffers
|
||||||
buffers.audio[Buffers::REVERB] = (float*) malloc( sizeof(float) * nframes );
|
buffers.audio[Buffers::REVERB] = new float( nframes );
|
||||||
buffers.audio[Buffers::SIDECHAIN] = (float*) malloc( sizeof(float) * nframes );
|
buffers.audio[Buffers::SIDECHAIN] = new float( nframes );
|
||||||
buffers.audio[Buffers::POST_SIDECHAIN] = (float*) malloc( sizeof(float) * nframes );
|
buffers.audio[Buffers::POST_SIDECHAIN] = new float( nframes );
|
||||||
buffers.audio[Buffers::MASTER_OUTPUT] = (float*) malloc( sizeof(float) * nframes );
|
buffers.audio[Buffers::MASTER_OUTPUT] = new float( nframes );
|
||||||
|
|
||||||
|
printf("Master output buffer on alloc() %i\n", buffers.audio[Buffers::MASTER_OUTPUT] );
|
||||||
|
|
||||||
for(int i = 0; i < NTRACKS; i++)
|
for(int i = 0; i < NTRACKS; i++)
|
||||||
{
|
{
|
||||||
loopers.push_back( new Looper(i) );
|
loopers.push_back( new Looper(i) );
|
||||||
timeManager.registerObserver( loopers.at(i) );
|
timeManager.registerObserver( loopers.back() );
|
||||||
|
|
||||||
buffers.audio[Buffers::TRACK_0 + i] = (float*) malloc( sizeof(float) * nframes );
|
trackOutputs.push_back( new TrackOutput(i, loopers.back() ) );
|
||||||
}
|
|
||||||
|
//buffers.audio[Buffers::TRACK_0 + i] = new float( nframes ); // (float*) malloc( sizeof(float) * nframes );
|
||||||
for( int i = 0; i < NTRACKS; i++)
|
|
||||||
{
|
|
||||||
trackOutputs.push_back( new TrackOutput(i, loopers.at(i) ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timeManager.registerObserver( &metronome );
|
timeManager.registerObserver( &metronome );
|
||||||
|
@ -107,23 +106,19 @@ void Jack::activate()
|
||||||
int Jack::process (jack_nframes_t nframes)
|
int Jack::process (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
// get buffers
|
// get buffers
|
||||||
buffers.audio[Buffers::MASTER_INPUT] = (float*)jack_port_get_buffer( masterInput , nframes);
|
buffers.audio[Buffers::MASTER_INPUT] = (float*)jack_port_get_buffer( masterInput , nframes );
|
||||||
buffers.audio[Buffers::JACK_MASTER_OUTPUT]=(float*)jack_port_get_buffer(masterOutput, nframes);
|
buffers.audio[Buffers::JACK_MASTER_OUTPUT] = (float*)jack_port_get_buffer( masterOutput , nframes );
|
||||||
buffers.midi[Buffers::MASTER_MIDI_INPUT]= (void*) jack_port_get_buffer( masterMidiInput, nframes );
|
buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes );
|
||||||
buffers.midi[Buffers::APC_INPUT] = (void*) jack_port_get_buffer( apcMidiInput , nframes );
|
buffers.midi [Buffers::APC_INPUT] = (void*) jack_port_get_buffer( apcMidiInput , nframes );
|
||||||
buffers.midi[Buffers::APC_OUTPUT] = (void*) jack_port_get_buffer( apcMidiOutput , nframes );
|
buffers.midi [Buffers::APC_OUTPUT] = (void*) jack_port_get_buffer( apcMidiOutput , nframes );
|
||||||
|
|
||||||
|
|
||||||
// pre-zero output buffers
|
// pre-zero output buffers
|
||||||
memset( buffers.audio[Buffers::MASTER_OUTPUT], 0, sizeof(float) * nframes );
|
memset( buffers.audio[Buffers::MASTER_OUTPUT] , 0, sizeof(float) * nframes );
|
||||||
memset( buffers.audio[Buffers::JACK_MASTER_OUTPUT],0,sizeof(float)*nframes);
|
memset( buffers.audio[Buffers::JACK_MASTER_OUTPUT], 0, sizeof(float) * nframes );
|
||||||
memset( buffers.audio[Buffers::REVERB] , 0, sizeof(float) * nframes );
|
memset( buffers.audio[Buffers::REVERB] , 0, sizeof(float) * nframes );
|
||||||
memset( buffers.audio[Buffers::SIDECHAIN] , 0, sizeof(float) * nframes );
|
memset( buffers.audio[Buffers::SIDECHAIN] , 0, sizeof(float) * nframes );
|
||||||
memset( buffers.audio[Buffers::POST_SIDECHAIN],0, sizeof(float) * nframes );
|
memset( buffers.audio[Buffers::POST_SIDECHAIN] , 0, sizeof(float) * nframes );
|
||||||
|
|
||||||
for(int i = 0; i < NTRACKS; i++)
|
|
||||||
{
|
|
||||||
memset( buffers.audio[Buffers::TRACK_0 + i], 0, sizeof(float) * nframes );
|
|
||||||
}
|
|
||||||
|
|
||||||
jack_midi_clear_buffer( buffers.midi[Buffers::APC_OUTPUT] );
|
jack_midi_clear_buffer( buffers.midi[Buffers::APC_OUTPUT] );
|
||||||
|
|
||||||
|
@ -156,7 +151,9 @@ int Jack::process (jack_nframes_t nframes)
|
||||||
|
|
||||||
// process each track, starting at output and working up signal path
|
// process each track, starting at output and working up signal path
|
||||||
for(uint i = 0; i < NTRACKS; i++)
|
for(uint i = 0; i < NTRACKS; i++)
|
||||||
|
{
|
||||||
loopers.at(i)->process( nframes, &buffers );
|
loopers.at(i)->process( nframes, &buffers );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// process fx
|
// process fx
|
||||||
|
|
|
@ -12,11 +12,20 @@
|
||||||
extern Jack* jack;
|
extern Jack* jack;
|
||||||
|
|
||||||
Looper::Looper(int t) :
|
Looper::Looper(int t) :
|
||||||
track(t)
|
AudioProcessor(),
|
||||||
|
Observer(),
|
||||||
|
track(t),
|
||||||
|
uiUpdateConstant(44100/30.f),
|
||||||
|
uiUpdateCounter(44100/30.f)
|
||||||
{
|
{
|
||||||
// pre-zero the internal sample
|
// pre-zero the internal sample
|
||||||
tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE );
|
//tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE );
|
||||||
memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE );
|
//memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE );
|
||||||
|
|
||||||
|
for(int i = 0; i < 10; i++ )
|
||||||
|
{
|
||||||
|
clips[i] = new LooperClip();
|
||||||
|
}
|
||||||
|
|
||||||
// init faust pitch shift variables
|
// init faust pitch shift variables
|
||||||
fSamplingFreq = 44100;
|
fSamplingFreq = 44100;
|
||||||
|
@ -34,7 +43,7 @@ Looper::Looper(int t) :
|
||||||
|
|
||||||
LooperClip* Looper::getClip(int scene)
|
LooperClip* Looper::getClip(int scene)
|
||||||
{
|
{
|
||||||
return &clips[scene];
|
return clips[scene];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::midi(unsigned char* data)
|
void Looper::midi(unsigned char* data)
|
||||||
|
@ -138,7 +147,7 @@ void Looper::updateControllers()
|
||||||
|
|
||||||
void Looper::setSample(int scene, AudioBuffer* ab)
|
void Looper::setSample(int scene, AudioBuffer* ab)
|
||||||
{
|
{
|
||||||
clips[scene].load( ab );
|
clips[scene]->load( ab );
|
||||||
/*
|
/*
|
||||||
vector<float>& buf = ab->getData();
|
vector<float>& buf = ab->getData();
|
||||||
if ( buf.size() > SAMPLE_SIZE )
|
if ( buf.size() > SAMPLE_SIZE )
|
||||||
|
@ -176,7 +185,7 @@ void Looper::process(int nframes, Buffers* buffers)
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// using the track output causes distortion: clipping / not proper writing.
|
// using the track output causes distortion: clipping / not proper writing.
|
||||||
// writing to master fixes issue, so its due to trackOutput or Looper writing...?
|
// writing to master fixes issue, so its due to trackOutput or Looper writing...?
|
||||||
float* trk = buffers->audio[Buffers::TRACK_0 + track];
|
//float* trk = buffers->audio[Buffers::TRACK_0 + track];
|
||||||
float* out = buffers->audio[Buffers::MASTER_OUTPUT];
|
float* out = buffers->audio[Buffers::MASTER_OUTPUT];
|
||||||
|
|
||||||
// process each clip individually: this allows for playback of one clip,
|
// process each clip individually: this allows for playback of one clip,
|
||||||
|
@ -185,22 +194,34 @@ void Looper::process(int nframes, Buffers* buffers)
|
||||||
{
|
{
|
||||||
// handle state of clip, and do what needs doing:
|
// handle state of clip, and do what needs doing:
|
||||||
// record into buffer, play from buffer, etc
|
// record into buffer, play from buffer, etc
|
||||||
if ( clips[i].recording() )
|
if ( clips[i]->recording() )
|
||||||
{
|
{
|
||||||
// copy data from input buffer to recording buffer
|
// copy data from input buffer to recording buffer
|
||||||
|
|
||||||
if ( clips[i].nframesAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST )
|
if ( clips[i]->nframesAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST )
|
||||||
{
|
{
|
||||||
// request bigger buffer for this track/scene
|
// request bigger buffer for this track/scene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( clips[i].playing() )
|
else if ( clips[i]->playing() )
|
||||||
{
|
{
|
||||||
|
//printf("Looper %i playing()\n", track );
|
||||||
// copy data into tmpBuffer, then pitch-stretch into track buffer
|
// copy data into tmpBuffer, then pitch-stretch into track buffer
|
||||||
for(int i = 0; i < nframes; i++ )
|
for(int c = 0; c < nframes; c++ )
|
||||||
{
|
{
|
||||||
out[i] += clips[i].getSample();
|
|
||||||
|
out[i] = clips[i]->getSample(); // sin( clips[i]->getProgress() * 440 * 6.24 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update UI of progress
|
||||||
|
if ( uiUpdateCounter > uiUpdateConstant )
|
||||||
|
{
|
||||||
|
EventLooperProgress e(track, clips[i]->getProgress() );
|
||||||
|
writeToGuiRingbuffer( &e );
|
||||||
|
//printf("writing event\n");
|
||||||
|
uiUpdateCounter = 0;
|
||||||
|
}
|
||||||
|
uiUpdateCounter += nframes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ using namespace std;
|
||||||
* The class which reads from LooperClips, and reads/ writes the data using the
|
* The class which reads from LooperClips, and reads/ writes the data using the
|
||||||
* track buffer. Scene recording / playback is the essential functionality here.
|
* track buffer. Scene recording / playback is the essential functionality here.
|
||||||
**/
|
**/
|
||||||
class Looper : public Observer, public AudioProcessor
|
class Looper : public AudioProcessor, public Observer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Looper(int t);
|
Looper(int t);
|
||||||
|
@ -44,7 +44,7 @@ class Looper : public Observer, public AudioProcessor
|
||||||
const int track;
|
const int track;
|
||||||
|
|
||||||
float* tmpRecordBuffer;
|
float* tmpRecordBuffer;
|
||||||
LooperClip clips[10];
|
LooperClip* clips[10];
|
||||||
|
|
||||||
// Pitch Shifting
|
// Pitch Shifting
|
||||||
void pitchShift(int count, float* input, float* output);
|
void pitchShift(int count, float* input, float* output);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#ifndef LUPPP_LOOPER_CLIP_H
|
#ifndef LUPPP_LOOPER_CLIP_H
|
||||||
#define LUPPP_LOOPER_CLIP_H
|
#define LUPPP_LOOPER_CLIP_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "audiobuffer.hxx"
|
#include "audiobuffer.hxx"
|
||||||
|
|
||||||
/** LooperClip
|
/** LooperClip
|
||||||
|
@ -31,15 +32,24 @@ class LooperClip
|
||||||
|
|
||||||
_buffer = 0;
|
_buffer = 0;
|
||||||
|
|
||||||
index = 0;
|
_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// loads a sample: eg from disk
|
// loads a sample: eg from disk
|
||||||
void load( AudioBuffer* ab )
|
void load( AudioBuffer* ab )
|
||||||
{
|
{
|
||||||
_loaded = true;
|
_loaded = true;
|
||||||
|
|
||||||
|
if ( _buffer )
|
||||||
|
{
|
||||||
|
// unload old buffer!
|
||||||
|
printf("LooperClip: FIXME:TODO de-allocate old sample here!\n");
|
||||||
|
}
|
||||||
|
|
||||||
_buffer = ab;
|
_buffer = ab;
|
||||||
|
|
||||||
|
_index = 0;
|
||||||
|
|
||||||
_playing = true;
|
_playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,16 +64,43 @@ class LooperClip
|
||||||
// write "count" samples into current buffer. If the last
|
// write "count" samples into current buffer. If the last
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int nframesAvailable()
|
int nframesAvailable()
|
||||||
{
|
{
|
||||||
// return amount of space left to record
|
// return amount of space left to record
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool loaded(){return _loaded;}
|
bool loaded(){return _loaded;}
|
||||||
bool playing(){return _playing;}
|
bool playing(){return _playing;}
|
||||||
bool recording(){return _recording;}
|
bool recording(){return _recording;}
|
||||||
|
|
||||||
float getSample(){return _buffer->getData().at(index++);}
|
float getSample()
|
||||||
|
{
|
||||||
|
if ( _buffer )
|
||||||
|
{
|
||||||
|
if ( _index >= _buffer->getData().size() || _index < 0 )
|
||||||
|
{
|
||||||
|
_index = 0;
|
||||||
|
}
|
||||||
|
float tmp = _buffer->getData().at(_index);
|
||||||
|
_index++;
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getProgress()
|
||||||
|
{
|
||||||
|
if ( _buffer )
|
||||||
|
{
|
||||||
|
return float(_index) / _buffer->getData().size();
|
||||||
|
}
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
void clipLength(int l){_clipLenght = l;}
|
void clipLength(int l){_clipLenght = l;}
|
||||||
|
@ -73,7 +110,7 @@ class LooperClip
|
||||||
bool _recording;
|
bool _recording;
|
||||||
bool _playing;
|
bool _playing;
|
||||||
|
|
||||||
long index;
|
unsigned int _index;
|
||||||
AudioBuffer* _buffer;
|
AudioBuffer* _buffer;
|
||||||
|
|
||||||
// Clip Properties
|
// Clip Properties
|
||||||
|
|
|
@ -40,7 +40,7 @@ int main()
|
||||||
|
|
||||||
jack = new Jack();
|
jack = new Jack();
|
||||||
|
|
||||||
//jack->activate();
|
jack->activate();
|
||||||
|
|
||||||
gui->show();
|
gui->show();
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,11 @@ class TrackOutput : public AudioProcessor
|
||||||
|
|
||||||
for(int i = 0; i < nframes; i++)
|
for(int i = 0; i < nframes; i++)
|
||||||
{
|
{
|
||||||
*reverb++ += *trackBuf * _toReverb;
|
//*reverb++ += *trackBuf * _toReverb;
|
||||||
*sidechain++ += *trackBuf * _toSidechain;
|
//*sidechain++ += *trackBuf * _toSidechain;
|
||||||
*postSidechain++ += *trackBuf * _toPostSidechain;
|
//*postSidechain++ += *trackBuf * _toPostSidechain;
|
||||||
|
|
||||||
*master++ += *trackBuf * _toMaster;
|
//*master++ += *trackBuf * _toMaster;
|
||||||
|
|
||||||
trackBuf++;
|
trackBuf++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue