diff --git a/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.C b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.C new file mode 100644 index 0000000..7bbe33a --- /dev/null +++ b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.C @@ -0,0 +1,371 @@ +/* LoopWidget + * Copyleft (C) 2000 David Griffiths + * + * 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 "Fl_Loop.h" +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// + +static const int REZ = 1000; +static const float RADCONV = 0.017453292; +static const int INDW = 3; // indicator width +static const int UPDATECYCLES = 4; + +static const int POSMARKER_MAX = 50; + +Fl_Loop::Fl_Loop(int x, int y, int w, int h, const char* label) : +Fl_Group(x,y,w,h,label), +m_data(NULL), +m_MainWin(NULL), +m_Length(1000), +m_InnerRad((int)(w/2*0.75f)), +m_OuterRad((int)(w/2*0.95f)), +m_BorderRad(w/2), +m_IndSX(0), +m_IndSY(0), +m_IndEX(0), +m_IndEY(0), +m_StartAngle(0), +m_EndAngle(1), +m_MoveAngle(0.0f), +m_RangeStart(0), +m_RangeEnd(0), +m_Angle(0), +m_Pos(0), +m_Update(true), +m_StopUpdate(false), +m_WaveSize(1.0f), +m_Move(0), +m_LastMove(0), +m_Snap(false), +m_SnapDegrees(45), +m_PosMarkerCount(0) +{ + box(FL_NO_BOX); + m_MidX=(w/2)+x; + m_MidY=(h/2)+y-20; +} + +void Fl_Loop::SetData(float const *set, const int Len) +{ + if (m_data!=NULL) delete[] m_data; + m_data = new float[Len]; + memcpy((void*)m_data,(void*)set,Len*sizeof(float)); + + SetLength(Len); +} + +void Fl_Loop::SetLength(const int Len) +{ + m_Length=Len; + + // recalc start and end points + m_RangeStart=(long)(m_StartAngle*(m_Length/360.0f)); + while (m_RangeStart < 0) m_RangeStart += m_Length; + while (m_RangeStart > m_Length) m_RangeStart -= m_Length; + + m_RangeEnd=(long)(m_EndAngle*(m_Length/360.0f)); + while (m_RangeEnd < 0) m_RangeEnd += m_Length; + while (m_RangeEnd > m_Length) m_RangeEnd -= m_Length; +} + +void Fl_Loop::SelectAll() +{ + m_RangeStart=0; + m_RangeEnd=m_Length; +} + +void Fl_Loop::DrawWav() +{ + int Thickness=(m_OuterRad-m_InnerRad)/2; + int n=0,X=0,Y=0,ox=0,oy=0, c=0; + bool FirstTime=true, DrawnSnap=false; + float Angle=0; + float Sample=0; + float SampleAngle=360.0f/(float)(REZ); + + fl_color(100,155,100); + + while(m_Length>0 && n1) Sample=1; + if (Sample<-1) Sample=-1; + } + + Angle=c*SampleAngle; + + ox=X; + oy=Y; + + float pos=Sample*Thickness+m_InnerRad+Thickness; + + X=(int)(m_MidX+x()+sin(Angle*RADCONV)*pos); + Y=(int)(m_MidY+y()+cos(Angle*RADCONV)*pos); + + if (Angle>m_StartAngle && Anglevisible() || !parent()->visible()) return; + window()->make_current(); + + float Angle=(m_Pos/m_Length)*360.0; + fl_line_style(FL_SOLID, 3, NULL); +#if !__APPLE__ + XSetFunction(fl_display,fl_gc,GXxor); +#endif + fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); + + fl_color(FL_BLUE); + + m_IndSX=(int)(m_MidX+x()+sin(Angle*RADCONV)*m_InnerRad); + m_IndSY=(int)(m_MidY+y()+cos(Angle*RADCONV)*m_InnerRad); + m_IndEX=(int)(m_MidX+x()+sin(Angle*RADCONV)*m_OuterRad); + m_IndEY=(int)(m_MidY+y()+cos(Angle*RADCONV)*m_OuterRad); + + fl_line(m_IndSX,m_IndSY,m_IndEX,m_IndEY); + fl_line_style(FL_SOLID, 1, NULL); +#if !__APPLE__ + XSetFunction(fl_display,fl_gc,GXcopy); +#endif + + if (m_PosMarkerCount>POSMARKER_MAX) + { + redraw(); + m_PosMarkerCount=0; + } + + m_PosMarkerCount++; + + //Last->make_current(); +} + +void Fl_Loop::DrawWidgets() +{ + Fl_Group::draw(); +} + +void Fl_Loop::DrawEveryThing() +{ + if (damage() & (FL_DAMAGE_EXPOSE|FL_DAMAGE_ALL)) + { + if (m_PosMarkerCount>POSMARKER_MAX) + { + m_PosMarkerCount=0; + } + + //fl_color(color()); + //fl_rectf(x(),y(),w(),h()); + + m_InnerRad-=5; + m_OuterRad+=5; + fl_color(20,60,20); + fl_pie(m_MidX+x()-m_OuterRad, m_MidY+y()-m_OuterRad, m_OuterRad*2, m_OuterRad*2, 0, 360); + fl_color(color()); + fl_pie(m_MidX+x()-m_InnerRad, m_MidY+y()-m_InnerRad, m_InnerRad*2, m_InnerRad*2, 0, 360); + m_OuterRad-=5; + m_InnerRad+=5; + + DrawWav(); + } + + DrawWidgets(); +} + +void Fl_Loop::draw() +{ + DrawEveryThing(); +} + +int Fl_Loop::handle(int event) +{ + static int LastButtonPushed=0; + + // call base + if (!Fl_Group::handle(event)) + { + switch (event) + { + case FL_PUSH: + LastButtonPushed=Fl::event_button(); + // fall through + case FL_DRAG: + { + int mx = Fl::event_x()-(m_MidX+x()); + int my = Fl::event_y()-(m_MidY+y()); + if (!mx && !my) break; + + double angle = 90+atan2((float)-my, (float)mx)*180/M_PI; + while (angle < m_Angle-180) angle += 360; + while (angle > m_Angle+180) angle -= 360; + + while (angle < 0) angle += 360; + while (angle > 360) angle -= 360; + + m_Angle=angle; + + // snap + if (m_Snap) + { + m_Angle-=(int)m_Angle%m_SnapDegrees; + } + + if (LastButtonPushed==2) + { + m_Pos=m_Angle*(m_Length/360.0f); + + while (m_Pos < 0) m_Pos += m_Length; + while (m_Pos > m_Length) m_Pos -= m_Length; + } + else if (LastButtonPushed==1) + { + switch (event) + { + case FL_PUSH: + { + m_StartAngle=m_Angle; + m_EndAngle=m_Angle; + redraw(); + } + break; + + case FL_DRAG: + { + if (m_Angle>m_StartAngle) + { + m_EndAngle=m_Angle; + } + else + { + m_StartAngle=m_Angle; + } + redraw(); + } + break; + } + + // convert angle to sample data + m_RangeStart=(long)(m_StartAngle*(m_Length/360.0f)); + while (m_RangeStart < 0) m_RangeStart += m_Length; + while (m_RangeStart > m_Length) m_RangeStart -= m_Length; + + m_RangeEnd=(long)(m_EndAngle*(m_Length/360.0f)); + while (m_RangeEnd < 0) m_RangeEnd += m_Length; + while (m_RangeEnd > m_Length) m_RangeEnd -= m_Length; + + }else if (LastButtonPushed==3) + { + switch (event) + { + case FL_PUSH: + { + m_MoveAngle=m_Angle; + + // reset the last + // convert angle to sample data + m_LastMove=(int)(m_MoveAngle*(m_Length/360.0f)); + while (m_LastMove < 0) m_LastMove += m_Length; + while (m_LastMove > m_Length) m_Move -= m_Length; + } + break; + + case FL_DRAG: + { + m_MoveAngle=m_Angle; + redraw(); + } + break; + } + + // convert angle to sample data + m_Move=(int)(m_MoveAngle*(m_Length/360.0f)); + while (m_Move < 0) m_Move += m_Length; + while (m_Move > m_Length) m_Move -= m_Length; + + // do the move + cb_Move(this,m_LastMove-m_Move); + + m_LastMove=m_Move; + } + } + break; + + case FL_RELEASE: + break; + + default: + return 0; + } + + } + return 1; +} diff --git a/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.h b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.h new file mode 100644 index 0000000..5f610ec --- /dev/null +++ b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Loop.h @@ -0,0 +1,89 @@ +/* SpiralLoops + * Copyleft (C) 2000 David Griffiths + * + * 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 +#include +#include + +#ifndef LOOPWIDGET +#define LOOPWIDGET + +class Fl_Loop : public Fl_Group +{ +public: + Fl_Loop(int x, int y, int w, int h, const char* label=0); + + virtual void draw(); + virtual int handle(int event); + + void SetData(float const *set, const int Len); + void SetLength(const int Len); + int GetLength() { return m_Length; } + void SetPos(float p) {m_Pos=p;} + void SetUpdate(bool p) {m_Update=p;} + void StopUpdate(bool p) {m_StopUpdate=p;} + void SetWaveSize(float s) {m_WaveSize=s;} + void SetMainWin(Fl_Window *s) {m_MainWin=s;} + void DrawWav(); + void DrawWidgets(); + void DrawEveryThing(); + void DrawPosMarker(); + void SetSnap(bool s) {m_Snap=s;} + void SetSnapAngle(int s) {m_SnapDegrees=s;} + + typedef void (cb)(Fl_Widget *, int); + void SetMoveCallback(cb *cb_Move); + + void SelectAll(); + long GetRangeStart() { return m_RangeStart; } + long GetRangeEnd() { return m_RangeEnd; } + +private: + + float const *m_data; + + Fl_Window *m_MainWin; + + int m_Length; + int m_InnerRad; + int m_OuterRad; + int m_BorderRad; + int m_IndSX,m_IndSY,m_IndEX,m_IndEY; + int m_MidX,m_MidY; + + float m_StartAngle; + float m_EndAngle; + float m_MoveAngle; + long m_RangeStart; + long m_RangeEnd; + float m_Angle; + float m_Pos; + bool m_Update; + bool m_StopUpdate; + float m_WaveSize; + int m_Move; + int m_LastMove; + bool m_Snap; + int m_SnapDegrees; + int m_PosMarkerCount; + + cb *cb_Move; + +}; + +#endif diff --git a/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Trigger.C b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Trigger.C new file mode 100644 index 0000000..6047c6e --- /dev/null +++ b/SpiralSound/Plugins/SpiralLoopPlugin/Fl_Trigger.C @@ -0,0 +1,188 @@ +/* TriggerWidget + * Copyleft (C) 2000 David Griffiths + * + * 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 "Fl_Trigger.h" +#include +#include +#include +#include +#include "Fl_Loop.h" + +///////////////////////////////////////////////////////////////////////////// + +static const float RADCONV = 0.017453292; + +Fl_Trigger::Fl_Trigger(int x, int y, int w, int h, const char* label) : +Fl_Widget(x,y,w,h,label), +m_ID(0), +m_Channel(0), +m_CentreX(0), +m_CentreY(0), +m_CentreRadius(0), +m_Dragging(false), +m_Loop(0), +m_Passes(0), +m_Count(0), +m_Angle(0), +m_MaxLoops(10), +m_MaxPasses(10), +m_Snap(false), +m_SnapDegrees(45) +{ +} + +void Fl_Trigger::draw() +{ + x(parent()->x()+(int)((sin(m_Angle*RADCONV)*m_CentreRadius)+m_CentreX-w()/2)); + y(parent()->y()+(int)((cos(m_Angle*RADCONV)*m_CentreRadius)+m_CentreY-h()/2)); + + fl_font(fl_font(),8); + + fl_color(255,255,255); + fl_arc(x(), y(), w(), h(), 0, 360); + + int cx=x()+w()/2; + int cy=y()+h()/2; + + char text[32]; + //sprintf(text,"%d",m_Loop); + //fl_draw(text, cx-2, cy-h()+5); + + //sprintf(text,"%d",m_Passes); + //fl_draw(text, cx+w()-5, cy+3); + + sprintf(text,"%d",m_Channel); + fl_draw(text, cx, cy); + + //char t[32]; + //sprintf(t,"%d",m_Count); + //fl_draw(t, cx-2, cy-h()+5); +} + +int Fl_Trigger::handle(int event) +{ + static int LastButtonPushed=0; + + // call base + if (!Fl_Widget::handle(event)) + { + int ww,hh; + + ww = w(); + hh = h(); + + int mx = Fl::event_x(); + int my = Fl::event_y(); + + switch (event) + { + case FL_PUSH: + LastButtonPushed=Fl::event_button(); + + if (LastButtonPushed==1) + { + m_Dragging=true; + } + + if (LastButtonPushed==3) + { + m_Channel++; + if (m_Channel>7) + { + m_Channel=0; + } + redraw(); + Fl_Loop *p=(Fl_Loop*)parent(); + p->DrawEveryThing(); + p->redraw(); + } + + // fall through + + case FL_DRAG: + { + if (LastButtonPushed==2) + { + + } + else if (LastButtonPushed==1) + { + if (m_Dragging) + { + int px = mx-(m_CentreX+parent()->x()); + int py = my-(m_CentreY+parent()->y()); + + double angle = 90+atan2((float)-py, (float)px)*180/M_PI; + while (angle < m_Angle-180) angle += 360; + while (angle > m_Angle+180) angle -= 360; + + while (angle < 0) angle += 360; + while (angle > 360) angle -= 360; + + m_Angle=angle; + + // snap + if (m_Snap) + { + m_Angle-=(int)m_Angle%m_SnapDegrees; + } + + redraw(); + } + } + else if (LastButtonPushed==3) + { + + } + } + break; + + case FL_RELEASE: + { + m_Dragging=false; + Fl_Loop *p=(Fl_Loop*)parent(); + p->DrawEveryThing(); + p->redraw(); + do_callback(); + } + break; + + default: + return 0; + } + + } + return 1; +} + +istream &operator>>(istream &s, Fl_Trigger &o) +{ + s>>o.m_CentreX>>o.m_CentreY>>o.m_CentreRadius>>o.m_Dragging>>o.m_ID>>o.m_Passes>> + o.m_Count>>o.m_Angle>>o.m_MaxLoops>>o.m_MaxPasses; + + return s; +} + +ostream &operator<<(ostream &s, Fl_Trigger &o) +{ + s< + * + * 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 +#include +#include + +#ifndef TRIGGERWIDGET +#define TRIGGERWIDGET + +using namespace std; + +class Fl_Trigger : public Fl_Widget +{ +public: + Fl_Trigger(int x, int y, int w, int h, const char* label=0); + + virtual void draw(); + virtual int handle(int event); + + void SetID(int s) {m_ID=s;} + int GetID() { return m_ID;} + void SetChannel(int s) {m_Channel=s;} + int GetChannel() { return m_Channel;} + void SetCentreX(int s) {m_CentreX=s;} + void SetCentreY(int s) {m_CentreY=s;} + void SetCentreRadius(int s) {m_CentreRadius=s;} + void IncCount() + { + m_Count++; if (m_Count>m_Passes) m_Count=0; + } + bool Completed() {return (m_Count==m_Passes); } + + float GetAngle() {return m_Angle;} + int GetLoop() {return m_Loop;} + int GetPass() {return m_Passes;} + void SetSnap(bool s) {m_Snap=s;} + void SetSnapAngle(int s) {m_SnapDegrees=s;} + +private: + + int m_ID; + int m_Channel; + int m_CentreX; + int m_CentreY; + int m_CentreRadius; + + bool m_Dragging; + int m_Loop; + int m_Passes; + int m_Count; + + float m_Angle; + + int m_MaxLoops; + int m_MaxPasses; + + bool m_Snap; + int m_SnapDegrees; + + friend istream &operator>>(istream &s, Fl_Trigger &o); + friend ostream &operator<<(ostream &s, Fl_Trigger &o); +}; + +istream &operator>>(istream &s, Fl_Trigger &o); +ostream &operator<<(ostream &s, Fl_Trigger &o); + +#endif diff --git a/SpiralSound/Plugins/SpiralLoopPlugin/Makefile.in b/SpiralSound/Plugins/SpiralLoopPlugin/Makefile.in index faa10a7..1e734c4 100644 --- a/SpiralSound/Plugins/SpiralLoopPlugin/Makefile.in +++ b/SpiralSound/Plugins/SpiralLoopPlugin/Makefile.in @@ -161,6 +161,9 @@ install: GUI/Widgets/Fl_Loop.o: GUI/Widgets/Fl_Loop.C \ GUI/Widgets/Fl_Loop.h +Fl_Loop.o: Fl_Loop.C \ + Fl_Loop.h + Fl_Trigger.o: Fl_Trigger.C \ Fl_Trigger.h \ Fl_Loop.h diff --git a/configure.in b/configure.in index 3090fef..20e3e22 100644 --- a/configure.in +++ b/configure.in @@ -45,7 +45,7 @@ if test $ac_arg_jack = "Y" ; then WaveTablePlugin LADSPAPlugin XFadePlugin PoshSamplerPlugin SeqSelectorPlugin\ DistributorPlugin LFOPlugin KeyboardPlugin DiskWriterPlugin FormantFilterPlugin \ AnotherFilterPlugin OperatorPlugin CounterPlugin FlipflopPlugin SwitchPlugin \ - BeatMatchPlugin NoisePlugin SequencerPlugin LogicPlugin SplitSwitchPlugin \ + BeatMatchPlugin NoisePlugin LogicPlugin SplitSwitchPlugin \ MixSwitchPlugin MeterPlugin WaveShaperPlugin TrigPlugin SpiralLoopPlugin \ MasherPlugin JackPlugin" else @@ -56,7 +56,7 @@ else WaveTablePlugin LADSPAPlugin XFadePlugin PoshSamplerPlugin SeqSelectorPlugin\ DistributorPlugin LFOPlugin KeyboardPlugin DiskWriterPlugin FormantFilterPlugin \ AnotherFilterPlugin OperatorPlugin CounterPlugin FlipflopPlugin SwitchPlugin \ - BeatMatchPlugin NoisePlugin SequencerPlugin LogicPlugin SplitSwitchPlugin \ + BeatMatchPlugin NoisePlugin LogicPlugin SplitSwitchPlugin \ MixSwitchPlugin MeterPlugin WaveShaperPlugin TrigPlugin SpiralLoopPlugin \ MasherPlugin" @@ -168,7 +168,6 @@ SpiralSound/Plugins/FlipflopPlugin/Makefile SpiralSound/Plugins/SwitchPlugin/Makefile SpiralSound/Plugins/BeatMatchPlugin/Makefile SpiralSound/Plugins/NoisePlugin/Makefile -SpiralSound/Plugins/SequencerPlugin/Makefile SpiralSound/Plugins/LogicPlugin/Makefile SpiralSound/Plugins/SplitSwitchPlugin/Makefile SpiralSound/Plugins/MixSwitchPlugin/Makefile