Commit 045eefea authored by dave griffiths's avatar dave griffiths
Browse files

sync/timing bz

parent 7563cf14
(synth-init)
(play-now (mul
5
(echo
(mooglp
(saw (add 400 (mul (sine 0.1) 1000)))
(add (sine 0.23) 1)
0.45)
0.4 0.9)) 0)
(synth-init)
(play-now (mul
5
(echo
(mul (adsr 0 1 0 0)
(sine (add 40 (mul (sine 800)
(mul (sine 3) 1000)))))
0.1 0.9)) 0)
(synth-init)
(define (time-add t secs)
(list (+ (car t) secs) (cadr t)))
(define time (time-add (time-of-day) 20))
(define (loop time m)
(when (< m 100)
(display time)(newline)
(play time (mul (adsr 0 0.1 0.3 1) (saw (+ 40 (* m 20)))) 0)
(loop (time-add time 1) (+ m 1))))
(loop time 0)
\ No newline at end of file
(define (loop m)
(when (not (zero? m))
(play-now (mul (adsr 0 0.1 0 0) (sine 440)) 0)
(loop (- m 1))))
(loop 100)
\ No newline at end of file
// Copyright (C) 2003 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Event.h"
using namespace spiralcore;
// Copyright (C) 2003 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Types.h"
#include "Time.h"
#ifndef NE_EVENT
#define NE_EVENT
namespace spiralcore
{
class Event
{
public:
Event() :
ID(0),
Frequency(440.0f),
SlideFrequency(0.0f),
Volume(1.0f),
Pan(0.0f),
Position(0),
Channel(0),
NoteNum(0),
Message(0)
{}
int ID; // the currently playing sample, or voice
float32 Frequency; // freq
float32 SlideFrequency; // slide dest freq
float32 Volume; // or velocity
float32 Pan; // stereo pan
float32 Position; // sample position start->end 0->1
int Channel; // output channel for this event
int NoteNum;
char Message; // used for charscore message passing
Time TimeStamp; // when to do this event
};
}
#endif
// Copyright (C) 2004 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "EventQueue.h"
using namespace spiralcore;
EventQueue::EventQueue()
{
}
EventQueue::~EventQueue()
{
}
bool EventQueue::Add(const Event &e)
{
for (int i=0; i<EVENT_QUEUE_SIZE; i++)
{
if (m_Queue[i].m_IsEmpty)
{
m_Queue[i].m_Event=e;
m_Queue[i].m_IsEmpty=false;
return true;
}
}
return false;
}
bool EventQueue::Get(Time from, Time till, Event &e)
{
for (int i=0; i<EVENT_QUEUE_SIZE; i++)
{
if (!m_Queue[i].m_IsEmpty && m_Queue[i].m_Event.TimeStamp>from &&
m_Queue[i].m_Event.TimeStamp<till)
{
e=m_Queue[i].m_Event; // return this one
m_Queue[i].m_IsEmpty=true; // delete from the queue
return true;
}
}
return false;
}
// Copyright (C) 2004 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Event.h"
#ifndef SPIRALCORE_EVENT_QUEUE
#define SPIRALCORE_EVENT_QUEUE
static const int EVENT_QUEUE_SIZE = 256;
namespace spiralcore
{
// no mallocs, so a bit of diy memory allocation
class EventQueue
{
public:
EventQueue();
~EventQueue();
bool Add(const Event &e);
// you should keep calling this function for the specified
// time slice until it returns false
bool Get(Time from, Time till, Event &e);
private:
struct QueueItem
{
QueueItem() : m_IsEmpty(true) {}
bool m_IsEmpty;
Event m_Event;
};
QueueItem m_Queue[EVENT_QUEUE_SIZE];
};
}
#endif
// Copyright (C) 2004 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <assert.h>
#include <math.h>
#include "Time.h"
using namespace spiralcore;
// got this and usec2ntp from http://www.openmash.org/lxr/source/rtp/ntp-time.h
static const unsigned long GETTIMEOFDAY_TO_NTP_OFFSET = 2208988800UL;
// convert microseconds to fraction of second * 2^32 (i.e., the lsw of
// a 64-bit ntp timestamp). This routine uses the factorization
// 2^32/10^6 = 4096 + 256 - 1825/32 which results in a max conversion
// error of 3 * 10^-7 and an average error of half that.
unsigned int usec2ntp(unsigned int usec)
{
unsigned int t = (usec * 1825) >> 5;
return ((usec << 12) + (usec << 8) - t);
}
Time::Time() :
Seconds(0),
Fraction(0)
{
}
void Time::SetToNow()
{
timeval tv;
gettimeofday(&tv,0);
SetFromPosix(tv);
}
void Time::SetFromPosix(timeval tv)
{
// gettimeofday epoch is 00:00:00 UTC, January 1, 1970
// ntp (what we're basing time on for OSC compat) epoch is
// 00:00:00 UTC, January 1, 1900, so we need to convert...
Seconds = (unsigned int)tv.tv_sec + GETTIMEOFDAY_TO_NTP_OFFSET;
Fraction = usec2ntp(tv.tv_usec);
}
void Time::IncBySample(unsigned long samples, unsigned long samplerate)
{
(*this)+=samples/(double)samplerate;
}
Time &Time::operator+=(double s)
{
unsigned int Secs = (unsigned int)floor(s);
Seconds += Secs;
double Frac = s-Secs;
// overflow? (must do this better)
if (Frac+Fraction*ONE_OVER_UINT_MAX>1.0f) Seconds++;
Fraction += (unsigned int)(Frac*UINT_MAX);
return *this;
}
double Time::GetDifference(const Time& other)
{
double SecsDiff = (long)Seconds-(long)other.Seconds;
double SecsFrac = Fraction*ONE_OVER_UINT_MAX;
SecsFrac-=other.Fraction*ONE_OVER_UINT_MAX;
return SecsDiff+SecsFrac;
}
bool Time::operator<(const Time& other)
{
if (Seconds<other.Seconds) return true;
else if (Seconds==other.Seconds && Fraction<other.Fraction) return true;
return false;
}
bool Time::operator>(const Time& other)
{
if (Seconds>other.Seconds) return true;
else if (Seconds==other.Seconds && Fraction>other.Fraction) return true;
return false;
}
bool Time::operator<=(const Time& other)
{
if (Seconds<other.Seconds|| (Seconds==other.Seconds && Fraction==other.Fraction)) return true;
else if (Seconds==other.Seconds && Fraction<other.Fraction) return true;
return false;
}
bool Time::operator>=(const Time& other)
{
if (Seconds>other.Seconds || (Seconds==other.Seconds && Fraction==other.Fraction)) return true;
else if (Seconds==other.Seconds && Fraction>other.Fraction) return true;
return false;
}
bool Time::operator==(const Time& other)
{
if (Seconds==other.Seconds && Fraction==other.Fraction) return true;
return false;
}
void Time::Print() const
{
cerr<<Seconds<<":"<<GetFraction()<<" ("<<Fraction<<")"<<endl;
}
// Copyright (C) 2004 David Griffiths <dave@pawfal.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <sys/time.h>
#include <iostream>
#include <limits.h>
using namespace std;
#ifndef SPIRALCORE_TIME
#define SPIRALCORE_TIME
static const double ONE_OVER_UINT_MAX = 1.0/UINT_MAX;
namespace spiralcore
{
class Time
{
public:
Time();
Time(int s, int f) : Seconds(s),Fraction(f) {}
void SetToNow();
void SetFromPosix(timeval tv);
void IncBySample(unsigned long samples, unsigned long samplerate);
bool operator<(const Time& other);
bool operator>(const Time& other);
bool operator<=(const Time& other);
bool operator>=(const Time& other);
bool operator==(const Time& other);
Time &operator+=(double s);
void Print() const;
double GetFraction() const { return Fraction*ONE_OVER_UINT_MAX; }
void SetFraction(double s) { Fraction = (int)(s*(double)UINT_MAX); }
bool IsEmpty() { return (!Seconds && !Fraction); }
double GetDifference(const Time& other);
unsigned int Seconds;
unsigned int Fraction;
};
}
#endif
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