Beispiel #1
0
            private LinkedList <float[]> generateAudioSamples()
            {
                MyMMLSequencer       seq = station.acgState.sequencer;
                MyMixer              mix = station.acgState.mixer;
                List <MySynthesizer> sss = station.acgState.synthesizers;

                if ((seq == null) || (mix == null) || (sss == null))
                {
                    return(null);
                }
                mix.Reset();
                for (int j = 0; j < sss.Count; j++)
                {
                    seq.SetSynthesizer(j, sss[j], toneSet, toneMap, 0xffffffffU);
                }
                seq.KeyShift    = clip.Key;
                seq.VolumeScale = clip.Volume;
                seq.TempoScale  = clip.Tempo;
                seq.Play(mml, 0.0f, false);

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

                float[] work      = new float[workSize * AudioClipGeneratorState.numChannels];
                bool    zeroCross = false;

                for (;;)
                {
                    if (station.disabled)
                    {
                        return(null);
                    }
                    if (seq.Playing)
                    {
                        mix.Update();
                    }
                    Array.Clear(work, 0, work.Length);
                    int numSamples = mix.Output(work, AudioClipGeneratorState.numChannels, workSize);
                    if (numSamples == 0)
                    {
                        if (!zeroCross)
                        {
                            mix.Update();
                            continue;
                        }
                        break;
                    }
                    {
                        float[] block = new float[numSamples * AudioClipGeneratorState.numChannels];
                        Array.Copy(work, block, numSamples * AudioClipGeneratorState.numChannels);
                        temp.AddLast(block);
                        float v0 = work[(numSamples - 1) * AudioClipGeneratorState.numChannels + 0];
                        float v1 = work[(numSamples - 1) * AudioClipGeneratorState.numChannels + 1];
                        zeroCross = (v0 == 0.0f) && (v1 == 0.0f);
                    }
                }
                return(temp);
            }
    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);
    }