WBL4014Sets.c

WBL4014Sets.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