WBL4014Sets.cWBL4014Sets.c
/*--------------------------
Routines to initialize/redraw
various parts of the WBL4014
global state. Useful after
loading a fresh document.
Started 19 February 1995
--------------------------*/
/*--------------------------
Inclusions
--------------------------*/
#include "BigEasyTextish.h"
#include "WBL4014Formatting.h"
#include "WBL4014.h"
#include "StupidMemoryTricks.h"
#include "AtomicLister.h"
#define kGlobalMagic 12345
/*--------------------------
Routines
--------------------------*/
void ClearGrids(void)
/*
* Clear out the states of everything
* Dispose some things
* but dont reset/redraw yet.
*/
{
short i,j;
ArpGrid *ag;
ArpPattern *ap;
for(i = 0; i < kCheckBoxCount; i++)
g->cb[i] = 0;
g->cb[kCBSyncByMeasure] = true;
for(i = 0; i < kArpGridCount; i++)
{
ag = &g->ag[i];
ag->playingGridNumber = 0;
ag->nextPlayingGridNumber = 0;
#if 0
{
NoteChannel nc;
nc = ag->nc;
ag->nc = 0;
NADisposeNoteChannel(g->na,nc);
}
#else
{
ToneDescription td;
ComponentResult result;
result = NAStuffToneDescription(g->na,0,&td);
if(!ag->iH)
result = QTNewAtomContainer(&ag->iH);
setAI(ag->iH,&td);
}
#endif
//DisposeHandleAt(&ag->iH);
for(j = 0; j < kArpGridPatternCount; j++)
{
ap = ag->ap[j];
if(ap)
{
ag->ap[j] = 0;
DisposePtr((Ptr)ap);
}
}
for(j = 0; j < kMaxSequenceKeys; j++)
{
}
EnsureAgAp(i,0);
}
GetDisplayAgAp(g,nil,nil);
}
void SetGridInstruments(long gridLetter)
{
short lo,hi;
long i,j;
ArpGrid *ag;
OSType oldSynth,newSynth;
ComponentResult result;
if(gridLetter < 0)
{
lo = 0;
hi = kArpGridCount-1;
}
else
lo = hi = gridLetter;
for(i = lo; i <= hi; i++)
{
ag = &g->ag[i];
if(ag->nc)
{
NoteChannel nc;
nc = ag->nc;
ag->nc = 0;
GetNoteChannelMusicComponent(nc,nil,&oldSynth,nil);
result = NADisposeNoteChannel(g->na,nc);
}
else
oldSynth = 0;
if(ag->iH)
{
long index,part;
MusicComponent mc;
QTLockContainer(ag->iH);
result = NANewNoteChannelFromAtomicInstrument(g->na,*ag->iH,kSetAtomicInstCallerTosses,&ag->nc);
if(result)
ListAtomicInstrumentWindow(ag->iH);
result = NAGetNoteChannelInfo(g->na,ag->nc,&index,&part);
result = NAGetRegisteredMusicDevice(g->na,index,nil,nil,nil,&mc);
QTUnlockContainer(ag->iH);
}
ag->ncMC = GetNoteChannelMusicComponent(ag->nc,&ag->ncPart,&newSynth,nil);
if(oldSynth != newSynth)
{
DisposeOddMenu(&ag->om);
ag->om = BuildKnobMenu(ag->ncMC);
for(j = 0; j < kKnobLFOCount; j++)
{
SetWBLKnobLFOMenu(&ag->knobLFO[j],ag->om,0);
DrawWBLKnobLFO(&ag->knobLFO[j]);
}
}
if(i == g->displayGridLetter)
DrawInstrumentStat();
}
}
void SetGridNotes(long gridLetter,long gridNumber)
{
long loG,hiG,loP,hiP;
long k,p;
ArpGrid *ag;
ArpPattern *ap;
ComponentResult result;
if(gridLetter < 0)
{
loG = 0;
hiG = kArpGridCount-1;
}
else
loG = hiG = gridLetter;
if(gridNumber < 0)
{
loP = 0;
hiP = kArpGridPatternCount-1;
}
else
loP = hiP = gridNumber;
for(k = loG; k <= hiG; k++)
{
ag = &g->ag[k];
for(p = loP; p <= hiP; p++)
{
/*
* if its the one we're displaying
* then force an update
*/
if(k == g->displayGridLetter && p == g->displayGridNumber)
{
g->drawnGridLetter = -1;
ap = ag->ap[p];
if(ap)
{
BuildPKeys(g,ag,ap);
}
}
SetHasNotes(k,p);
}
}
}
#define kDefaultApLength 32
ArpPattern *NewAp(void)
{
ArpPattern *ap;
ap = (ArpPattern *)NewPtrClear(sizeof(ArpPattern));
if(ap)
{
ap->length = kDefaultApLength;
ap->volume = 0xE000;
}
return ap;
}
ArpPattern *EnsureAgAp(long gridLetter,long gridNumber)
{
ArpGrid *ag;
ArpPattern *ap;
ag = &g->ag[gridLetter];
ap = ag->ap[gridNumber];
if(!ap)
{
ap = NewAp();
if(ap)
ag->ap[gridNumber] = ap;
}
return ap;
}
void SetHasNotes(long gridLetter,long gridNumber)
{
short i,j;
ArpGrid *ag;
ArpPattern *ap;
Boolean hasNotes;
ag = &g->ag[gridLetter];
ap = ag->ap[gridNumber];
hasNotes = false;
if(ap)
{
for(i = 0; i < kMaxSequenceLength; i++)
for(j = 0; j < kMaxSequenceKeys; j++)
if(ap->a[i][j])
{
hasNotes = ap->hasNotes = true;
goto x;
}
}
x:
DrawPatternOverview(gridLetter,false,gridNumber);
}
void SetWBLVolume(long gridLetter,long gridNumber,Fixed volume)
{
ArpGrid *ag;
ArpPattern *ap;
ag = &g->ag[gridLetter];
ap = ag->ap[gridNumber];
if(ap)
{
ap->volume = volume;
SendWBLVolume(g,ag,ap);
}
}
void SetCheckBoxes(void)
/*
* Set the display checkbox values to the current bools
*/
{
short i;
for(i = 0; i < kCheckBoxCount; i++)
SetControlValue(g->cbC[i],g->cb[i]);
}
void SetPlayRate(Fixed rate)
/*
* Set the slider, and the actual timebase, to rate in beats/minute
*/
{
if(g->playRate != rate)
{
g->playRate = rate;
DrawBPM();
}
SetWBLSliderValue(&g->rateS,g->playRate,0);
if(!g->cb[kCBSlaveSync])
SetTimeBaseRate(g->tb,(g->playRate * kCellsPerBeat / (60 * kCellsPerSecond))<<8);
else
SetTimeBaseRate(g->tb,0);
}
void SetEverything(void)
/*
* Set everything interesting after a 'Load' or a 'New'
*/
{
Fixed rate;
rate = g->playRate;
SetPlayRate(0);
SetGridInstruments(-1);
SetGridNotes(-1,-1);
SetCheckBoxes();
SetPlayRate(rate);
}
void CopyPattern(long toGridLetter,long toGridNumber,
long fromGridLetter,long fromGridNumber)
{
ArpPattern *ap,*fromAp;
ap = g->ag[toGridLetter].ap[toGridNumber];
fromAp = g->ag[fromGridLetter].ap[fromGridNumber];
if(ap && fromAp)
*ap = *fromAp;
}
void CheckBoxesMenu(short n,short menu,short ref)
{
long flags;
ArpGrid *ag;
ArpPattern *ap;
GetDisplayAgAp(g,&ag,&ap);
if(ref > mFirstCheckBox && ref <= mLastCheckBox)
{
short n;
n = ref - mFirstCheckBox - 1;
FlashCheckBox(g->cbC[n],&g->cb[n]);
CheckBoxChanged(n);
}
else switch(ref)
{
case mCopyGrid:
CopyPattern(g->displayGridLetter,g->displayGridNumber,g->displayGridLetter,(g->displayGridNumber + 99) % 100);
g->drawnGridLetter = -1;
break;
case mPickInstrument:
BlinkControl(g->instrumentC);
WBLPickInstrument();
break;
case mEditPickInstrument:
flags = kPickEditAllowPick+kPickEditAllowEdit;
goto eeedittt;
case mEditInstrument:
{
ComponentResult result;
long index,part;
MusicComponent mc;
flags = kPickEditAllowEdit;
eeedittt:
result = NAGetNoteChannelInfo(g->na,ag->nc,&index,&part);
result = NAGetRegisteredMusicDevice(g->na,index,nil,nil,nil,&mc);
DisposeHandleAt(&ag->iH);
result = NAPickEditInstrument(g->na,MyFilterProc,"\ppick edit",
0,
ag->nc,
nil,flags);
if(flags & kPickEditAllowEdit)
result = WBLGetPartAtomicInstrument(mc,part,&ag->iH,0);
//result = NAGetNoteChannelInfo(g->na,ag->nc,&index,&part);
//result = NAGetNoteRequest(g->na,ag->nc,&ag->nr);
}
break;
case mClearGrid:
{
short i,j;
for(i = 0; i < kMaxSequenceLength; i++)
for(j = 0; j < kMaxSequenceKeys; j++)
ap->a[i][j] = 0;
FillInGrid();
SetHasNotes(g->displayGridLetter,g->displayGridNumber);
}
break;
case mStdGrid:
{
short i,j;
for(i = 0; i < kMaxSequenceLength; i++)
for(j = 0; j < kMaxSequenceKeys; j++)
ap->a[i][j] = 0;
for(j = 0; j < kMaxSequenceKeys; j++)
ap->a[j][j] = 1;
SetGridEnd(kMaxSequenceKeys);
FillInGrid();
SetHasNotes(g->displayGridLetter,g->displayGridNumber);
}
break;
case mDoubleGrid:
{
short i,j,newLength;
newLength = ap->length * 2;
if(newLength > kMaxSequenceLength)
newLength = kMaxSequenceLength;
for(i = ap->length; i < newLength; i++)
for(j = 0; j < kMaxSequenceKeys; j++)
ap->a[i][j] = ap->a[i - ap->length][j];
SetGridEnd(newLength);
FillInGrid();
}
break;
}
}
void RecordToMovie(short n,short menu,short ref)
{
StandardFileReply sfr;
Str255 s;
NoteRequest *nr;
AtomicInstrument ai;
long i;
if(!(g->recording || g->waitingToRecord))
{
CopyPString(s,"\puntitled wbl movie");
StandardPutFile("\pRecord WBL 4014:", s, &sfr);
if(!sfr.sfGood)
goto goHome;
g->mc = NewMusicConstructor();
for(i = 0; i < kArpGridCount; i++)
{
ai = g->ag[i].iH;
if(ai)
AddAtomicInstrumentMC(g->mc,i,ai);
}
StartMovieMC(g->mc,&sfr.sfFile,kWBLMovieTimeScale);
g->recordingT = 0;
g->waitingToRecord = true;
}
else
{
g->recording = false;
EndMovieMC(g->mc,g->recordingT);
DisposeMusicConstructorAt(&g->mc);
}
goHome:
FixUpMenus(true);
}
void KeyDoc(short n,short key,short code,short mods)
/*
* 28, 29, 31, 30 = L R D U
*/
{
short i;
short x;
ArpGrid *ag;
ArpPattern *ap;
GetDisplayAgAp(g,&ag,&ap);
if(key >= 'A' && key <= 'Z')
key += 'a' - 'A';
if(key >= 'a' && key < 'a' + kArpGridCount)
SetDisplayGrid(key - 'a',-1);
switch(key)
{
case ' ':
for(i = 0; i < 128; i++)
KeyDownKey(g,ag,i,0,false);
break;
case 28: /* left arrow, go to pattern-number - 1 */
x = -1;
bumpPattern:
if(mods & optionKey) /* option key means bump *all* patterns */
{
x = (g->displayGridNumber + 100 + x) % 100;
SetDisplayGrid(g->displayGridLetter,x);
for(i = 0; i < kArpGridCount; i++)
{
ArpGrid *ag;
ag = &g->ag[i];
ag->nextPlayingGridNumber = x;
EnsureAgAp(i,ag->nextPlayingGridNumber);
}
}
else
{
x = (g->displayGridNumber + 100 + x) % 100;
SetDisplayGrid(g->displayGridLetter,x);
}
break;
case 29: /* right arrow */
x = 1;
goto bumpPattern;
case 31: /* right arrow */
x = 10;
goto bumpPattern;
case 30: /* right arrow */
x = -10;
goto bumpPattern;
}
}
void SetGridEnd(short newEnd)
{
ArpGrid *ag;
ArpPattern *ap;
GetDisplayAgAp(g,&ag,&ap);
if(newEnd != ap->length)
{
DrawGridEnd(ap->length,newEnd);
if(ap->length < newEnd)
{
DrawGrid(ap->length,newEnd,false,
0,ag->keyCount,true);
DrawGrid(ap->length,newEnd,false,
ag->keyCount,kMaxSequenceKeys,false);
}
else
{
DrawGrid(newEnd,ap->length,true,
0,kMaxSequenceKeys,false);
}
ap->length = newEnd;
}
}
PM.3/18/96 - 9:08.PM