Commit 7563cf14 authored by dave griffiths's avatar dave griffiths
Browse files

timing stuff

parent c0e3b603
...@@ -15,6 +15,9 @@ SRCS := src/main.cpp\ ...@@ -15,6 +15,9 @@ SRCS := src/main.cpp\
src/fluxa/GraphNode.cpp\ src/fluxa/GraphNode.cpp\
src/fluxa/Modules.cpp\ src/fluxa/Modules.cpp\
src/fluxa/ModuleNodes.cpp\ src/fluxa/ModuleNodes.cpp\
src/fluxa/Event.cpp\
src/fluxa/EventQueue.cpp\
src/fluxa/Time.cpp\
src/audio/alsa.cpp \ src/audio/alsa.cpp \
src/engine/obj_reader.cpp\ src/engine/obj_reader.cpp\
src/engine/engine.cpp\ src/engine/engine.cpp\
......
...@@ -47,7 +47,8 @@ ...@@ -47,7 +47,8 @@
(map (lambda (l) (apply synth-connect l)) (make-args id operands)) (map (lambda (l) (apply synth-connect l)) (make-args id operands))
(node id))) (node id)))
(define (play-now node pan) (synth-play 0 (node-id node) pan)) (define (play-now node pan) (synth-play 0 0 (node-id node) pan))
(define (play time node pan) (synth-play (car time) (cadr time) (node-id node) pan))
;;--------------------------------------------------------------- ;;---------------------------------------------------------------
;; operators ;; operators
......
...@@ -33,6 +33,7 @@ alsa_device::~alsa_device() { ...@@ -33,6 +33,7 @@ alsa_device::~alsa_device() {
#define AUDIO_BUFSIZE 4096 #define AUDIO_BUFSIZE 4096
void audio_loop(void *c) { void audio_loop(void *c) {
alsa_device *a=(alsa_device *)c; alsa_device *a=(alsa_device *)c;
...@@ -48,8 +49,6 @@ void audio_loop(void *c) { ...@@ -48,8 +49,6 @@ void audio_loop(void *c) {
g->Process(AUDIO_BUFSIZE, left, right); g->Process(AUDIO_BUFSIZE, left, right);
unsigned int pos=0; unsigned int pos=0;
for (unsigned int i=0; i<AUDIO_BUFSIZE*2; i+=2) for (unsigned int i=0; i<AUDIO_BUFSIZE*2; i+=2)
{ {
......
...@@ -26,7 +26,7 @@ using namespace std; ...@@ -26,7 +26,7 @@ using namespace std;
pthread_mutex_t* m_Mutex; pthread_mutex_t* m_Mutex;
Graph::Graph(unsigned int NumNodes, unsigned int SampleRate) : Graph::Graph(unsigned int NumNodes, unsigned int SampleRate) :
m_MaxPlaying(10), m_MaxPlaying(5),
m_NumNodes(NumNodes), m_NumNodes(NumNodes),
m_SampleRate(SampleRate) m_SampleRate(SampleRate)
{ {
...@@ -34,6 +34,7 @@ m_SampleRate(SampleRate) ...@@ -34,6 +34,7 @@ m_SampleRate(SampleRate)
Init(); Init();
m_Mutex = new pthread_mutex_t; m_Mutex = new pthread_mutex_t;
pthread_mutex_init(m_Mutex,NULL); pthread_mutex_init(m_Mutex,NULL);
m_CurrentTime.SetToNow();
} }
Graph::~Graph() Graph::~Graph()
...@@ -169,9 +170,9 @@ void Graph::Connect(unsigned int id, unsigned int arg, unsigned int to) ...@@ -169,9 +170,9 @@ void Graph::Connect(unsigned int id, unsigned int arg, unsigned int to)
} }
} }
void Graph::Play(float time, unsigned int id, float pan) void Graph::_Play(float time, unsigned int id, float pan)
{ {
pthread_mutex_lock(m_Mutex); // pthread_mutex_lock(m_Mutex);
{ {
//cerr<<"play id "<<id<<endl; //cerr<<"play id "<<id<<endl;
if (m_NodeMap[id]!=NULL) if (m_NodeMap[id]!=NULL)
...@@ -184,7 +185,7 @@ void Graph::Play(float time, unsigned int id, float pan) ...@@ -184,7 +185,7 @@ void Graph::Play(float time, unsigned int id, float pan)
m_RootNodes.erase(m_RootNodes.begin()); m_RootNodes.erase(m_RootNodes.begin());
} }
} }
pthread_mutex_unlock(m_Mutex); // pthread_mutex_unlock(m_Mutex);
} }
} }
...@@ -192,26 +193,75 @@ void Graph::Process(unsigned int bufsize, Sample &left, Sample &right) ...@@ -192,26 +193,75 @@ void Graph::Process(unsigned int bufsize, Sample &left, Sample &right)
{ {
pthread_mutex_lock(m_Mutex); pthread_mutex_lock(m_Mutex);
{ {
Time LastTime = m_CurrentTime;
m_CurrentTime.IncBySample(bufsize,48000);
// first check the event queue
Event e;
while (m_EventQueue.Get(LastTime, m_CurrentTime, e)) {
float t = LastTime.GetDifference(e.TimeStamp);
// hack to get round bug with GetDifference throwing big numbers
if (t<=0) {
_Play(t,e.ID,e.Pan);
} else {
cerr<<"----------------"<<endl;
cerr<<t<<endl;
LastTime.Print();
e.TimeStamp.Print();
}
}
for(list<pair<unsigned int, float> >::iterator i=m_RootNodes.begin(); for(list<pair<unsigned int, float> >::iterator i=m_RootNodes.begin();
i!=m_RootNodes.end(); ++i) i!=m_RootNodes.end(); ++i)
{ {
if (m_NodeMap[i->first]!=NULL) if (m_NodeMap[i->first]!=NULL)
{ {
m_NodeMap[i->first]->Process(bufsize); m_NodeMap[i->first]->Process(bufsize);
// do stereo panning // do stereo panning
float pan = i->second; float pan = i->second;
float leftpan=1,rightpan=1; float leftpan=1,rightpan=1;
if (pan<0) leftpan=1-pan; if (pan<0) leftpan=1-pan;
else rightpan=1+pan; else rightpan=1+pan;
left.MulMix(m_NodeMap[i->first]->GetOutput(),0.1*leftpan); left.MulMix(m_NodeMap[i->first]->GetOutput(),0.1*leftpan);
right.MulMix(m_NodeMap[i->first]->GetOutput(),0.1*rightpan); right.MulMix(m_NodeMap[i->first]->GetOutput(),0.1*rightpan);
} }
} }
pthread_mutex_unlock(m_Mutex);
}
}
pthread_mutex_unlock(m_Mutex);
void Graph::Play(unsigned int seconds, unsigned int fraction, unsigned int id, float pan) {
pthread_mutex_lock(m_Mutex);
Event e;
e.TimeStamp.Seconds=seconds;
e.TimeStamp.Fraction=fraction;
e.ID=id;
e.Pan=pan;
// play-now (ish)
if (e.TimeStamp.Seconds==0 && e.TimeStamp.Fraction==0) {
e.TimeStamp=m_CurrentTime;
e.TimeStamp+=0.1;
}
if (e.TimeStamp>=m_CurrentTime) {
m_EventQueue.Add(e);
if (e.TimeStamp.GetDifference(m_CurrentTime)>30) {
cerr<<"Reset clock? Event far in future: "<<e.TimeStamp.GetDifference(m_CurrentTime)<<endl;
} }
} else {
cerr<<"Event arrived too late ignoring: "<<m_CurrentTime.GetDifference(e.TimeStamp)<<endl;
m_CurrentTime.Print();
e.TimeStamp=m_CurrentTime;
e.TimeStamp+=0.1;
m_EventQueue.Add(e);
}
pthread_mutex_unlock(m_Mutex);
} }
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <math.h> #include <math.h>
#include "GraphNode.h" #include "GraphNode.h"
#include "ModuleNodes.h" #include "ModuleNodes.h"
#include "EventQueue.h"
#ifndef GRAPH #ifndef GRAPH
#define GRAPH #define GRAPH
...@@ -39,11 +40,13 @@ public: ...@@ -39,11 +40,13 @@ public:
void Clear(); void Clear();
void Create(unsigned int id, Type t, float v); void Create(unsigned int id, Type t, float v);
void Connect(unsigned int id, unsigned int arg, unsigned int to); void Connect(unsigned int id, unsigned int arg, unsigned int to);
void Play(float time, unsigned int id, float pan); void Play(unsigned int seconds, unsigned int fraction, unsigned int id, float pan);
void Process(unsigned int bufsize, Sample &left, Sample &right); void Process(unsigned int bufsize, Sample &left, Sample &right);
void SetMaxPlaying(int s) { m_MaxPlaying=s; } void SetMaxPlaying(int s) { m_MaxPlaying=s; }
private: private:
void _Play(float time, unsigned int id, float pan);
class NodeDesc class NodeDesc
{ {
public: public:
...@@ -77,6 +80,9 @@ private: ...@@ -77,6 +80,9 @@ private:
map<Type,NodeDescVec*> m_NodeDescMap; map<Type,NodeDescVec*> m_NodeDescMap;
unsigned int m_NumNodes; unsigned int m_NumNodes;
unsigned int m_SampleRate; unsigned int m_SampleRate;
EventQueue m_EventQueue;
Time m_CurrentTime;
}; };
#endif #endif
...@@ -200,6 +200,7 @@ ...@@ -200,6 +200,7 @@
// _OP_DEF(opexe_6, "db-select-blob", 5, 5, TST_NONE, OP_SELECT_BLOB_DB ) // _OP_DEF(opexe_6, "db-select-blob", 5, 5, TST_NONE, OP_SELECT_BLOB_DB )
_OP_DEF(opexe_6, "db-status", 1, 1, TST_NONE, OP_STATUS_DB ) _OP_DEF(opexe_6, "db-status", 1, 1, TST_NONE, OP_STATUS_DB )
_OP_DEF(opexe_6, "time-of-day", 0, 0, TST_NONE, OP_TIME ) _OP_DEF(opexe_6, "time-of-day", 0, 0, TST_NONE, OP_TIME )
_OP_DEF(opexe_6, "ntp-time", 0, 0, TST_NONE, OP_NTP_TIME )
_OP_DEF(opexe_6, "date-time", 0, 0, TST_NONE, OP_DATETIME ) _OP_DEF(opexe_6, "date-time", 0, 0, TST_NONE, OP_DATETIME )
_OP_DEF(opexe_6, "id-map-add", 2, 2, TST_NONE, OP_ID_MAP_ADD ) _OP_DEF(opexe_6, "id-map-add", 2, 2, TST_NONE, OP_ID_MAP_ADD )
_OP_DEF(opexe_6, "id-map-get", 1, 1, TST_NONE, OP_ID_MAP_GET ) _OP_DEF(opexe_6, "id-map-get", 1, 1, TST_NONE, OP_ID_MAP_GET )
...@@ -207,7 +208,7 @@ ...@@ -207,7 +208,7 @@
_OP_DEF(opexe_6, "synth-init", 0, 0, 0, OP_SYNTH_INIT ) _OP_DEF(opexe_6, "synth-init", 0, 0, 0, OP_SYNTH_INIT )
_OP_DEF(opexe_6, "synth-create", 3, 3, 0, OP_SYNTH_CRT ) _OP_DEF(opexe_6, "synth-create", 3, 3, 0, OP_SYNTH_CRT )
_OP_DEF(opexe_6, "synth-connect", 3, 3, 0, OP_SYNTH_CON ) _OP_DEF(opexe_6, "synth-connect", 3, 3, 0, OP_SYNTH_CON )
_OP_DEF(opexe_6, "synth-play", 3, 3, 0, OP_SYNTH_PLY ) _OP_DEF(opexe_6, "synth-play", 4, 4, 0, OP_SYNTH_PLY )
_OP_DEF(opexe_6, "sleep", 1, 1, 0, OP_SLEEP ) _OP_DEF(opexe_6, "sleep", 1, 1, 0, OP_SLEEP )
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "../engine/engine.h" #include "../engine/engine.h"
#include "../core/geometry.h" #include "../core/geometry.h"
#include "../fluxa/Graph.h" #include "../fluxa/Graph.h"
#include "../fluxa/Time.h"
#include "../audio/alsa.h" #include "../audio/alsa.h"
Graph *m_audio_graph = NULL; Graph *m_audio_graph = NULL;
...@@ -4488,6 +4489,11 @@ static pointer opexe_6(scheme *sc, enum scheme_opcodes op) { ...@@ -4488,6 +4489,11 @@ static pointer opexe_6(scheme *sc, enum scheme_opcodes op) {
s_return(sc,cons(sc,mk_integer(sc,t.tv_sec), s_return(sc,cons(sc,mk_integer(sc,t.tv_sec),
cons(sc,mk_integer(sc,t.tv_usec),sc->NIL))); cons(sc,mk_integer(sc,t.tv_usec),sc->NIL)));
} }
case OP_NTP_TIME: {
Time t;
t.SetToNow();
s_return(sc,mk_real(sc,t.Seconds+t.Fraction/(float)UINT_MAX));
}
case OP_DATETIME: { case OP_DATETIME: {
timeval t; timeval t;
// stop valgrind complaining // stop valgrind complaining
...@@ -4546,9 +4552,10 @@ static pointer opexe_6(scheme *sc, enum scheme_opcodes op) { ...@@ -4546,9 +4552,10 @@ static pointer opexe_6(scheme *sc, enum scheme_opcodes op) {
} break; } break;
case OP_SYNTH_PLY: { case OP_SYNTH_PLY: {
m_audio_graph m_audio_graph
->Play(rvalue(car(sc->args)), ->Play(ivalue(car(sc->args)),
ivalue(cadr(sc->args)), ivalue(cadr(sc->args)),
rvalue(caddr(sc->args))); ivalue(caddr(sc->args)),
rvalue(cadddr(sc->args)));
s_return(sc,sc->F); s_return(sc,sc->F);
} break; } break;
case OP_SLEEP: { case OP_SLEEP: {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment