public MyMMLSequenceUnit(List <MySpace.Synthesizer.MySynthesizer> Synthesizers, List <object> ToneSet, Dictionary <int, int> ToneMap, MyMMLSequence Sequence, string Error) { synthesizers = Synthesizers; toneSet = ToneSet; toneMap = ToneMap; sequence = Sequence; error = Error; }
public string ParseMMLText(string text, out MyMMLSequence mml) { mml = new MySpace.Synthesizer.MMLSequencer.MyMMLSequence(text); if (mml.ErrorLine != 0) { return("Error line " + mml.ErrorLine + ":" + mml.ErrorPosition + " " + mml.ErrorString); } return(null); }
public void Play(MyMMLSequence mml, List <object> toneSet, Dictionary <int, int> toneMap, float fadeInTime, AppDataEventFunc appDataEventFunc, PlayingEventFunc playingEventFunc) { if (Sequencer != null) { Sequencer.PlayingEvent = playingEventFunc; Sequencer.AppDataEvent = appDataEventFunc; Sequencer.SetSynthesizer(0, Synthesizer, toneSet, toneMap, 0xffffffffU); Sequencer.KeyShift = 0; Sequencer.VolumeShift = 0.0f; Sequencer.TempoShift = 0.0f; Sequencer.Play(mml, fadeInTime, false); } }
public string CreateDefaultToneMap(MyMMLSequence mml, out List <object> toneSet, out Dictionary <int, int> toneMap) { toneSet = new List <object>(); toneMap = new Dictionary <int, int>(); if ((mml == null) || (Synthesizer == null)) { return("Failed: CreateDefaultToneMap()"); } for (var i = 0; i < mml.ToneData.Count; i++) { object tone = Synthesizer.CreateToneObject(mml.ToneData[i]); //tone = new MySpace.Synthesizer.PM8.ToneParam(); // dummy tone if (tone != null) { toneMap.Add(i, toneSet.Count); toneSet.Add(tone); } else { return("Failed: CreateDefaultToneMap(): toneData[" + mml.ToneName[i] + "] :" + mml.ToneData[i]); } } return(null); }
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); }
public System.Collections.IEnumerator Prepare() { string lastError = null; mml = null; { Task task = Task.Run(() => { mml = new MyMMLSequence(mmlText); }); while (!task.IsCompleted) { yield return(null); } //task.Dispose(); } if (mml == null) { // task aborted yield break; } if (mml.ErrorLine != 0) { lastError = "Failed: parsing mml <" + mml.ErrorLine.ToString() + ":" + mml.ErrorPosition.ToString() + "> : " + mml.ErrorString; clip.Unit = new MyMMLSequenceUnit(null, null, null, null, lastError); yield break; } toneSet = new List <object>(); toneMap = new Dictionary <int, int>(); Dictionary <string, float[]> resource = new Dictionary <string, float[]>(); for (var i = 0; i < mml.ToneData.Count; i++) { object tone = null; for (int j = 0; j < station.synthesizers.Count; j++) { if ((mml.ToneMask[i] & (1 << j)) != 0) { tone = station.synthesizers[j].CreateToneObject(mml.ToneData[i]); if (tone == null) { lastError = "Failed: CreateToneObject(): toneData[" + mml.ToneName[i] + "] :" + mml.ToneData[i]; clip.Unit = new MyMMLSequenceUnit(null, null, null, null, lastError); yield break; } } } if (tone != null) { if (tone is MySpace.Synthesizer.SS8.ToneParam) { MySpace.Synthesizer.SS8.ToneParam ssTone = tone as MySpace.Synthesizer.SS8.ToneParam; float[] samples; if (!resource.TryGetValue(ssTone.ResourceName, out samples)) { AudioClip ac; if (bundle != null) { AssetBundleRequest request; request = bundle.LoadAssetAsync(ssTone.ResourceName, typeof(AudioClip)); yield return(request); ac = request.asset as AudioClip; } else { ac = Resources.Load <AudioClip>(ssTone.ResourceName); } if (ac == null) { lastError = "Failed: Load(): toneData[" + mml.ToneName[i] + "] :" + mml.ToneData[i]; clip.Unit = new MyMMLSequenceUnit(null, null, null, null, lastError); yield break; } while (ac.loadState == AudioDataLoadState.Loading) { yield return(null); } samples = new float[ac.samples * ac.channels]; ac.GetData(samples, 0); if (ac.channels != 1) { float[] mix = new float[ac.samples]; for (int k = 0; k < ac.samples; k++) { float s = 0.0f; for (int l = 0; l < ac.channels; l++) { s += samples[k * ac.channels + l]; } mix[k] = s; } samples = mix; } resource.Add(ssTone.ResourceName, samples); } ssTone.SetSamples(samples); } toneMap.Add(i, toneSet.Count); toneSet.Add(tone); } } clip.Unit = new MyMMLSequenceUnit(station.synthesizers, toneSet, toneMap, mml, null); if (dontGenerate) { yield break; } if (clip.GenerateAudioClip) { station.jobListB.AddLast(generate()); } yield break; }