Beispiel #1
0
 private static extern void midi_WavFileOut(
     IntPtr filePath,
     IntPtr pWaveTable,
     INST_LIST *list,
     uint sampleRate,
     uint bitRate,
     IntPtr pEvents,
     uint eventSize,
     uint baseTick
     );
Beispiel #2
0
        public Sender(string dlsPath)
        {
            uint fileSize = 0;

            mpWaveTable = waveout_LoadWaveTable(Marshal.StringToHGlobalAuto(dlsPath), out fileSize);
            mpInstList  = (INST_LIST *)Marshal.AllocHGlobal(Marshal.SizeOf <INST_LIST>());
            var dls = new DLS.DLS(mpWaveTable, fileSize);

            dls.GetInstList(mpInstList);
            //var sf2 = new SF2.SF2(dlsPath, mpWaveTable, fileSize);
            //sf2.GetInstList(mpInstList);
            waveout_SystemValues(SampleRate, 16, 220, 50, CHANNEL_COUNT, SAMPLER_COUNT);
            mppChannels = waveout_GetChannelPtr();
            mppSamplers = waveout_GetSamplerPtr();
            mppNotes    = waveout_GetNotePtr();
            midi_CreateChannels(mpInstList, mppSamplers, mppNotes, mppChannels, SAMPLER_COUNT);
            mppChParam = midi_GetChannelParamPtr();
            waveout_Open();
        }
Beispiel #3
0
        unsafe public void GetInstList(INST_LIST *list)
        {
            list->instCount = 0;
            list->ppInst    = (INST_REC **)Marshal.AllocHGlobal(sizeof(INST_REC *) * Instruments.List.Count);
            foreach (var inst in Instruments.List)
            {
                list->ppInst[list->instCount] = (INST_REC *)Marshal.AllocHGlobal(Marshal.SizeOf <INST_REC>());
                var pInst = list->ppInst[list->instCount];
                list->instCount++;
                //
                pInst->id.isDrum    = (byte)(inst.Header.locale.bankFlags == 0x80 ? 1 : 0);
                pInst->id.programNo = inst.Header.locale.programNo;
                pInst->id.bankMSB   = inst.Header.locale.bankMSB;
                pInst->id.bankLSB   = inst.Header.locale.bankLSB;
                pInst->regionCount  = inst.Regions.List.Count;
                if (string.IsNullOrWhiteSpace(inst.Name))
                {
                    pInst->pName = Marshal.StringToHGlobalAuto(string.Format(
                                                                   "MSB:{0} LSB:{1} PROG:{2}",
                                                                   pInst->id.bankMSB.ToString("000"),
                                                                   pInst->id.bankLSB.ToString("000"),
                                                                   pInst->id.programNo.ToString("000")
                                                                   ));
                }
                else
                {
                    pInst->pName = Marshal.StringToHGlobalAuto(inst.Name);
                }
                if (string.IsNullOrWhiteSpace(inst.Category))
                {
                    if (0 < pInst->id.isDrum)
                    {
                        pInst->pCategory = Marshal.StringToHGlobalAuto("Drum set");
                    }
                    else
                    {
                        pInst->pCategory = Marshal.StringToHGlobalAuto("");
                    }
                }
                else
                {
                    pInst->pCategory = Marshal.StringToHGlobalAuto(inst.Category);
                }
                pInst->ppRegions = (REGION **)Marshal.AllocHGlobal(sizeof(REGION *) * inst.Regions.List.Count);

                #region instEnv
                var instEnv = new ENVELOPE();
                instEnv.deltaA = 1000.0 * Sender.DeltaTime * Sender.AttackSpeed;  // 1msec
                instEnv.deltaD = 1000.0 * Sender.DeltaTime * Sender.DecaySpeed;   // 1msec
                instEnv.deltaR = 1000.0 * Sender.DeltaTime * Sender.ReleaseSpeed; // 1msec
                instEnv.levelS = 1.0;
                instEnv.hold   = 0.0;
                if (null != inst.Articulations)
                {
                    foreach (var conn in inst.Articulations.Art.List)
                    {
                        if (SRC_TYPE.NONE != conn.source)
                        {
                            continue;
                        }
                        switch (conn.destination)
                        {
                        case DST_TYPE.EG1_ATTACK_TIME:
                            instEnv.deltaA = Sender.AttackSpeed * Sender.DeltaTime / ART.GetValue(conn);
                            instEnv.hold  += ART.GetValue(conn);
                            break;

                        case DST_TYPE.EG1_HOLD_TIME:
                            instEnv.hold += ART.GetValue(conn);
                            break;

                        case DST_TYPE.EG1_DECAY_TIME:
                            instEnv.deltaD = Sender.DecaySpeed * Sender.DeltaTime / ART.GetValue(conn);
                            break;

                        case DST_TYPE.EG1_RELEASE_TIME:
                            instEnv.deltaR = Sender.ReleaseSpeed * Sender.DeltaTime / ART.GetValue(conn);
                            break;

                        case DST_TYPE.EG1_SUSTAIN_LEVEL:
                            instEnv.levelS = (0.0 == ART.GetValue(conn)) ? 1.0 : (ART.GetValue(conn) * 0.01);
                            break;
                        }
                    }
                }
                if (instEnv.hold < Sender.DeltaTime)
                {
                    instEnv.hold = Sender.DeltaTime;
                }
                #endregion

                var ppRegions = pInst->ppRegions;
                var rgnIdx    = 0;
                foreach (var rgn in inst.Regions.List)
                {
                    ppRegions[rgnIdx] = (REGION *)Marshal.AllocHGlobal(Marshal.SizeOf <REGION>());
                    var pRegion = ppRegions[rgnIdx];
                    rgnIdx++;

                    if (null == rgn.Articulations)
                    {
                        pRegion->env = instEnv;
                    }
                    else
                    {
                        #region regionEnv
                        var regionEnv = new ENVELOPE();
                        regionEnv.deltaA = 1000.0 * Sender.DeltaTime * Sender.AttackSpeed;  // 1msec
                        regionEnv.deltaD = 1000.0 * Sender.DeltaTime * Sender.DecaySpeed;   // 1msec
                        regionEnv.deltaR = 1000.0 * Sender.DeltaTime * Sender.ReleaseSpeed; // 1msec
                        regionEnv.levelS = 1.0;
                        regionEnv.hold   = 0.0;
                        foreach (var conn in rgn.Articulations.Art.List)
                        {
                            if (SRC_TYPE.NONE != conn.source)
                            {
                                continue;
                            }
                            switch (conn.destination)
                            {
                            case DST_TYPE.EG1_ATTACK_TIME:
                                regionEnv.deltaA = Sender.AttackSpeed * Sender.DeltaTime / ART.GetValue(conn);
                                regionEnv.hold  += ART.GetValue(conn);
                                break;

                            case DST_TYPE.EG1_HOLD_TIME:
                                regionEnv.hold += ART.GetValue(conn);
                                break;

                            case DST_TYPE.EG1_DECAY_TIME:
                                regionEnv.deltaD = Sender.DecaySpeed * Sender.DeltaTime / ART.GetValue(conn);
                                break;

                            case DST_TYPE.EG1_SUSTAIN_LEVEL:
                                regionEnv.levelS = (0.0 == ART.GetValue(conn)) ? 1.0 : (ART.GetValue(conn) * 0.01);
                                break;

                            case DST_TYPE.EG1_RELEASE_TIME:
                                regionEnv.deltaR = Sender.ReleaseSpeed * Sender.DeltaTime / ART.GetValue(conn);
                                break;
                            }
                        }
                        if (regionEnv.hold < Sender.DeltaTime)
                        {
                            regionEnv.hold = Sender.DeltaTime;
                        }
                        #endregion
                        pRegion->env = regionEnv;
                    }

                    var wave    = WavePool.List[(int)rgn.WaveLink.tableIndex];
                    var samples = wave.Size / wave.Format.blockAlign;
                    pRegion->waveInfo.waveOfs = wave.Addr - (uint)mDlsPtr.ToInt64();
                    if (rgn.HasSampler)
                    {
                        pRegion->waveInfo.gain      = rgn.Sampler.Gain / 32768.0;
                        pRegion->waveInfo.unityNote = (byte)rgn.Sampler.unityNote;
                        pRegion->waveInfo.delta
                            = Math.Pow(2.0, rgn.Sampler.fineTune / 1200.0)
                              * wave.Format.sampleRate / Sender.SampleRate;
                        ;
                        if (rgn.HasLoop)
                        {
                            pRegion->waveInfo.loopBegin  = rgn.Loops[0].start;
                            pRegion->waveInfo.loopLength = rgn.Loops[0].length;
                            pRegion->waveInfo.loopEnable = true;
                        }
                        else if (wave.HasLoop)
                        {
                            pRegion->waveInfo.loopBegin  = wave.Loops[0].start;
                            pRegion->waveInfo.loopLength = wave.Loops[0].length;
                            pRegion->waveInfo.loopEnable = true;
                        }
                        else
                        {
                            pRegion->waveInfo.loopBegin  = 0;
                            pRegion->waveInfo.loopLength = samples;
                            pRegion->waveInfo.loopEnable = false;
                            pRegion->env.deltaR          = Sender.DeltaTime * pRegion->waveInfo.delta / samples;
                        }
                    }
                    else
                    {
                        pRegion->waveInfo.gain      = wave.Sampler.Gain / 32768.0;
                        pRegion->waveInfo.unityNote = (byte)wave.Sampler.unityNote;
                        pRegion->waveInfo.delta
                            = Math.Pow(2.0, wave.Sampler.fineTune / 1200.0)
                              * wave.Format.sampleRate / Sender.SampleRate;
                        ;
                        if (wave.HasLoop)
                        {
                            pRegion->waveInfo.loopBegin  = wave.Loops[0].start;
                            pRegion->waveInfo.loopLength = wave.Loops[0].length;
                            pRegion->waveInfo.loopEnable = true;
                        }
                        else
                        {
                            pRegion->waveInfo.loopBegin  = 0;
                            pRegion->waveInfo.loopLength = samples;
                            pRegion->waveInfo.loopEnable = false;
                        }
                    }
                    pRegion->keyLo = (byte)rgn.Header.key.low;
                    pRegion->keyHi = (byte)rgn.Header.key.high;
                    pRegion->velLo = (byte)rgn.Header.velocity.low;
                    pRegion->velHi = (byte)rgn.Header.velocity.high;
                }
            }
        }
Beispiel #4
0
 unsafe public void GetInstList(INST_LIST *list)
 {
     list->instCount = 0;
     list->ppInst    = (INST_REC **)Marshal.AllocHGlobal(sizeof(INST_REC *) * mPdta.PresetList.Count);
     foreach (var preset in mPdta.PresetList)
     {
         list->ppInst[list->instCount] = (INST_REC *)Marshal.AllocHGlobal(Marshal.SizeOf <INST_REC>());
         var pInst = list->ppInst[list->instCount];
         list->instCount++;
         //
         pInst->id.isDrum    = (byte)(0 < preset.Key.isDrum ? 1 : 0);
         pInst->id.programNo = preset.Key.programNo;
         pInst->id.bankMSB   = preset.Key.bankMSB;
         pInst->id.bankLSB   = preset.Key.bankLSB;
         if (string.IsNullOrWhiteSpace(preset.Value.Item1))
         {
             pInst->pName = Marshal.StringToHGlobalAuto(string.Format(
                                                            "MSB:{0} LSB:{1} PROG:{2}",
                                                            pInst->id.bankMSB.ToString("000"),
                                                            pInst->id.bankLSB.ToString("000"),
                                                            pInst->id.programNo.ToString("000")
                                                            ));
         }
         else
         {
             pInst->pName = Marshal.StringToHGlobalAuto(preset.Value.Item1);
         }
         if (0 < pInst->id.isDrum)
         {
             pInst->pCategory = Marshal.StringToHGlobalAuto("Drum set");
         }
         else
         {
             pInst->pCategory = Marshal.StringToHGlobalAuto("");
         }
         //
         pInst->regionCount = 0;
         foreach (var pv in preset.Value.Item2)
         {
             foreach (var iv in mPdta.InstList[pv.instId].Item2)
             {
                 pInst->regionCount++;
             }
         }
         pInst->ppRegions = (REGION **)Marshal.AllocHGlobal(sizeof(REGION *) * pInst->regionCount);
         //
         var ppRegions = pInst->ppRegions;
         var rgnIdx    = 0;
         foreach (var pv in preset.Value.Item2)
         {
             foreach (var iv in mPdta.InstList[pv.instId].Item2)
             {
                 ppRegions[rgnIdx] = (REGION *)Marshal.AllocHGlobal(Marshal.SizeOf <REGION>());
                 var pRegion = ppRegions[rgnIdx];
                 rgnIdx++;
                 //
                 pRegion->keyLo = Math.Max(pv.keyLo, iv.keyLo);
                 pRegion->keyHi = Math.Min(pv.keyHi, iv.keyHi);
                 pRegion->velLo = Math.Max(pv.velLo, iv.velLo);
                 pRegion->velHi = Math.Min(pv.velHi, iv.velHi);
                 //
                 var smpl      = mPdta.SHDR[iv.sampleId];
                 var waveBegin = smpl.start + iv.waveBegin;
                 pRegion->waveInfo.waveOfs = (uint)(mSdta.pData.ToInt64() - mSf2Ptr.ToInt64() + waveBegin * 2);
                 //
                 pRegion->waveInfo.loopEnable = iv.loopEnable;
                 if (pRegion->waveInfo.loopEnable)
                 {
                     pRegion->waveInfo.loopBegin  = smpl.loopstart - waveBegin;
                     pRegion->waveInfo.loopLength = smpl.loopend - smpl.loopstart;
                 }
                 else
                 {
                     var waveEnd = smpl.end + iv.waveEnd;
                     pRegion->waveInfo.loopBegin  = 0;
                     pRegion->waveInfo.loopLength = waveEnd - waveBegin;
                 }
                 //
                 if (0 <= iv.rootKey)
                 {
                     pRegion->waveInfo.unityNote = (byte)iv.rootKey;
                 }
                 else if (0 <= pv.rootKey)
                 {
                     pRegion->waveInfo.unityNote = (byte)pv.rootKey;
                 }
                 else
                 {
                     pRegion->waveInfo.unityNote = smpl.originalKey;
                 }
                 //
                 pRegion->waveInfo.gain  = pv.gain * iv.gain / 32768.0;
                 pRegion->waveInfo.delta = iv.fineTune * iv.coarseTune * smpl.sampleRate / Sender.SampleRate;
                 pRegion->env            = iv.env;
             }
         }
     }
 }
Beispiel #5
0
 private static extern void midi_CreateChannels(INST_LIST *list, IntPtr ppSmpl, NOTE **ppNote, IntPtr ppCh, int samplerCount);