public static void Main(string[] args) { using (var settings = new Settings()) { // Change this if you don't have pulseaudio or want to change to anything else. if (Environment.OSVersion.Platform == PlatformID.Unix) { settings[ConfigurationKeys.AudioDriver].StringValue = "pulseaudio"; } settings[ConfigurationKeys.SynthAudioChannels].IntValue = 2; using (var syn = new Synth(settings)) { foreach (var arg in args) { if (SoundFont.IsSoundFont(arg)) { syn.LoadSoundFont(arg, true); } } if (syn.FontCount == 0) { syn.LoadSoundFont("/usr/share/sounds/sf2/FluidR3_GM.sf2", true); } for (int i = 0; i < 16; i++) { syn.SoundFontSelect(i, 0); } var files = args.Where(SoundFont.IsMidiFile); if (files.Any()) { foreach (var arg in files) { using (var player = new Player(syn)) { using (var adriver = new AudioDriver(syn.Settings, syn)) { player.Add(arg); player.Play(); player.Join(); } } } } else { using (var adriver = new AudioDriver(syn.Settings, syn)) { syn.ProgramChange(0, 1); syn.NoteOn(0, 60, 120); Thread.Sleep(5000); syn.NoteOff(0, 60); } } } } }
public Task OpenAsync() { if (synth != null) { throw new InvalidOperationException("The MIDI output is already open."); } settings = new Settings(); if (midi_access.ConfigureSettings != null) { midi_access.ConfigureSettings(settings); } synth = new Synth(settings); synth.HandleError = midi_access.HandleNativeError; foreach (var factory in midi_access.SoundFontLoaderFactories) { synth.AddSoundFontLoader(factory(synth)); } foreach (var sf in midi_access.SoundFonts) { synth.LoadSoundFont(sf, false); } adriver = new AudioDriver(synth.Settings, synth); return(Task.FromResult(true)); }
public static void Main(string[] args) { using (var settings = new Settings()) { if (Environment.OSVersion.Platform == PlatformID.Unix) { settings [ConfigurationKeys.AudioDriver].StringValue = "alsa"; } using (var syn = new Synth(settings)) { foreach (var arg in args) { if (Synth.IsSoundFont(arg)) { syn.LoadSoundFont(arg, true); } } if (syn.FontCount == 0) { syn.LoadSoundFont("/usr/share/sounds/sf2/FluidR3_GM.sf2", true); } var files = args.Where(a => Synth.IsMidiFile(a)); if (files.Any()) { foreach (var arg in files) { using (var player = new Player(syn)) { using (var adriver = new AudioDriver(syn.Settings, syn)) { player.Add(arg); player.Play(); player.Join(); } } } } else { using (var adriver = new AudioDriver(syn.Settings, syn)) { syn.NoteOn(0, 60, 100); Thread.Sleep(5000); syn.NoteOff(0, 60); } } } } }
public void LoadUnloadSoundFont() { using (var syn = new Synth (NewAlsaSettings ())) using (var audio = new AudioDriver (syn.Settings, syn)) { syn.LoadSoundFont ("/usr/share/sounds/sf2/FluidR3_GS.sf2", false); Assert.AreEqual (1, syn.FontCount, "FontCount"); for (int i = 0; i < 16; i++) syn.SoundFontSelect (i, 1); syn.UnloadSoundFont (1, true); Assert.AreEqual (0, syn.FontCount, "FontCount"); } }
public void LoadUnloadSoundFont() { using (var syn = new Synth(NewAlsaSettings())) using (var audio = new AudioDriver(syn.Settings, syn)) { syn.LoadSoundFont("/usr/share/sounds/sf2/FluidR3_GS.sf2", false); Assert.AreEqual(1, syn.FontCount, "FontCount"); for (int i = 0; i < 16; i++) { syn.SoundFontSelect(i, 1); } syn.UnloadSoundFont(1, true); Assert.AreEqual(0, syn.FontCount, "FontCount"); } }
public int SetSoundFont2(string sfont) { try { if (sfontId != -1) { synth.UnloadSoundFont(sfontId, true); } sfontId = synth.LoadSoundFont(sfont, true); } catch { return(1); } return(0); }
public FluidsynthMidiReceiver(Context context) { #if MIDI_MANAGER access = new FluidsynthMidiAccess(); access.ConfigureSettings = (settings) => { #else var settings = new Settings(); #endif settings [ConfigurationKeys.AudioDriver].StringValue = "oboe"; //settings [ConfigurationKeys.SynthParallelRender].IntValue = 0; //settings [ConfigurationKeys.SynthThreadsafeApi].IntValue = 0; //settings [ConfigurationKeys.AudioPeriods].IntValue = 16; //settings [ConfigurationKeys.AudioPeriods].IntValue = 64; settings [ConfigurationKeys.AudioSampleFormat].StringValue = "16bits"; // float or 16bits var manager = context.GetSystemService(Context.AudioService).JavaCast <AudioManager> (); // Note that it is NOT audio sample rate but *synthesizing* sample rate. // So it is kind of wrong assumption that AudioManager.PropertyOutputSampleRate would give the best outcome... //var sr = double.Parse (manager.GetProperty (AudioManager.PropertyOutputSampleRate)); //settings [ConfigurationKeys.SynthSampleRate].DoubleValue = sr; settings [ConfigurationKeys.SynthSampleRate].DoubleValue = 11025; var fpb = double.Parse(manager.GetProperty(AudioManager.PropertyOutputFramesPerBuffer)); settings [ConfigurationKeys.AudioPeriodSize].IntValue = (int)fpb; #if MIDI_MANAGER }; SynthAndroidExtensions.GetSoundFonts(access.SoundFonts, context, predefined_temp_path); output = access.OpenOutputAsync(access.Outputs.First().Id).Result; #else syn = new Synth(settings); var sfs = new List <string> (); SynthAndroidExtensions.GetSoundFonts(sfs, context, predefined_temp_path); asset_sfloader = new AndroidNativeAssetSoundFontLoader(settings, context.Assets); syn.AddSoundFontLoader(asset_sfloader); foreach (var sf in sfs) { syn.LoadSoundFont(sf, false); } adriver = new AudioDriver(syn.Settings, syn); #endif }
/// <summary> /// Renders the currently applied settings to a MIDI file (in memory) and then sets up a player /// </summary> bool setupPlayerForPlayback() { if (drv != null) { drv.Dispose(); } if (player != null) { player.Dispose(); } if (syn != null) { syn.Dispose(); } var soundfontFile = @"Soundbanks\ExtractedSoundbank_" + (NLSTChoice + 10).ToString("X2") + ".dls"; if (!File.Exists(soundfontFile)) { MessageBox.Show("A required soundbank file is missing - Please see the Github on how to extract soundbanks from your ROM."); return(false); } var settings = new Settings(); settings[ConfigurationKeys.SynthAudioChannels].IntValue = 2; syn = new Synth(settings); syn.Gain = 0.5f; syn.LoadSoundFont(soundfontFile, true); for (int i = 0; i < 16; i++) { syn.SoundFontSelect(i, 1); } player = new Player(syn); var mid = exportMIDBytes(); player.AddMem(mid, 0, mid.Length); drv = new AudioDriver(settings, syn); return(true); }
public async Task Play() { using (var settings = new Settings()) { settings[ConfigurationKeys.AudioDriver].StringValue = "pulseaudio"; settings[ConfigurationKeys.SynthAudioChannels].IntValue = 2; settings[ConfigurationKeys.AudioRealtimePrio].IntValue = 0; settings[ConfigurationKeys.SynthVerbose].IntValue = 0; settings[ConfigurationKeys.AudioPeriodSize].IntValue = 1024; settings[ConfigurationKeys.SynthReverbActive].IntValue = ReverbEnabled ? 1 : 0; settings[ConfigurationKeys.SynthChorusActive].IntValue = ChorusEnabled ? 1 : 0; using (var syn = new Synth(settings)) { syn.LoadSoundFont("/usr/share/sounds/sf2/FluidR3_GM.sf2", true); using (var adriver = new AudioDriver(syn.Settings, syn)) { if (ReverbEnabled) { syn.SetReverb(ReverbRoomSize, ReverbDamping, ReverbWidth, ReverbLevel); } if (ChorusEnabled) { syn.SetChorus(ChorusNumVoices, ChorusLevel, ChorusSpeed, ChorusDepthMS, ChorusMod); } // Hardcoded, will be changed in the future syn.ProgramChange(1, (int)GeneralMidi.Violin); if (Midi != null) { // Meanwhile we are cheating a little bit and using the build-in FluidSynth MIDI player // In the future it would be nice to read the events from the MIDI file and play them ourselves // That way we could mix MIDI files with our own music expressions, and maybe even transform MIDI files using (var player = new Player(syn)) { player.Add(Midi); player.Play(); // Synchronous join. Thankfully this code runs in a separate thread. Would be nice to have a async version player.Join(); } } else { var sw = new System.Diagnostics.Stopwatch(); sw.Start(); // Explaining the timer process used // All note commands (NoteOn/NoteOff) are ordered by their noteCommand.Timestamp (value in milliseconds relative to the beginning // of the music). Let's imagine that two of them are, for example, one second apart. Ideally, we would want to do a // Thread.Sleep( 1000 ) and hope that the thread would unblock exactly 1000 milliseconds after. However, the system's clock // resolution varies between different Operating Systems and different physical Processors. So we could not be sure when the thread // would be woken. Instead we do a Thread.Sleep( 1000 - minResolution ), which hopefully means that our thread will awake before the note is due // Three things can happen now: // - We can be early, i.e. we still have to wait a bit, and for that we use a simple loop with a high-precision Stopwatch // - We can be on time, in which case we just play the note // - We can be late, in wich case we play the note right away and add to the drift variable how late we are // Every subsequent timestamp will have the drift variable added to it to compensate int minResolution = 30; int drift = 0; foreach (INoteCommand noteCommand in BuildCommands(Notes)) { int timestamp = noteCommand.Timestamp + drift; int elapsed = (int)sw.Elapsed.TotalMilliseconds; if (timestamp - minResolution > elapsed) { await Task.Delay(Math.Max(0, timestamp - elapsed - minResolution)); } while (timestamp > sw.Elapsed.TotalMilliseconds) { Thread.Sleep(0); } elapsed = (int)sw.Elapsed.TotalMilliseconds; noteCommand.Apply(syn); if (timestamp < elapsed) { drift += elapsed - timestamp; } } sw.Stop(); Console.WriteLine($"Total drift: {drift}ms out of {sw.Elapsed.TotalMilliseconds}ms"); } } } } }
/// <summary> /// 음악 출력 장치와 타이머를 초기화하고, 현재 음악 테마를 SFXThemeName으로 설정합니다. /// </summary> /// <param name="SFXThemeName">설정할 음악 테마 이름</param> /// <param name="noteResolution">단위 리듬</param> /// <param name="timerTickDelegates">타이머의 틱마다 추가로 실행할 메서드의 대리자 목록</param> public static void Initialize(string SFXThemeName, int noteResolution, Timer.TickDelegate[] timerTickDelegates = null) { IsReady = false; HasStart = false; //outDevice = new OutputDevice(0); settings = new Settings(); settings[ConfigurationKeys.SynthAudioChannels].IntValue = 2; syn = new Synth(settings); try { syn.LoadSoundFont("FluidR3_GM.sf2", true); } catch (FileNotFoundException e) { Console.WriteLine(e.StackTrace); return; } for (int i = 0; i < 16; i++) { syn.SoundFontSelect(i, 0); } adriver = new AudioDriver(syn.Settings, syn); /* * WaveInEvent recorder = new WaveInEvent * { * WaveFormat = new WaveFormat(44100, 2) * }; * BufferedWaveProvider sound = new BufferedWaveProvider(recorder.WaveFormat); * recorder.DataAvailable += (object sender, WaveInEventArgs e) => * { * sound.AddSamples(e.Buffer, 0, e.BytesRecorded); * }; * recorder.StartRecording(); * //sound.Read(); */ //playback = new WaveOutEvent(); //playback.Init(sound); //playback.Play(); /* * sound = new BufferedWaveProvider(new WaveFormat(44100, 2)); * buffer = new byte[44100 * 4]; * stream = new MemoryStream(); * Task.Run(() => { * soundStream = new RawSourceWaveStream(stream, new WaveFormat(44100, 2)); * reverb = new DmoEffectWaveProvider<DmoWavesReverb, DmoWavesReverb.Params>(soundStream); * outputDevice = new WasapiOut(); * * outputDevice.Init(reverb); * outputDevice.Play(); * }); */ SFXTheme.CurrentSFXTheme = SFXTheme.FindSFXTheme(SFXThemeName); //Console.WriteLine(SFXThemeName + " " + SFXTheme.CurrentSFXTheme.Name); NoteResolution = noteResolution; Accompaniment.Initialize(); tickDelegate += Tick; if (timerTickDelegates != null) { foreach (Timer.TickDelegate t in timerTickDelegates) { tickDelegate += t; } } mgmt = new PowerManagement(); mgmt.InitPowerEvents(); mgmt.OnPowerSuspend += Suspend; mgmt.OnPowerResume += Resume; syncPlayBuffer = new List <Note>(); syncTransitionBuffer = false; playPitchEventBuffer = new List <int>(); accompanimentTickNumber = new Dictionary <int, int>(); accompanimentPlayNumber = new Dictionary <int, int>(); accompanimentTickNumber.Add(7, 0); accompanimentTickNumber.Add(8, 0); accompanimentPlayNumber.Add(7, 0); accompanimentPlayNumber.Add(8, 0); IsReady = true; /* * Task.Run(() => * { * var capture = new WasapiLoopbackCapture(); * var effectProvider = new DmoEffectWaveProvider<DmoWavesReverb, DmoWavesReverb.Params>(new WaveInProvider(capture)); * * PlayEffectorSound(capture, effectProvider); * using (var outputDevice = new WasapiOut()) * { * outputDevice.Init(effectProvider); * capture.StartRecording(); * outputDevice.Play(); * while (capture.CaptureState != NAudio.CoreAudioApi.CaptureState.Stopped) * { * Thread.Sleep(500); * if (!IsReady) capture.StopRecording(); * } * Console.WriteLine("Effector stopped"); * } * * }); */ }