home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Music Architecture / Embedding Instruments / MusicHelper.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-06  |  7.7 KB  |  425 lines  |  [TEXT/KAHL]

  1.  
  2.  
  3. #include <types.h>
  4. #include <QuickTimeComponents.h>
  5.  
  6. #define _MusicHelperC_
  7.  
  8.  
  9.  
  10. #define kFullVolume 256
  11.  
  12. typedef struct
  13.     {
  14.     short partCount;
  15.     ToneDescription **toneDescriptions;
  16.     FlatInstrument ***flatInstruments;
  17.  
  18.     long tuneSize;
  19.     long tuneHandleSize;
  20.     unsigned long **tune;
  21.     } MusicScoreRecord, **MusicScore;
  22.  
  23.  
  24.  
  25. typedef struct
  26.     {
  27.     Movie mo;
  28.     Track tr;
  29.     Media me;
  30.  
  31.     MusicDescriptionHandle mdH;
  32.     TimeValue duration;
  33.     short refNum;
  34.     } MusicMovieRecord, **MusicMovie;
  35.  
  36.  
  37. #include "MusicHelper.h"
  38.  
  39.  
  40. #define kTuneHandleBump 1024
  41.  
  42.  
  43.  
  44. static void StuffToneDescription(short gmNumber,ToneDescription *td);
  45. static void BumpTuneHandleSize(MusicScoreRecord *msr);
  46. static short InternalAddPart(MusicScore ms,ToneDescription *td,FlatInstrument *flat);
  47.  
  48.  
  49. #define hLock(x) HLock((Handle)(x))
  50. #define hUnlock(x) HUnlock((Handle)(x))
  51.  
  52. MusicScore NewMusicScore(void)
  53.     {
  54.     MusicScoreRecord *msr;
  55.     MusicScore ms;
  56.  
  57.     ms = (MusicScore)NewHandle(sizeof(MusicScoreRecord));
  58.     hLock(ms);
  59.     msr = *ms;
  60.     msr->partCount= 0;
  61.     msr->toneDescriptions = (ToneDescription **)NewHandle(0);
  62.     msr->flatInstruments = (FlatInstrument ***)NewHandle(0);
  63.     msr->tuneSize = 0;
  64.     msr->tuneHandleSize = kTuneHandleBump;
  65.     msr->tune = (unsigned long**)NewHandle(kTuneHandleBump * sizeof(long));
  66.     hUnlock(ms);
  67.  
  68.     return ms;
  69.     }
  70.  
  71.  
  72. void DisposeMusicScore(MusicScore *ms)
  73.     {
  74.     MusicScoreRecord *msr;
  75.  
  76.     hLock(*ms);
  77.     msr = **ms;
  78.     DisposeHandle((Handle)msr->toneDescriptions);
  79.     DisposeHandle((Handle)msr->tune);
  80.     *ms = nil;
  81.     }
  82.  
  83. short AddMusicScoreGMInstrument(MusicScore ms,short gmInstrument)
  84.     {
  85.     ToneDescription td;
  86.  
  87.     StuffToneDescription(gmInstrument,&td);
  88.     return AddMusicScoreInstrument(ms,&td);
  89.     }
  90.  
  91. short AddMusicScoreInstrument(MusicScore ms,ToneDescription *td)
  92.     {
  93.     return InternalAddPart(ms,td,nil);
  94.     }
  95.  
  96.  
  97. short AddMusicScoreFlatInstrument(MusicScore ms,FlatInstrument *flat)
  98.     {
  99.     return InternalAddPart(ms,&flat->tone,flat);
  100.     }
  101.  
  102.  
  103.  
  104.  
  105. short InternalAddPart(MusicScore ms,ToneDescription *td,FlatInstrument *flat)
  106.     {
  107.     MusicScoreRecord *msr;
  108.  
  109.     hLock(ms);
  110.     msr = *ms;
  111.     msr->partCount++;
  112.     SetHandleSize((Handle)msr->toneDescriptions,msr->partCount * sizeof(ToneDescription));
  113.     SetHandleSize((Handle)msr->flatInstruments,msr->partCount * sizeof(FlatInstrument *));
  114.     (*msr->toneDescriptions)[msr->partCount-1] = *td;
  115.     (*msr->flatInstruments)[msr->partCount-1] = flat;
  116.     hUnlock(ms);
  117.     return msr->partCount;
  118.     }
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126. void AddMusicScoreNote(MusicScore ms,short part,Fixed pitch,long velocity,TimeValue noteDuration)
  127.     {
  128.     MusicScoreRecord *msr;
  129.     unsigned long *w;
  130.  
  131.     hLock(ms);
  132.     msr = *ms;
  133.     
  134.     part--;
  135.  
  136.     BumpTuneHandleSize(msr);
  137.  
  138.     HLock((Handle)msr->tune);
  139.     w = *(msr->tune) + msr->tuneSize;
  140.  
  141.     if(pitch >= 32 && pitch <= 95 && part < 32
  142.             && noteDuration < 2048)
  143.         {
  144.         _StuffNoteEvent(*w,part,pitch,velocity,noteDuration);
  145.         msr->tuneSize ++;
  146.         }
  147.     else
  148.         {
  149.         _StuffXNoteEvent(*w,*(w+1),part,pitch,velocity,noteDuration);
  150.         msr->tuneSize += 2;
  151.         }
  152.  
  153.     hUnlock(msr->tune);
  154.     hUnlock(ms);
  155.     }
  156.  
  157. void AddMusicScoreRest(MusicScore ms,TimeValue restDuration)
  158.     {
  159.     MusicScoreRecord *msr;
  160.     unsigned long *w;
  161.  
  162.     hLock(ms);
  163.     msr = *ms;
  164.  
  165.     BumpTuneHandleSize(msr);
  166.  
  167.     HLock((Handle)msr->tune);
  168.     w = *(msr->tune) + msr->tuneSize;
  169.  
  170.     _StuffRestEvent(*w,restDuration);
  171.     msr->tuneSize ++;
  172.  
  173.     hUnlock(msr->tune);
  174.     hUnlock(ms);
  175.     }
  176.  
  177. #define kNoteRequestMessageSize sizeof(NoteRequest)/4 + 2
  178.  
  179.  
  180. Handle GetMusicScoreHeader(MusicScore ms)
  181.     {
  182.     Handle h;
  183.     unsigned long *w;
  184.     long size;
  185.     NoteRequest *nr;
  186.     FlatInstrument *flat;
  187.     MusicScoreRecord *msr;
  188.     int i;
  189.  
  190.     hLock(ms);
  191.     msr = *ms;
  192.  
  193.     size = msr->partCount*(8 + sizeof(NoteRequest))
  194.             + 4; /* 8 bytes for general music message, 
  195.                         + 4 for end marker */
  196.  
  197.     for(i = 0; i < msr->partCount; i++)
  198.         {
  199.         flat = (*msr->flatInstruments)[i];
  200.         if(flat)
  201.             size += flat->size;
  202.         }
  203.  
  204.  
  205.     h = NewHandleClear(size);
  206.     w = (unsigned long *)*h;
  207.  
  208.     for(i = 0; i < msr->partCount; i++)
  209.         {
  210.         flat = (*msr->flatInstruments)[i];
  211.         if(flat)
  212.             {
  213.             size = kNoteRequestMessageSize + (flat->size + 3)/4;
  214.             _StuffGeneralEvent(*w,*(w + size - 1),
  215.                     i,kGeneralEventFlatInstrument,size);
  216.             nr = (NoteRequest *)(w + 1);
  217.     
  218.             nr->polyphony = 1;
  219.             nr->typicalPolyphony = 0x10000;
  220.     
  221.             nr->tone = (*msr->toneDescriptions)[i];
  222.             BlockMove(&flat->size,((char *)&nr->tone) + sizeof(ToneDescription),flat->size);
  223.     
  224.             w += size;
  225.             }
  226.         else
  227.             {
  228.             _StuffGeneralEvent(*w,*(w + kNoteRequestMessageSize - 1),
  229.                     i,kGeneralEventNoteRequest,kNoteRequestMessageSize);
  230.             nr = (NoteRequest *)(w + 1);
  231.     
  232.             nr->polyphony = 1;
  233.             nr->typicalPolyphony = 0x10000;
  234.     
  235.             nr->tone = (*msr->toneDescriptions)[i];
  236.     
  237.             w += kNoteRequestMessageSize;
  238.             }
  239.         }
  240.  
  241.     *w++ = 0x60000000;                        /* end marker */
  242.  
  243.     hUnlock(ms);
  244.  
  245.     return h;
  246.     }
  247.  
  248. Handle GetMusicScoreScore(MusicScore ms)
  249.     {
  250.     Handle h;
  251.     MusicScoreRecord *msr;
  252.     unsigned long *w;
  253.     long size;
  254.  
  255.     hLock(ms);
  256.     msr = *ms;
  257.  
  258.     size = msr->tuneSize * sizeof(unsigned long) + 4;
  259.  
  260.     msr = *ms;
  261.     h = NewHandle(size);
  262.     BlockMove(*msr->tune, *h, size);
  263.     (*(unsigned long **)h)[msr->tuneSize] = 0x60000000;
  264.  
  265.     hUnlock(ms);
  266.  
  267.     return h;
  268.     }
  269.  
  270.  
  271.  
  272. void StuffToneDescription(short gmNumber,ToneDescription *td)
  273.     {
  274.     ComponentResult result;
  275.     NoteAllocator na;
  276.  
  277.  
  278.     na = OpenDefaultComponent('nota',0);
  279.     if(na)
  280.         {
  281.         NAStuffToneDescription(na,gmNumber,td);
  282.         CloseComponent(na);
  283.         }
  284.     else
  285.         {
  286.         td->synthesizerType = 0;
  287.         td->synthesizerName[0] = 0;
  288.         td->instrumentName[0] = 0;
  289.         td->instrumentNumber = 0;
  290.         td->gmNumber = gmNumber;
  291.         }
  292.     }
  293.  
  294. #define kTuneSizeMargin 16
  295.  
  296. void BumpTuneHandleSize(MusicScoreRecord *msr)
  297.     {
  298.     if(msr->tuneHandleSize - msr->tuneSize < kTuneSizeMargin)
  299.         {
  300.         msr->tuneHandleSize += kTuneHandleBump;
  301.         SetHandleSize((Handle)msr->tune,msr->tuneHandleSize * sizeof(unsigned long));
  302.         }
  303.     }
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316. MusicMovie StartMusicMovie(FSSpec *movieSpec,Handle header)
  317.     {
  318.     MusicMovie mm;
  319.     MusicMovieRecord *mmr;
  320.     ComponentResult thisError;
  321.     unsigned long size;
  322.  
  323.     EnterMovies();
  324.  
  325.     mm = (MusicMovie)NewHandle(sizeof(MusicMovieRecord));
  326.     hLock(mm);
  327.     mmr = *mm;
  328.  
  329.     thisError = CreateMovieFile(movieSpec,'TVOD',0,
  330.              createMovieFileDeleteCurFile,
  331.              &mmr->refNum,
  332.              &mmr->mo);
  333.      SetMoviePreferredVolume(mmr->mo,kFullVolume);
  334.      SetMovieVolume(mmr->mo,kFullVolume);
  335.     mmr->tr = NewMovieTrack(mmr->mo,0,0,kFullVolume);
  336.     mmr->me = NewTrackMedia(mmr->tr,kMusicComponentType,600,0,0);
  337.     thisError = GetMoviesError();
  338.  
  339.     size = sizeof(MusicDescription) + GetHandleSize(header);
  340.  
  341.     mmr->mdH = (void *)NewHandleClear(size);
  342. // ••• ???    (**mmr->mdH).size = size;
  343. // ••• ???    (**mmr->mdH).type = 'musi';
  344.     BlockMove(*header,&(**mmr->mdH).headerData,GetHandleSize(header));
  345.  
  346.     mmr->duration = 0;
  347.  
  348.     thisError = BeginMediaEdits(mmr->me);
  349.  
  350.     hUnlock(mm);
  351.  
  352.     return mm;
  353.     }
  354.  
  355.  
  356. void AddMusicMovieSample(MusicMovie mm,Handle score)
  357.     {
  358.     MusicMovieRecord *mmr;
  359.     ComponentResult thisError;
  360.     TimeValue sampleDuration;
  361.     unsigned long sampleLength;
  362.  
  363.     hLock(mm);
  364.     mmr = *mm;
  365.  
  366.     // • Compute duration of tune
  367.         {
  368.         unsigned long *start,*w,*end;
  369.         unsigned long eventType,eventLength;
  370.         unsigned long x;
  371.  
  372.         start = (unsigned long *)*score;
  373.         end = (unsigned long *)( ((char *)*score) + GetHandleSize(score));
  374.  
  375.         w = start;
  376.         sampleDuration = 0;
  377.         while(w < end)
  378.             {
  379.             x = *w;
  380.             eventLength = _EventLength(x);
  381.             eventType = _EventType(x);
  382.             if(eventType == kRestEventType)
  383.                 sampleDuration += _RestDuration(x);
  384.             if(eventLength < 1 || eventLength > 1000)
  385.                 goto done;
  386.             w += eventLength;
  387.             }
  388. done:
  389.         sampleLength = (w - start) * sizeof(unsigned long);
  390.         }
  391.  
  392.     thisError = AddMediaSample(mmr->me,score,0,sampleLength,
  393.             sampleDuration,(void *)mmr->mdH,
  394.             1,0,0);
  395.  
  396.     mmr->duration += sampleDuration;
  397.  
  398.     hUnlock(mm);
  399.     }
  400.  
  401.  
  402.  
  403. void FinishMusicMovie(MusicMovie *mm)
  404.     {
  405.     MusicMovieRecord *mmr;
  406.     ComponentResult thisError;
  407.  
  408.     hLock(*mm);
  409.     mmr = **mm;
  410.  
  411.     thisError = InsertMediaIntoTrack(mmr->tr,0,0,mmr->duration,(1L<<16));
  412.     thisError = EndMediaEdits(mmr->me);
  413.  
  414.      thisError = AddMovieResource(mmr->mo,mmr->refNum,nil,nil);
  415.     thisError = CloseMovieFile(mmr->refNum);
  416.  
  417.     DisposeHandle((Handle)*mm);
  418.     *mm = 0;
  419.  
  420.     ExitMovies();
  421.     }
  422.  
  423.  
  424.  
  425.