Skip to content

Commit

Permalink
Oscilloscope added
Browse files Browse the repository at this point in the history
  • Loading branch information
hsaturn committed Feb 10, 2017
1 parent 17f6117 commit 6df3806
Show file tree
Hide file tree
Showing 22 changed files with 1,481 additions and 421 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 2.8.11)
project(synth)

set(CMAKE_BUILD_TYPE Debug)
# set(CMAKE_BUILD_TYPE Debug)

add_compile_options (-Wall -O4 -std=c++11)
add_subdirectory (lib)
Expand Down
1 change: 1 addition & 0 deletions bin/synth/bug.synth
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
am reverb 30:30 50 100 sinus 200:80 sq 300
Binary file added bin/synth/line
Binary file not shown.
13 changes: 13 additions & 0 deletions bin/synth/motor.synth
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
define sound
{
am
70 100
sinus 200:80
sq 300
}

reverb 30:30
{
sound
fm 10 100 sound level 0
}
Binary file added bin/synth/render
Binary file not shown.
66 changes: 63 additions & 3 deletions lib/include/libsynth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

using namespace std;

const int BUF_LENGTH = 8192;
const int BUF_LENGTH = 32768;

class SoundGenerator
{
Expand Down Expand Up @@ -53,7 +53,7 @@ class SoundGenerator
static void missingGeneratorExit(string msg="");

static void play(SoundGenerator*);
static void stop(SoundGenerator*);
static bool stop(SoundGenerator*);

// Return the number of active playing generators.
static uint16_t count(){ return list_generator_size; }
Expand Down Expand Up @@ -219,13 +219,17 @@ class WhiteNoiseGenerator : public SoundGenerator

class TriangleGenerator : public SoundGenerator
{
const int ASC=0;
const int DESC=1;
const int BIDIR=2;

public:
TriangleGenerator() : SoundGenerator("tri triangle") {}; // factory

TriangleGenerator(istream& in);

virtual void next(float &left, float &right, float speed=1.0);

virtual void reset();

protected:
virtual SoundGenerator* build(istream& in) const
Expand All @@ -237,6 +241,7 @@ class TriangleGenerator : public SoundGenerator
float a;
float da;
int sign;
uint8_t dir;
};


Expand Down Expand Up @@ -618,4 +623,59 @@ class ChainSound : public SoundGenerator
float t;
};

class Oscilloscope : public SoundGenerator
{
class Buffer
{
struct Max
{
float max;
uint32_t pos;
};

public:
Buffer(uint32_t sz, bool auto_threshold=true);

void resize(uint32_t sz)
{
}

bool fill(float left, float right);

void reset();

~Buffer()
{
delete[] buffer;
}

void render(SDL_Renderer* r, int w, int h, bool draw_left, float dx=1);

private:
uint32_t size;
uint32_t pos;
float* buffer;
Max lmax;
Max rmax;
bool auto_threshold;
};

public:
Oscilloscope();
~Oscilloscope();

Oscilloscope(istream& in);


virtual void next(float &left, float &right, float speed = 1.0);
virtual void Help(Help&) const {}

virtual SoundGenerator* build(istream &in) const
{ return new Oscilloscope(in); }

private:
Buffer* buffer;
SoundGenerator* sound;
};

#endif
168 changes: 168 additions & 0 deletions lib/src/Oscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include <libsynth.hpp>
#include <future>

Oscilloscope::Oscilloscope::Buffer::Buffer(uint32_t sz, bool auto_thr)
: size(sz), auto_threshold(auto_thr)
{
pos=0;
buffer = new float[2*sz];
}

void Oscilloscope::Oscilloscope::Buffer::reset()
{
pos = 0;
lmax.max = -9e9;
rmax.max = -9e9;
}

void Oscilloscope::Oscilloscope::Buffer::render(SDL_Renderer* r, int w, int h, bool draw_left, float dx)
{
int half = h/2;
int coeff = (h-25)/2;
SDL_SetRenderDrawColor(r, 128, 128, 255, SDL_ALPHA_OPAQUE);
SDL_RenderDrawLine(r, 0,half,w,half);
SDL_RenderDrawLine(r, w/2, 0, w/2, h);
SDL_SetRenderDrawColor(r, 0, 255, 0, SDL_ALPHA_OPAQUE);
uint32_t p;
if (draw_left)
p=lmax.pos;
else
p=rmax.pos;

// Find 0
/*
float v0=1;
while(p<pos && p<size)
{
float v=buffer[p];
if (v>v0 && v0<0 && v>=0)
break;
else
v0 = v;
p +=2;
}
if (p>=pos)
{
return; // Nothing to draw (0 not found))
} */

float x=0;

int lastx=-1;
int lasty=-1;

while(p<pos && x<w)
{
int y = h - (half + buffer[p]*coeff);

if (lastx==-1)
{
lastx = 0;
lasty = y;
}
else
{
int xx=(int)x;
if (xx > lastx)
{
SDL_RenderDrawLine(r, lastx, lasty, xx, y);
lastx = xx;
lasty = y;
}
x += dx;
}
p += 2;
}
}

bool Oscilloscope::Buffer::fill(float left, float right)
{
if (pos<size+1)
{
if (auto_threshold)
{
if (lmax.max<left)
{
lmax.max=left+0.05;
lmax.pos=pos;
}
if (rmax.max<right)
{
rmax.max=right+0.05;
rmax.pos=pos+1;
}
}
buffer[pos++]=left;
buffer[pos++]=right;
return false;
}
return true;
}


Oscilloscope::Oscilloscope() : SoundGenerator("oscillo")
, buffer(0), sound(0)
{
}

Oscilloscope::~Oscilloscope()
{
if (buffer)
delete buffer;
if (sound)
delete sound;
}

Oscilloscope::Oscilloscope(istream& in)
{
buffer = new Buffer(10000);
sound = factory(in, true);
if (SDL_Init(SDL_INIT_VIDEO)) // FIXME no a good place for that
{
cerr << "Unable to init video" << endl;
exit(1);
}
}

void Oscilloscope::next(float& left, float& right, float speed)
{
float l=0;
float r=0;

sound->next(l,r,speed);
left += l;
right += r;

if (buffer->fill(l,r))
{
static atomic<bool> rendering(false);
if (rendering)
return;

static SDL_Window* window = NULL;
static SDL_Renderer* renderer = NULL;
rendering = true;
static Buffer* b = buffer;
static thread* f = 0;
if (f)
f->join();
f = new thread([]{
if (window == NULL)
{
if (SDL_CreateWindowAndRenderer(640, 200, 0, &window, &renderer))
return;
}

SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
b->render(renderer, 640, 200, true, 1);
SDL_RenderPresent(renderer);

b->reset();
rendering = false;
});


}
}

Loading

0 comments on commit 6df3806

Please sign in to comment.