⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 midimgr.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
    Init.portType = midiPortTypeOutput;    Init.timeBase = TimeRefNum;    Init.offsetTime = midiGetCurrent;    Init.readHook = NULL;    Init.refCon = refCon0;    C2PStrCpy("OutputPort", Init.name);    TheErr = MIDIAddPort(CMTclientID, outputPortBuffSize, &OutputRefNum, &Init);    /* Has a PatchBay connection been resolved? */    if (TheErr == midiVConnectMade) {        GManualPatch = false;    } else if (TheErr == memFullErr) {        printf("Not enough room in heap zone to add output port!  Aborting...");        MIDISignOut(CMTclientID);               EXIT(1);    }            if (GManualPatch) {        PatchPorts(); /* connect ports as they were */    }    /* to clean this up (later) call finish_midimgr() */    cu_register((cu_fn_type) finish_midimgr, (cu_parm_type) finish_midimgr);            /* Start our Clock. */    MIDIStartTime(TimeRefNum);              }/* The Read Hook Function. *//* 1st 4 bytes of sysex message get saved here and enqueued later */char save_sysex_head[4];int save_sysex_head_x = 0;void sysex_insert(unsigned char data) {    if (save_sysex_head_x < 4) {        save_sysex_head[save_sysex_head_x++] = data;    }    xbuff[xbuftail++] = data;    xbuftail &= xbufmask;    if (xbuftail == xbufhead) {        set_error(SYSEXOVFL);    }    if (data == MIDI_EOX) { /* we're done with the message */        *((long *) (((byte *) buff) + bufftail)) = *((long *)save_sysex_head);        bufftail = (bufftail + 4) & BUFF_MASK;        if (bufftail == buffhead) {            set_error(BUFFOVFL);        }    }}/* Read all incomming MIDI data. */pascal short CMTreader(MIDIPacket *ThePacketPtr, long TheRefCon){    /* Set up our A5 world. */    long    SysA5 = SetA5(TheRefCon);    short   RetVal = midiMorePacket, i, j;    unsigned char *mm_data = ThePacketPtr->data;    register byte data1 = mm_data[1];            if (midi_read_lock) {        /* Don't want to read packet now, get it later */        /* DOES THIS REALLY WORK?  WHAT WILL CAUSE AN INTERRUPT         * TO OCCUR LATER?  THIS IS ONLY USED BY midi_flush, IS         * BASED ON THE MidiArp CODE FROM APPLE, AND IS UNTESTED - RBD         */        RetVal = midiKeepPacket;        goto alldone;	    }    /* see if Packet is an error message */    if (((ThePacketPtr->flags & midiTypeMask) == midiMgrType) &&         *((short *) (&(ThePacketPtr->data))) < midiMaxErr) {        set_error(MIDIMGRERR);        goto alldone;    }            /* filter out control changes */    if (ctrlFilter) {        register int hibits = *mm_data & 0xF0;        if (hibits == 0xD0 ||   /* Chan Pressure */            hibits == 0xE0 ||       /* Pitch Bend */            hibits == 0xA0 ||       /* Poly Pressure */            ((hibits == 0xB0) &&    /* Control change (don't count switches) */             ((data1 < 64) || (data1 > 121)))) {            /* CONTROL MESSAGE HAS BEEN FILTERED */            goto alldone;        }    } else if (realFilter) {        register int hibits = *mm_data & 0xF0;        if (hibits >= 0xF8) goto alldone;    }            /* if not a continuation, copy the data into cmt_data */    /* The logic to detect a non-continued     * packet or a first packet is: "flags bit 1 is clear".     */    if ((((ThePacketPtr->flags & midiContMask) == midiNoCont)) &&         (*mm_data != MIDI_SYSEX)) {        register byte *cmt_data = ((byte *) buff) + bufftail;        *((long *) cmt_data) = *((long *) mm_data);        bufftail = (bufftail + 4) & BUFF_MASK;        if (bufftail == buffhead) {            /* filled buffer faster than client emptied it */            set_error(BUFFOVFL);        }    }            /* see if we have a sysex message to copy to buffer */    if (xbuff && !exclFilter &&        ((ThePacketPtr->flags & midiContMask) || *mm_data == MIDI_SYSEX)) {        int i;        register byte *x_data = xbuff + xbuftail;        /* iterate over data in message */        /* NOTE: in the previous implementation, I thought Sysex messages were         * always starting at the beginning of the buffer, but that didn't work.         * This implementation assumes nothing -- it is slower because of additional         * testing and parsing inside the loop, but seems to work.         */        for (i = ThePacketPtr->len - 6; i > 0; i--) {            if (xbuf_flush) {	/* we're searching for beginning of message */                if (*mm_data == MIDI_SYSEX) {                    xbuf_flush = false;                    sysex_insert(MIDI_SYSEX);                }            } else {	/* we're scanning to the end of the message */                if (*mm_data == MIDI_SYSEX) {	/* found it, insert proper EOX */                    sysex_insert(MIDI_EOX);                    sysex_insert(MIDI_SYSEX);                } else if (*mm_data == MIDI_EOX) {	/* found it */                    sysex_insert(MIDI_EOX);                    xbuf_flush = true;                } else sysex_insert(*mm_data);            }            mm_data++;        }    }alldone:    /* Restore the systems A5 world. */    SetA5(SysA5);        return(RetVal);}/* Sign out from the MIDI Manager. */void finish_midimgr(void){        if (GManualPatch && patch_flag) {                SavePatch(timePortID, timePortResInfoID, "timePortInfo");                SavePatch(inputPortID, inputPortResInfoID, "inputPortInfo");                SavePatch(outputPortID, outputPortResInfoID, "outputPortInfo");        }        MIDISignOut(CMTclientID);}/* Alert user to Resource Manager Error. */voidReportResError(char *Msg){        OSErr   TheErr;        char    Buf[256];                if ( (TheErr = ResError()) != noErr) {                gprintf(ERROR, "ResError %d: %s...Aborting.", TheErr, Msg);                EXIT(1);        } else {                /* gprintf(ERROR, "%s OK\n", Msg); */        }}/*****************************************************************************                                       error handling* Effect:*       various error conditions are flagged by setting bits in*       the global midi_error_flags.  it is up to the client to clear this *       word when necessary.****************************************************************************/private void set_error(int bit){        midi_error_flags |= (1 << bit);}void midi_show_errors(){    if (midi_error_flags & (1<<BUFFOVFL))         gprintf(ERROR, "Midi Buffer Overflow Error\n");    if (midi_error_flags & (1<<MIDIMGRERR))         gprintf(ERROR, "Midi Manager Error\n");    if (midi_error_flags & (1<<SYSEXOVFL))         gprintf(ERROR, "Midi Sysex Overflow Error\n");}/**************** PATCHING CODE ***************//*        MIDIArp Time, Input, and Output Port         Info Record Resource ID's.*//* Get previously saved port connections (port info records) *//* from application's 'port' resource. */voidPatchPorts(void){        MIDIPortInfoHdl PortInfoH;      /* Handle to port info record. */        MIDIPortInfoPtr PortInfoP;      /* Pointer to port info record. */        short                   i, TheErr;                patch_flag = cl_switch("patch");                                /* SET UP TIME PORT CONNECTIONS. */        if (patch_flag)                PortInfoH = (MIDIPortInfoHdl) GetResource(portResType, timePortResInfoID);        if (!patch_flag || PortInfoH == NULL) {                MIDIIDListHdl clients, ports;                OSErr err;                                gprintf(TRANS, "Connecting to MIDI IN and OUT\n");#ifdef MIDIMGR_VERBOSE                clients = MIDIGetClients();                gprintf(TRANS, "clients = %lx\n", clients);                HLock((Handle) clients);                                for (i = 0; i < (*clients)->numIDs; i++) {                        OSType id = (*clients)->list[i];                        gprintf(TRANS, "%d: %c%c%c%c\n", i, (char) (id>>24),                                    (char) ((id >> 16) & 0xFF), (char) ((id >> 8) & 0xFF),                                    (char) (id & 0xFF));                }                ports = MIDIGetPorts('amdr');                HLock((Handle) ports);                for (i = 0; i < (*ports)->numIDs; i++) {                        OSType id = (*ports)->list[i];                        gprintf(TRANS, "%d: %c%c%c%c\n", i, (char) (id>>24),                                    (char) ((id >> 16) & 0xFF), (char) ((id >> 8) & 0xFF),                                    (char) (id & 0xFF));                }                HUnlock((Handle) ports);                HUnlock((Handle) clients);#endif                /* the work starts here */                err = MIDIConnectData('CMT ', 'Cout', 'amdr', 'Aout');                /* gprintf(TRANS, "Connected CMT.Cout to amdr.Aout: %d\n", err); */                err = MIDIConnectData('amdr', 'Ain ', 'CMT ', 'Bin ');                /* gprintf(TRANS, "Connected amdr.Ain to CMT.Bin: %d\n", err); */                return;        }        HLock((Handle) PortInfoH);        PortInfoP = *PortInfoH;        if (GetHandleSize((Handle) PortInfoH) != 0)        {                        /* Were we supposed to be sync'd to another client? */                if (PortInfoP->timeBase.clientID != noClient)                {                                                   /* Yes, so make that client our time base. */                        TheErr = MIDIConnectTime(                                                                    PortInfoP->timeBase.clientID,                                                                     PortInfoP->timeBase.portID,                                                                    CMTclientID,                                                                     timePortID                                                                     );#ifdef IGNORE                                    /* Is the client still signed in? */                        if (TheErr != midiVConnectErr)                         {                                                           /* Yes, so set our sync mode to external. */                                    MIDISetSync(ArpGlobals.TimeRefNum, midiExternalSync);                        }#endif                                        }                        /* Were we somebody else's time base? */                for (i=0; i<PortInfoP->numConnects; i++)                {                        MIDIConnectTime(CMTclientID,                                                                     timePortID,                                                                     PortInfoP->cList[i].clientID,                                                                     PortInfoP->cList[i].portID);                }        }        HUnlock((Handle) PortInfoH);        ReleaseResource((Handle) PortInfoH);        ReportResError("PatchPorts/ReleaseResource()");                        /* SET UP INPUT PORT CONNECTIONS. */        PortInfoH = (MIDIPortInfoHdl) GetResource(portResType, inputPortResInfoID);        if (PortInfoH == NULL)        {                ReportResError("PatchPorts/GetResource()");        }        HLock((Handle) PortInfoH);        PortInfoP = *PortInfoH;        if (GetHandleSize((Handle) PortInfoH) != 0)        {                        /* Were we connected to anyone? */                for (i=0; i<PortInfoP->numConnects; i++)                {                        MIDIConnectData(CMTclientID,                                                                     inputPortID,                                                                     PortInfoP->cList[i].clientID,                                                                     PortInfoP->cList[i].portID);                }        }        HUnlock((Handle) PortInfoH);        ReleaseResource((Handle) PortInfoH);        ReportResError("PatchPorts/GetResource()");                        /* SET UP OUTPUT PORT CONNECTIONS. */        PortInfoH = (MIDIPortInfoHdl) GetResource(portResType, outputPortResInfoID);        if (PortInfoH == NULL)        {                       ReportResError("PatchPorts/GetResource()");        }        HLock((Handle) PortInfoH);        PortInfoP = *PortInfoH;        if (GetHandleSize((Handle) PortInfoH) != 0) {                        /* Were we connected to anyone? */                for (i=0; i<PortInfoP->numConnects; i++)                {                        MIDIConnectData(CMTclientID,                                                                     outputPortID,                                                                     PortInfoP->cList[i].clientID,                                                                     PortInfoP->cList[i].portID);                }        }        HUnlock((Handle) PortInfoH);        ReleaseResource((Handle) PortInfoH);        ReportResError("PatchPorts/ReleaseResource()");        }/* Save current port connections (port info records) *//* to application's 'port' resource. */voidSavePatch(OSType PortID, short PortInfoResID, char *PortInfoResName){        Handle                  PortResH;       /* Handle to ptch resource. */        CursHandle              WatchCurs;                      WatchCurs = GetCursor(watchCursor);        HLock((Handle) WatchCurs);        SetCursor(*WatchCurs);        HUnlock((Handle) WatchCurs);                        /* Remove existing port info resource. */        PortResH = GetResource(portResType, PortInfoResID);        /* gprintf(TRANS, "PortResH: %lx, *PortResH: %lx\n", PortResH, *PortResH); */        if (PortResH) {                ReportResError("SavePatch/GetResource()");                RmveResource(PortResH);                ReportResError("SavePatch/RmveResource()");                DisposHandle(PortResH);                UpdateResFile(CurResFile());                ReportResError("SavePatch/UpdateResFile()");        }                        /*      Get new configurateion. */        PortResH = (Handle) MIDIGetPortInfo(CMTclientID, PortID);                        /*      Save new configurateion. */        CtoPstr(PortInfoResName);        AddResource(PortResH, portResType, PortInfoResID,            (ConstStr255Param) PortInfoResName);        PtoCstr((unsigned char *) PortInfoResName);                ReportResError("SavePatch/AddResource()");        WriteResource(PortResH);        ReportResError("SavePatch/WriteResource()");        UpdateResFile(CurResFile());        ReportResError("SavePatch/UpdateResFile()");        ReleaseResource(PortResH);        ReportResError("SavePatch/ReleaseResource()");                InitCursor();}#endif /* NYQUIST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -