void OnEnable()
    {
        Mixer              = new MyMixer((UInt32)AudioSettings.outputSampleRate, false);
        Synthesizer        = new MySynthesizerPM8(Mixer);
        Sequencer          = new MyMMLSequencer(Mixer.TickFrequency);
        Mixer.TickCallback = () => { Sequencer.Tick(); };

        //UnityEngine.Debug.Log("sampleRate=" + AudioSettings.outputSampleRate + " numVoices=" + Synthesizer.MaxNumVoices);
        int len;
        int num;

        AudioSettings.GetDSPBufferSize(out len, out num);
        //UnityEngine.Debug.Log("len=" + len);
        //UnityEngine.Debug.Log("num=" + num);
    }
    public AudioClip CreateAudioClip(string name, MyMMLSequence mml, List <object> toneSet, Dictionary <int, int> toneMap)
    {
        const int      frequency   = 44100;
        const int      numChannels = 2;
        MyMixer        mix         = new MyMixer(frequency, true);
        MySynthesizer  ss0         = new MySynthesizerPM8(mix);
        MyMMLSequencer seq         = new MyMMLSequencer(mix.TickFrequency);

        mix.TickCallback = () => seq.Tick();

        seq.SetSynthesizer(0, ss0, toneSet, toneMap, 0xffffffffU);
        seq.Play(mml, 0.0f, false);

        int totalSamples              = 0;
        LinkedList <float[]> temp     = new LinkedList <float[]>();
        const int            workSize = 4096;

        float[] work  = new float[workSize * numChannels];
        bool    first = true;

        for (;;)
        {
            Array.Clear(work, 0, work.Length);
            if (seq.Playing)
            {
                mix.Update();
            }
            int numSamples = mix.Output(work, numChannels, workSize);
            if (numSamples == 0)
            {
                break;
            }
            if (first)
            {
                // skip leading zeros.
                for (var i = 0; i < numSamples; i++)
                {
                    if ((work[i * 2 + 0] != 0.0f) || (work[i * 2 + 1] != 0.0f))
                    {
                        first       = false;
                        numSamples -= i;
                        float[] block = new float[numSamples * numChannels];
                        Array.Copy(work, i * 2, block, 0, numSamples * numChannels);
                        temp.AddLast(block);
                        break;
                    }
                }
            }
            else
            {
                float[] block = new float[numSamples * numChannels];
                Array.Copy(work, block, numSamples * numChannels);
                temp.AddLast(block);
            }
            totalSamples += numSamples;
        }
        AudioClip clip = AudioClip.Create(name, totalSamples, numChannels, frequency, false);
        int       pos  = 0;

        foreach (var block in temp)
        {
            clip.SetData(block, pos);
            pos += block.Length / numChannels;
        }
        ss0.Terminate();
        mix.Terminate();
        return(clip);
    }