### Real-Time Analysis Workflow Setup and Playback Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Illustrates the setup process for real-time audio analysis, including creating analyzers and starting playback. ```csharp // 1. Create component var component = new SoundPlayer(engine, format, provider); // 2. Create analyzers var spectrum = new SpectrumAnalyzer(engine, format); var levels = new LevelMeterAnalyzer(engine, format); // 3. Add to component component.AddAnalyzer(spectrum); component.AddAnalyzer(levels); // 4. Start playback device.ConnectComponent(component); device.Start(); ``` -------------------------------- ### Example: Connecting Components to Playback Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Demonstrates initializing a playback device and connecting sound components to it before starting playback. ```csharp var playbackDevice = engine.InitializePlaybackDevice(null, AudioFormat.Dvd); playbackDevice.ConnectComponent(soundPlayer); playbackDevice.ConnectComponent(synth); playbackDevice.Start(); ``` -------------------------------- ### Complete SoundFlow Configuration Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/configuration.md This snippet shows a comprehensive setup for audio device configuration, security settings (encryption and signature), watermark and fingerprinting, metadata reading, and file rendering. It covers initialization of WASAPI for audio, generation of cryptographic keys, and setting various quality and accuracy parameters for processing. ```csharp // Audio device setup var wasapi = new SfWasapiConfig { Usage = WasapiUsage.Music, ShareMode = ShareMode.Shared }; var device = engine.InitializePlaybackDevice( null, AudioFormat.DvdHq, wasapi ); // Secure project setup var encryptKey = new byte[32]; using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create()) rng.GetBytes(encryptKey); var encConfig = new EncryptionConfiguration { EncryptionKey = encryptKey }; using var sigKey = ECDsa.Create(ECCurve.NamedCurves.nistP256); var sigConfig = new SignatureConfiguration { PrivateKey = sigKey, PublicKey = sigKey, HashAlgorithm = HashAlgorithmName.SHA256 }; var watermarkConfig = new WatermarkConfiguration { Method = WatermarkMethod.DSSS, StrengthLevel = 7 }; var fingerprintConfig = new FingerprintConfiguration { HashBandCount = 32, ConfidenceThreshold = 0.85f }; // Metadata reading var metadataOptions = new ReadOptions { ReadTags = true, ReadAlbumArt = true, DurationAccuracy = DurationAccuracy.Accurate }; var provider = new StreamDataProvider( engine, stream, metadataOptions ); // Rendering var renderOptions = new RenderOptions { Quality = RenderQuality.HighQuality, TargetSampleRate = 48000, BufferSize = 8192 }; await composition.Renderer.RenderToFileAsync( "output.wav", "wav", renderOptions ); ``` -------------------------------- ### MidiRecorder Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Demonstrates how to use the MidiRecorder to start recording, stop, and then iterate through the captured MIDI events. ```csharp var recorder = new MidiRecorder(); recorder.Start(); // MIDI input arrives... recorder.Stop(); var events = recorder.RecordedEvents; foreach (var evt in events) { Console.WriteLine($"{evt.Time}: {evt.Message}"); } ``` -------------------------------- ### Creating a Custom Instrument Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/synthesis.md Example demonstrating the creation of a custom instrument using VoiceDefinitions and VoiceMappings, suitable for layering sounds and controlling instrument behavior. ```csharp // Create voice definition for low notes with sampler var lowVoiceDef = new VoiceDefinition { SamplerSource = lowSampler, FilterCutoff = 5000f }; // Create voice definition for high notes with oscillator var highVoiceDef = new VoiceDefinition { OscillatorWaveform = OscillatorGenerator.WaveformType.Sawtooth, OscillatorFrequency = 440f, FilterCutoff = 8000f }; // Create mappings var mappings = new List { new() { NoteRangeStart = 36, NoteRangeEnd = 60, VelocityRangeStart = 0, VelocityRangeEnd = 127, Definition = lowVoiceDef }, new() { NoteRangeStart = 61, NoteRangeEnd = 127, VelocityRangeStart = 0, VelocityRangeEnd = 127, Definition = highVoiceDef } }; // Create instrument var instrument = new Instrument(mappings, lowVoiceDef); // Use in synthesizer synth.InstrumentBank.SetInstrument(0, instrument); ``` -------------------------------- ### RawDataProvider Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Shows how to create a RawDataProvider with a buffer of audio samples and then use it to initialize a SoundPlayer. ```csharp float[] audioBuffer = new float[44100 * 10]; // 10 seconds at 44100Hz // ... fill buffer with data ... var provider = new RawDataProvider(audioBuffer, 44100, SampleFormat.F32); var player = new SoundPlayer(engine, format, provider); ``` -------------------------------- ### MicrophoneDataProvider Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Demonstrates setting up a microphone data provider and using it with a SoundPlayer for real-time audio playback. ```csharp var captureDevice = engine.InitializeCaptureDevice(null, AudioFormat.DvdHq); var micProvider = new MicrophoneDataProvider(captureDevice); var player = new SoundPlayer(engine, AudioFormat.DvdHq, micProvider); player.Play(); // Real-time microphone input to speakers (with modifiers/effects) ``` -------------------------------- ### CompositionRecorder Example: Recording MIDI Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Illustrates starting and stopping MIDI recording on a track, then accessing the recorded segments and note count. ```csharp var midiTrack = comp.Editor.CreateMidiTrack("Recording"); comp.Recorder.StartRecording(midiTrack, startTime: 0f); // ... MIDI input arrives ... comp.Recorder.StopRecording(); var segment = midiTrack.MidiSegments[0]; Console.WriteLine($"Recorded {segment.Notes.Count} notes"); ``` -------------------------------- ### QueueDataProvider Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Demonstrates initializing QueueDataProvider, playing audio, and enqueuing samples from a network buffer. ```csharp var provider = new QueueDataProvider(44100, 2, SampleFormat.F32); var player = new SoundPlayer(engine, format, provider); player.Play(); // In a network receiving loop byte[] networkBuffer = new byte[4096]; int read = await socket.ReceiveAsync(networkBuffer); float[] samples = ConvertToFloat(networkBuffer); provider.Enqueue(samples); ``` -------------------------------- ### Start and Monitor Audio Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Initializes a playback device, connects a player component, starts audio output, and then enters a loop to check if the device is active. ```csharp var device = engine.InitializePlaybackDevice(null, AudioFormat.Dvd); device.ConnectComponent(player); device.Start(); // Audio now playing // Check if running while (device.IsActive) { // Device is processing audio } ``` -------------------------------- ### ADSRGenerator Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/synthesis.md Example demonstrating how to instantiate and configure an ADSRGenerator to control note dynamics. ```csharp var adsr = new ADSRGenerator { AttackTime = 0.1f, DecayTime = 0.2f, SustainLevel = 0.7f, ReleaseTime = 0.5f }; voiceDefinition.EnvelopeGenerator = adsr; ``` -------------------------------- ### MidiDataProvider Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Demonstrates creating a MIDI sequence with MidiNote objects and initializing MidiDataProvider for playback. ```csharp var synth = new Synthesizer(engine, format); var midiNotes = new[] { new MidiNote(60, 100, 0, 44100), // C4, velocity 100, start 0, length 44100 samples new MidiNote(64, 100, 44100, 44100), // E4 }; var midiProvider = new MidiDataProvider(synth, midiNotes, 44100); var player = new SoundPlayer(engine, format, midiProvider); player.Play(); ``` -------------------------------- ### NetworkDataProvider Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Shows how to initialize and play audio from a network stream using NetworkDataProvider. ```csharp var provider = new NetworkDataProvider(engine, "https://example.com/stream.mp3"); var player = new SoundPlayer(engine, format, provider); player.Play(); ``` -------------------------------- ### Install SoundFlow.Codecs.FFMpeg via .NET CLI Source: https://github.com/lsxprime/soundflow/blob/master/Codecs/SoundFlow.Codecs.FFMpeg/README.md Install the FFmpeg codec extension package using the .NET CLI. ```bash dotnet add package SoundFlow.Codecs.FFMpeg ``` -------------------------------- ### Example: Handling Audio Available Event Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Shows how to initialize a capture device and subscribe to the AudioAvailable event to process incoming audio samples. ```csharp var captureDevice = engine.InitializeCaptureDevice(null, AudioFormat.DvdHq); captureDevice.AudioAvailable += (s, samples) => { Console.WriteLine($"Received {samples.Length} samples"); }; captureDevice.Start(); ``` -------------------------------- ### StreamDataProvider Examples Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Demonstrates creating StreamDataProvider instances from a local file, a network stream, and with an explicitly defined audio format. ```csharp // From file using var fileStream = File.OpenRead("audio.mp3"); var provider = new StreamDataProvider(engine, fileStream); // From network stream using var httpStream = await client.GetStreamAsync("https://example.com/audio.mp3"); var networkProvider = new StreamDataProvider(engine, httpStream); // With explicit format var format = new AudioFormat { SampleRate = 48000, Channels = 2, Format = SampleFormat.F32 }; var customProvider = new StreamDataProvider(engine, format, fileStream); ``` -------------------------------- ### Install SoundFlow.Codecs.FFMpeg via NuGet Package Manager Source: https://github.com/lsxprime/soundflow/blob/master/Codecs/SoundFlow.Codecs.FFMpeg/README.md Install the FFmpeg codec extension package using the NuGet Package Manager console. ```bash Install-Package SoundFlow.Codecs.FFMpeg ``` -------------------------------- ### Example: Real-time Reverb on FullDuplexDevice Input Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Demonstrates initializing a full-duplex device and applying real-time reverb to the microphone input. ```csharp var duplex = engine.InitializeFullDuplexDevice(null, null, AudioFormat.DvdHq); // Apply real-time reverb to microphone input var reverbMixer = new Mixer(engine, AudioFormat.DvdHq); var reverb = new ReverbModifier(engine, AudioFormat.DvdHq); reverbMixer.AddModifier(reverb); duplex.CaptureDevice.AudioAvailable += (s, samples) => { // Process microphone with reverb }; duplex.Start(); ``` -------------------------------- ### ArpeggiatorModifier Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Demonstrates how to instantiate and configure an ArpeggiatorModifier, setting its mode and speed before adding it to a route. ```csharp var arp = new ArpeggiatorModifier(); arp.Mode = ArpeggiatorModifier.ArpeggioMode.UpDown; arp.Speed = 2.0f; // Two octaves per beat route.AddModifier(arp); ``` -------------------------------- ### IMidiMappable Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Demonstrates checking if a component implements IMidiMappable and creating a MidiMapping for it. ```csharp if (component is IMidiMappable mappable) { // Component can be MIDI-controlled var mapping = new MidiMapping(note: 60, target: mappable, parameter: "Volume"); } ``` -------------------------------- ### Configure and Use SpectrumAnalyzer Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Example of creating, configuring, and accessing frequency bins from a SpectrumAnalyzer. Demonstrates setting resolution, window type, and smoothing. ```csharp var spectrum = new SpectrumAnalyzer(engine, format); spectrum.BinCount = 4096; // Higher resolution spectrum.WindowType = WindowFunction.Hann; spectrum.SmoothingFactor = 0.7f; component.AddAnalyzer(spectrum); // Later: read frequency bins for (int i = 0; i < spectrum.FrequencyBins.Length; i++) { float magnitude = spectrum.FrequencyBins[i]; float frequency = i * (format.SampleRate / 2f / spectrum.FrequencyBins.Length); Console.WriteLine($"{frequency}Hz: {magnitude:F3}"); } ``` -------------------------------- ### Example: Signing and Verifying Audio Files Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/security.md Demonstrates generating ECDSA keys, configuring signature parameters, signing an audio file, and then verifying the signature. Ensure the stream position is reset before verification. ```csharp // Generate signing keys using var privateKey = ECDsa.Create(ECCurve.NamedCurves.nistP256); var publicKey = privateKey; var sigConfig = new SignatureConfiguration { PrivateKey = privateKey, PublicKey = publicKey, HashAlgorithm = HashAlgorithmName.SHA256 }; // Sign audio using var audioStream = File.OpenRead("audio.wav"); var signResult = await FileAuthenticator.SignStreamAsync(audioStream, sigConfig); if (signResult.IsSuccess) { string signature = signResult.Value; File.WriteAllText("audio.sig", signature); // Later: verify audioStream.Position = 0; var verifyResult = await FileAuthenticator.VerifyStreamAsync(audioStream, signature, sigConfig); if (verifyResult.IsSuccess && verifyResult.Value) Console.WriteLine("Signature valid!"); } ``` -------------------------------- ### Create and Use SpectrumVisualizer Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Example of initializing a SpectrumVisualizer and using its Bands property to drive UI elements. It demonstrates setting the number of bands and frequency range. ```csharp var visualizer = new SpectrumVisualizer( bandCount: 32, minFrequency: 20f, maxFrequency: 20000f ); var spectrum = new SpectrumAnalyzer(engine, format); component.AddAnalyzer(spectrum); // Use Bands property for UI display for (int i = 0; i < visualizer.Bands.Length; i++) { int barHeight = (int)(visualizer.Bands[i] * 100); DrawBar(i, barHeight); } ``` -------------------------------- ### WaveformVisualizer Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Shows how to use WaveformVisualizer to plot waveform data for the left channel. ```csharp var waveform = new WaveformVisualizer(); // In rendering for (int i = 0; i < waveform.LeftChannel.Length; i++) { float x = (float)i / waveform.SampleCount; float y = waveform.LeftChannel[i]; DrawPoint(x, y); } ``` -------------------------------- ### CompositionEditor Example: Creating Tracks and Segments Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Demonstrates how to create audio tracks, add audio segments with specified providers and timing, and add automation points for volume control. ```csharp // Create tracks var drumsTrack = comp.Editor.CreateAudioTrack("Drums"); var bassTrack = comp.Editor.CreateAudioTrack("Bass"); // Add segments var drumSegment = comp.Editor.AddAudioSegment( drumsTrack, drumProvider, startTime: 0f, duration: 8f ); var bassSegment = comp.Editor.AddAudioSegment( bassTrack, bassProvider, startTime: 2f, duration: 6f ); // Automate volume var volPoint = comp.Editor.AddAutomationPoint(bassSegment, time: 4f, value: 0.5f); ``` -------------------------------- ### MidiMessage Creation Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Shows how to create a 'Note On' MIDI message with specific channel, note, and velocity values. ```csharp // Create a Note On message var noteOn = new MidiMessage { Channel = 0, Command = MidiCommand.NoteOn, Data1 = 60, // Middle C Data2 = 100 // Velocity }; inputDevice.SendMessage(noteOn); ``` -------------------------------- ### Basic MIDI I/O (MIDI Thru) with PortMidi Source: https://github.com/lsxprime/soundflow/blob/master/Midi/SoundFlow.Midi.PortMidi/README.md Demonstrates how to initialize the SoundFlow engine with the PortMidi backend, list available MIDI devices, and create a basic MIDI thru route between an input and an output device. Ensure PortMidi is correctly installed and MIDI devices are connected. ```csharp using SoundFlow.Abstracts; using SoundFlow.Backends.MiniAudio; using SoundFlow.Midi.PortMidi; // Import the extension namespace using SoundFlow.Midi.Routing; // 1. Initialize an audio engine (PortMidi can coexist with any audio backend). using var engine = new MiniAudioEngine(); // 2. Enable the PortMidi backend. This returns the backend instance for configuration. var midiBackend = engine.UsePortMidi(); // 3. Refresh and list available MIDI devices. engine.UpdateMidiDevicesInfo(); Console.WriteLine("--- MIDI Inputs ---"); foreach (var input in engine.MidiInputDevices) { Console.WriteLine($"ID: {input.Id}, Name: {input.Name}"); } Console.WriteLine("\n--- MIDI Outputs ---"); foreach (var output in engine.MidiOutputDevices) { Console.WriteLine($"ID: {output.Id}, Name: {output.Name}"); } // 4. Select the first available input and output devices. var firstInput = engine.MidiInputDevices.FirstOrDefault(); var firstOutput = engine.MidiOutputDevices.FirstOrDefault(); if (firstInput.Name != null && firstOutput.Name != null) { Console.WriteLine($"\nCreating a route from '{firstInput.Name}' to '{firstOutput.Name}'."); Console.WriteLine("Play some notes on your MIDI keyboard. They should be sent to the output device."); // 5. Create a route using the MidiManager. // The MidiManager automatically handles device initialization. MidiRoute route = engine.MidiManager.CreateRoute(firstInput, firstOutput); // Add a modifier to the route (e.g., transpose up one octave). // route.AddProcessor(new TransposeModifier(12)); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); // 6. Clean up the route. engine.MidiManager.RemoveRoute(route); } else { Console.WriteLine("\nCould not find MIDI input and/or output devices to create a route."); } // The engine's Dispose() method will automatically clean up the backend. ``` -------------------------------- ### LevelMeterVisualizer Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Demonstrates how to instantiate and use LevelMeterVisualizer to draw level bars and display clipping warnings. ```csharp var levelVisualizer = new LevelMeterVisualizer(); // In rendering code for (int ch = 0; ch < levelVisualizer.ChannelMeters.Length; ch++) { DrawLevelBar(ch, levelVisualizer.ChannelMeters[ch]); } DrawMasterMeter(levelVisualizer.MasterMeter); if (levelVisualizer.IsClipping) ShowClippingWarning(); ``` -------------------------------- ### CompositionRenderer Example: Playback and File Rendering Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Shows how to control real-time playback of a composition and asynchronously render it to a WAV file with specified quality and sample rate. ```csharp // Real-time playback comp.Renderer.Play(); Console.WriteLine($"Time: {comp.Renderer.CurrentTime:F2}s"); // Render to file var renderOptions = new RenderOptions { Quality = RenderQuality.HighQuality, SampleRate = 48000 }; var result = await comp.Renderer.RenderToFileAsync( "output.wav", "wav", renderOptions ); if (result.IsSuccess) Console.WriteLine("Render complete!"); ``` -------------------------------- ### Add SoundFlow NuGet Package Source: https://github.com/lsxprime/soundflow/blob/master/README.md Install the core SoundFlow library using the .NET CLI. This is the first step to begin using SoundFlow. ```bash dotnet add package SoundFlow ``` -------------------------------- ### MIDI Clock Synchronization Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Illustrates generating MIDI clock ticks based on audio frame rendering to synchronize with external devices. ```csharp engine.AudioFramesRendered += (s, args) => { // Generate MIDI clock tick for every 6 MIDI clock ticks per quarter note if (args.RenderedFrames % ticksPerQuarterNote == 0) { SendMidiClock(); } }; ``` -------------------------------- ### Synthesize MIDI with SoundFont Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Illustrates setting up a synthesizer with a SoundFont bank for instrument sounds and routing MIDI input to the synthesizer. Requires MIDI input setup and a mixer component. ```csharp var synth = new Synthesizer(engine, AudioFormat.DvdHq); var bank = SoundFontBank.LoadFromFile("piano.sf2", engine); synth.InstrumentBank = bank; var midiInput = engine.MidiManager.AvailableInputs[0]; var route = engine.MidiManager.CreateRoute(midiInput, synth); mixer.AddComponent(synth); device.Start(); ``` -------------------------------- ### Example: Encrypting and Decrypting Audio Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/security.md Demonstrates generating a random encryption key, configuring encryption, encrypting an audio file, and subsequently decrypting it. Ensure to use a 32-byte key for AES-256. ```csharp // Generate random key var key = new byte[32]; using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create()) { rng.GetBytes(key); } var config = new EncryptionConfiguration { EncryptionKey = key }; using var inputStream = File.OpenRead("audio.wav"); var provider = new StreamDataProvider(engine, inputStream); using var outputStream = File.Create("audio.encrypted"); var signature = await AudioEncryptor.EncryptAsync(provider, outputStream, config); // Later: decrypt using var encryptedStream = File.OpenRead("audio.encrypted"); var decrypted = await AudioEncryptor.DecryptAsync(encryptedStream, key); if (decrypted.IsSuccess) { var decryptedProvider = decrypted.Value; } ``` -------------------------------- ### AssetDataProvider Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Shows how to load audio data from an embedded resource stream into a byte array and use it with AssetDataProvider. ```csharp // Embedded resource var assembly = typeof(MyClass).Assembly; using var resourceStream = assembly.GetManifestResourceStream("MyApp.audio.wav"); var buffer = new byte[resourceStream.Length]; resourceStream.Read(buffer, 0, buffer.Length); var provider = new AssetDataProvider(engine, buffer); var player = new SoundPlayer(engine, format, provider); ``` -------------------------------- ### Monitor Audio Levels with LevelMeterAnalyzer Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Example of creating a LevelMeterAnalyzer, adding it to a component, and reading its level properties in an update loop. Shows how to check for clipping and reset peak values. ```csharp var levelMeter = new LevelMeterAnalyzer(engine, format); component.AddAnalyzer(levelMeter); // In update loop Console.WriteLine($"RMS: {levelMeter.RmsLevel:F2}"); Console.WriteLine($"Peak: {levelMeter.PeakLevel:F2}"); if (levelMeter.HitClipping) Console.WriteLine("Clipping detected!"); levelMeter.ResetPeaks(); ``` -------------------------------- ### HarmonizerModifier Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Shows how to create and configure a HarmonizerModifier, setting the desired harmony intervals and volume before applying it. ```csharp var harmonizer = new HarmonizerModifier(); harmonizer.Intervals = new[] { 0, 7, 12 }; // Root, dominant, octave harmonizer.Volume = 0.7f; route.AddModifier(harmonizer); ``` -------------------------------- ### Audio Graph Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Visual representation of how SoundFlow components can be connected to form an audio processing graph. ```text [SoundPlayer] → [Mixer] → [Reverb] → [Device Master Mixer] → [Speaker] [SoundPlayer] ↗ ↘ [Recorder] [Mixer] ``` -------------------------------- ### Starting a Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Begins audio I/O for a device. For playback devices, this initiates audio generation by the master mixer's connected components. ```APIDOC ### Starting a Device ```csharp public abstract void Start(); ``` Begins audio I/O. For playback devices, the master mixer's connected components will begin generating audio. **Example:** ```csharp var device = engine.InitializePlaybackDevice(null, AudioFormat.Dvd); device.ConnectComponent(player); device.Start(); // Audio now playing // Check if running while (device.IsActive) { // Device is processing audio } ``` ``` -------------------------------- ### Start and Stop Recording Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Initiates and finalizes audio recording. Ensure a capture device and file path are provided. ```csharp public PlaybackState State { get; } public void Start(); public void Stop(); ``` ```csharp var recorder = new Recorder(captureDevice, "recording.wav"); recorder.Start(); // ... recording happens ... recorder.Stop(); // Finalizes file with headers ``` -------------------------------- ### SoundFlow Logging Examples Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/errors.md Utilize the SoundFlow logging utility for different levels of messages: Information, Warning, and Error. ```csharp using SoundFlow.Utils; Log.Information("Audio engine initialized"); Log.Warning("Codec factory failed: " + ex.Message); Log.Error("Critical error: " + ex.Message); ``` -------------------------------- ### Audio Segment Settings Example: Configuring Fades Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Demonstrates how to set fade-in and fade-out types and durations for an audio segment's settings. ```csharp segment.Settings.FadeInType = FadeCurveType.SmoothStep; segment.Settings.FadeInDuration = 1.0f; segment.Settings.FadeOutType = FadeCurveType.ExponentialOut; segment.Settings.FadeOutDuration = 2.0f; ``` -------------------------------- ### Get and Display Playback Devices Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Retrieves all available playback devices and prints their names and default status to the console. It then finds and initializes the default playback device. ```csharp var devices = engine.PlaybackDevices; foreach (var device in devices) { Console.WriteLine($"{device.Name} (Default: {device.IsDefault})"); } var defaultDevice = devices.First(d => d.IsDefault); var playback = engine.InitializePlaybackDevice(defaultDevice, AudioFormat.Dvd); ``` -------------------------------- ### Add SoundFlow.Midi.PortMidi NuGet Package Source: https://github.com/lsxprime/soundflow/blob/master/README.md Install the PortMidi backend extension for SoundFlow to enable MIDI hardware I/O. This package allows interaction with physical MIDI devices across different operating systems. ```bash dotnet add package SoundFlow.Midi.PortMidi ``` -------------------------------- ### PositionChangedEventArgs Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Example of subscribing to the PositionChanged event and logging the new position. ```csharp provider.PositionChanged += (s, args) => { Console.WriteLine($"Position: {args.NewPosition} samples"); }; ``` -------------------------------- ### Listen to Device Events Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Subscribes to engine events for device start and audio frames rendered, logging relevant information such as the device's sample rate or the number of frames rendered. ```csharp engine.DeviceStarted += (s, args) => { Console.WriteLine($"Device started: {args.Device.Format.SampleRate}Hz"); }; engine.AudioFramesRendered += (s, args) => { Console.WriteLine($"Rendered {args.RenderedFrames} frames at {args.DeviceTime}"); }; ``` -------------------------------- ### Update Audio and MIDI Device Information Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-engine.md Call these methods to refresh the lists of available audio and MIDI devices from the underlying system backend. The example shows how to update audio devices and find the default playback device. ```csharp public abstract void UpdateAudioDevicesInfo(); public virtual void UpdateMidiDevicesInfo(); ``` ```csharp engine.UpdateAudioDevicesInfo(); var defaultPlayback = engine.PlaybackDevices.FirstOrDefault(d => d.IsDefault); ``` -------------------------------- ### Composition Initialization and Service Access Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Demonstrates how to create a new Composition instance and access its editing services to create audio and MIDI tracks. Also shows how to add master effects and analyzers. ```csharp var comp = new Composition(engine, AudioFormat.DvdHq) { Name = "My Song" }; // Access services var audioTrack = comp.Editor.CreateAudioTrack("Drums"); var midiTrack = comp.Editor.CreateMidiTrack("Piano"); // Add effects to master comp.Modifiers.Add(new ReverbModifier(engine, format)); comp.Analyzers.Add(new SpectrumAnalyzer(engine, format)); ``` -------------------------------- ### Add LAME Dependency Source: https://github.com/lsxprime/soundflow/blob/master/Native/ffmpeg-codec/CMakeLists.txt Configures the LAME library as an external project. It specifies the URL, installation prefix, build-in-source option, and commands for configuration, build, and installation. ```cmake ExternalProject_Add(lame_dependency URL ${LAME_URL} PREFIX ${CMAKE_BINARY_DIR}/lame INSTALL_DIR ${LAME_INSTALL_DIR} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${BASH_EXECUTABLE} /configure --prefix=${LAME_INSTALL_DIR} ${LAME_COMMON_FLAGS} BUILD_COMMAND ${MAKE_EXECUTABLE} -j${CMAKE_BUILD_PARALLEL_LEVEL} INSTALL_COMMAND ${MAKE_EXECUTABLE} install LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 LOG_INSTALL 1 ) ``` -------------------------------- ### Add FFmpeg Dependency Source: https://github.com/lsxprime/soundflow/blob/master/Native/ffmpeg-codec/CMakeLists.txt Configures the FFmpeg library as an external project, depending on the LAME dependency. It specifies the URL, installation prefix, and commands for configuration, build, and installation. ```cmake ExternalProject_Add(ffmpeg_dependency DEPENDS lame_dependency URL ${FFMPEG_URL} PREFIX ${CMAKE_BINARY_DIR}/ffmpeg INSTALL_DIR ${FFMPEG_INSTALL_DIR} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${BASH_EXECUTABLE} /configure --prefix=${FFMPEG_INSTALL_DIR} ${FFMPEG_COMMON_FLAGS} BUILD_COMMAND ${MAKE_EXECUTABLE} -j${CMAKE_BUILD_PARALLEL_LEVEL} INSTALL_COMMAND ${MAKE_EXECUTABLE} install LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 LOG_INSTALL 1 ) ``` -------------------------------- ### Synthesizer Initialization and MIDI Routing Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/synthesis.md Demonstrates how to create a Synthesizer instance, set its maximum voices, add it to the mixer, and connect MIDI input to the synthesizer. ```csharp var synth = new Synthesizer(engine, AudioFormat.DvdHq); synth.MaxVoices = 128; // Support up to 128 simultaneous notes mixer.AddComponent(synth); // Connect MIDI to synth var route = engine.MidiManager.CreateRoute(midiInput, synth); ``` -------------------------------- ### Install WebRTC APM Extension via NuGet Package Manager Source: https://github.com/lsxprime/soundflow/blob/master/Extensions/SoundFlow.Extensions.WebRtc.Apm/README.md Use this command in the NuGet Package Manager Console to install the SoundFlow WebRTC APM extension. ```bash Install-Package SoundFlow.Extensions.WebRtc.Apm ``` -------------------------------- ### Recording Control Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Control the recording process, including starting and stopping. ```APIDOC ## Recording Control ### Description Provides methods to start and stop audio recording. ### Methods - `Start()`: Begins the recording process. - `Stop()`: Stops the recording process and finalizes the output file. ### Properties - `State` (PlaybackState): Gets the current playback state of the recorder. ``` -------------------------------- ### Add Analyzers to Component Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/visualization.md Example of adding SpectrumAnalyzer and LevelMeterAnalyzer instances to a component. ```csharp component.AddAnalyzer(spectrumAnalyzer); component.AddAnalyzer(levelAnalyzer); ``` -------------------------------- ### TransposeModifier Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Demonstrates creating a TransposeModifier to transpose MIDI notes up by one octave. ```csharp var transpose = new TransposeModifier { Semitones = 12 }; // Up one octave route.AddModifier(transpose); ``` -------------------------------- ### Play Audio File Workflow Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Initializes the audio engine, loads an MP3 file, and plays it back through the default audio device. ```csharp var engine = new MiniAudioEngine(); engine.UpdateAudioDevicesInfo(); var device = engine.InitializePlaybackDevice(null, AudioFormat.Dvd); using var stream = File.OpenRead("audio.mp3"); var provider = new StreamDataProvider(engine, stream); var player = new SoundPlayer(engine, AudioFormat.Dvd, provider); device.ConnectComponent(player); device.Start(); player.Play(); // Wait for playback while (player.State == PlaybackState.Playing) await Task.Delay(100); device.Stop(); engine.Dispose(); ``` -------------------------------- ### MidiRecorder Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Records incoming MIDI messages. Allows starting, stopping, and accessing recorded events. ```APIDOC ## MIDI Recorder ### Description The `MidiRecorder` class records incoming MIDI messages. It provides methods to start and stop recording, and exposes a read-only list of the recorded MIDI events. ### Class Definition ```csharp public class MidiRecorder : IDisposable { public PlaybackState State { get; } public void Start(); public void Stop(); public IReadOnlyList RecordedEvents { get; } } ``` ### Example Usage ```csharp var recorder = new MidiRecorder(); recorder.Start(); // MIDI input arrives... recorder.Stop(); var events = recorder.RecordedEvents; foreach (var evt in events) { Console.WriteLine($"{evt.Time}: {evt.Message}"); } ``` ``` -------------------------------- ### ChannelFilterModifier Usage Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/midi.md Shows how to instantiate and configure a ChannelFilterModifier to only allow MIDI messages from specific channels. ```csharp var filter = new ChannelFilterModifier(); filter.AllowedChannels = new[] { 1, 2, 3 }; // Only these channels pass through route.AddModifier(filter); ``` -------------------------------- ### Initialize Loopback Recording Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Initializes a loopback device to record system audio output and sets up a recorder to save the audio to a WAV file. ```csharp var loopback = engine.InitializeLoopbackDevice(AudioFormat.DvdHq); var recorder = new Recorder(loopback, "system_audio.wav"); recorder.Start(); ``` -------------------------------- ### Route Live MIDI Input to Synthesizer Source: https://github.com/lsxprime/soundflow/blob/master/Midi/SoundFlow.Midi.PortMidi/README.md Demonstrates routing a live MIDI keyboard input to an internal Synthesizer for audio output. Requires initializing the audio engine with PortMidi support, a playback device, and setting up MIDI routes. ```csharp using SoundFlow.Backends.MiniAudio; using SoundFlow.Midi.PortMidi; using SoundFlow.Structs; using SoundFlow.Synthesis; using SoundFlow.Synthesis.Banks; // 1. Initialize engines. PortMidi is required for MIDI input. using var engine = new MiniAudioEngine(); engine.UsePortMidi(); engine.UpdateMidiDevicesInfo(); var midiInput = engine.MidiInputDevices.FirstOrDefault(); if (midiInput.Name == null) { Console.WriteLine("No MIDI input device found."); return; } // 2. Initialize an audio playback device. using var audioDevice = engine.InitializePlaybackDevice(null, AudioFormat.DvdHq); // 3. Create an instrument bank and a synthesizer. var instrumentBank = new SoundFontBank("path/to/your/soundfont.sf2", audioDevice.Format); // or just use BasicInstrumentBank(audioDevice.Format); var synthesizer = new Synthesizer(engine, audioDevice.Format, instrumentBank); // 4. Create the audio path: Add the Synthesizer to the device's master mixer. audioDevice.MasterMixer.AddComponent(synthesizer); // 5. Create the MIDI control path: Route the physical input device to the synthesizer instance. MidiRoute route = engine.MidiManager.CreateRoute(midiInput, synthesizer); // 6. Start the audio device to begin processing sound. audioDevice.Start(); Console.WriteLine($"Ready to play! MIDI input from '{midiInput.Name}' is routed to the internal synthesizer."); Console.WriteLine("Press any key to exit."); Console.ReadKey(); // 7. Clean up. engine.MidiManager.RemoveRoute(route); audioDevice.Stop(); ``` -------------------------------- ### SoundPlayer Loop Points Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Configure specific start and end points for looping within the audio playback. ```APIDOC ## SoundPlayer Loop Points ### Description Configure specific start and end points for looping within the audio playback. ### Methods - **SetLoopPoints(float startTime, float? endTime = -1f)**: Sets loop points using time in seconds. `endTime` of -1f indicates looping to the natural end. - **SetLoopPoints(int startSample, int endSample = -1)**: Sets loop points using sample counts. `endSample` of -1 indicates looping to the natural end. - **SetLoopPoints(TimeSpan startTime, TimeSpan? endTime = null)**: Sets loop points using TimeSpan objects. ### Properties (Read-only) - **LoopStartSamples** (`int`): The start loop point in samples. - **LoopEndSamples** (`int`): The end loop point in samples. - **LoopStartSeconds** (`float`): The start loop point in seconds. - **LoopEndSeconds** (`float`): The end loop point in seconds. ``` -------------------------------- ### Stop and Restart Audio Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md Demonstrates stopping an audio device to suspend playback and then starting it again to resume. ```csharp device.Stop(); // Stop playback device.Start(); // Resume playback ``` -------------------------------- ### Save and Load Project Data Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/composition.md Demonstrates how to save the current project state to a byte array and file, and how to load a project from saved data. ```csharp // Save var projectData = comp.SaveProject(); File.WriteAllBytes("project.soundflow", projectData); // Load var loadedData = File.ReadAllBytes("project.soundflow"); var loadedComp = Composition.LoadProject(engine, loadedData); ``` -------------------------------- ### Include FFmpeg Headers Source: https://github.com/lsxprime/soundflow/blob/master/Native/ffmpeg-codec/CMakeLists.txt Adds the FFmpeg installation include directory to the private include directories for the 'soundflow-ffmpeg' target. ```cmake target_include_directories(soundflow-ffmpeg PRIVATE ${FFMPEG_INSTALL_DIR}/include) ``` -------------------------------- ### Multi-Track Composition and Rendering Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Shows how to create a multi-track composition, add audio segments to different tracks, apply global modifiers, and render the final composition to a WAV file. ```csharp var comp = new Composition(engine, AudioFormat.DvdHq) { Name = "My Song" }; var drums = comp.Editor.CreateAudioTrack("Drums"); var bass = comp.Editor.CreateAudioTrack("Bass"); comp.Editor.AddAudioSegment(drums, drumProvider, 0, 8); comp.Editor.AddAudioSegment(bass, bassProvider, 2, 6); comp.Modifiers.Add(new ReverbModifier(engine, format)); var renderOptions = new RenderOptions { Quality = RenderQuality.HighQuality }; await comp.Renderer.RenderToFileAsync("output.wav", "wav", renderOptions); ``` -------------------------------- ### ISoundDataProvider Core Methods Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Provides the essential methods for interacting with audio data providers: reading samples and seeking to a specific position. ```csharp int ReadBytes(Span buffer); ``` ```csharp void Seek(int offset); ``` -------------------------------- ### Codec Integration: Registering and Setting Priority Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Demonstrates registering a custom codec factory and setting its priority for audio decoding. ```csharp // Register custom codec var customCodec = new CustomMP3Codec(); engine.RegisterCodecFactory(customCodec); // Set priority engine.SetCodecPriority("custom.mp3", 100); // StreamDataProvider automatically uses registered codecs var provider = new StreamDataProvider(engine, fileStream); ``` -------------------------------- ### SoundPlayer Playback Control Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Control the playback state of the SoundPlayer. You can start, pause, resume, or stop audio playback. ```APIDOC ## SoundPlayer Playback Control ### Description Control the playback state of the SoundPlayer. You can start, pause, resume, or stop audio playback. ### Methods - **Play()**: Starts or resumes playback. - **Pause()**: Pauses playback at the current position. - **Stop()**: Stops playback and resets the position to the beginning. ### Properties - **State** (`PlaybackState`): Gets the current playback state. ``` -------------------------------- ### SoundPlayer Loop Points Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Methods to set loop start and end points using seconds or sample offsets. ```csharp public int LoopStartSamples { get; } public int LoopEndSamples { get; } public float LoopStartSeconds { get; } public float LoopEndSeconds { get; } public void SetLoopPoints(float startTime, float? endTime = -1f); public void SetLoopPoints(int startSample, int endSample = -1); public void SetLoopPoints(TimeSpan startTime, TimeSpan? endTime = null); ``` ```csharp // Loop between 2 and 8 seconds player.SetLoopPoints(2f, 8f); // Loop from 10 seconds to end player.SetLoopPoints(10f, -1f); // Reset to full loop player.SetLoopPoints(0, -1); ``` -------------------------------- ### SoundPlayer Playback Properties Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/sound-components.md Properties to get and set playback time, duration, speed, volume, and looping behavior. ```csharp public float Time { get; } public float Duration { get; } public float PlaybackSpeed { get; set; } public float Volume { get; set; } public bool IsLooping { get; set; } ``` ```csharp Console.WriteLine($"Playing: {player.Time:F2} / {player.Duration:F2}"); player.PlaybackSpeed = 1.5f; // Play at 1.5x speed player.IsLooping = true; // Loop when reaching end ``` -------------------------------- ### MicrophoneDataProvider Constructor Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/data-providers.md Initializes a MicrophoneDataProvider using an AudioCaptureDevice to capture live audio. ```csharp public MicrophoneDataProvider(AudioCaptureDevice captureDevice); ``` -------------------------------- ### Real-Time Spectrum Visualization Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Shows how to create a spectrum analyzer and visualize frequency bin magnitudes in real-time for applications like audio visualizers. Requires a running loop and drawing function. ```csharp var spectrum = new SpectrumAnalyzer(engine, format); component.AddAnalyzer(spectrum); while (isRunning) { for (int i = 0; i < spectrum.FrequencyBins.Length; i++) { float magnitude = spectrum.FrequencyBins[i]; DrawBar(i, magnitude * screenHeight); } await Task.Delay(16); // 60 FPS } ``` -------------------------------- ### Initialize Playback Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-engine.md Initializes an audio playback device. Pass null for deviceInfo to use the system default. The desired audio format must be specified. An optional backend-specific configuration can be provided. ```csharp public abstract AudioPlaybackDevice InitializePlaybackDevice( DeviceInfo? deviceInfo, AudioFormat format, DeviceConfig? config = null); ``` ```csharp var format = AudioFormat.Dvd; // 48000 Hz, stereo, S16 var device = engine.InitializePlaybackDevice(null, format); device.Start(); ``` -------------------------------- ### Link FFmpeg and LAME Libraries Source: https://github.com/lsxprime/soundflow/blob/master/Native/ffmpeg-codec/CMakeLists.txt Adds the FFmpeg and LAME installation library directories to the private link directories for the 'soundflow-ffmpeg' target. ```cmake target_link_directories(soundflow-ffmpeg PRIVATE ${FFMPEG_INSTALL_DIR}/lib ${LAME_INSTALL_DIR}/lib) ``` -------------------------------- ### Switch to Default Device on Failure Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/errors.md Check if a device is inactive. If so, find the default playback device and switch to it, then start the new device. ```csharp if (!device.IsActive) { // Switch to default device var defaultDevice = engine.PlaybackDevices.FirstOrDefault(d => d.IsDefault); if (defaultDevice != null) { device = engine.SwitchDevice(device, defaultDevice); device.Start(); } } ``` -------------------------------- ### AudioDevice Abstract Class Definition Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-devices.md The base class for all audio devices, defining core properties and abstract methods for starting and stopping. ```csharp public abstract class AudioDevice : IDisposable { public DeviceInfo Info { get; } public AudioFormat Format { get; } public bool IsDisposed { get; } public bool IsActive { get; protected set; } public abstract void Start(); public abstract void Stop(); } ``` -------------------------------- ### Instrument Creation with Voice Mappings Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/synthesis.md Illustrates creating an Instrument with multiple VoiceMappings for different velocity layers and a fallback definition. This allows for dynamic sound changes based on how hard a key is pressed. ```csharp var mapping = new VoiceMapping { NoteRangeStart = 36, // C2 NoteRangeEnd = 60, // C4 VelocityRangeStart = 0, VelocityRangeEnd = 63, Definition = voiceDefinition1 }; var mapping2 = new VoiceMapping { NoteRangeStart = 36, NoteRangeEnd = 60, VelocityRangeStart = 64, VelocityRangeEnd = 127, Definition = voiceDefinition2 // Different sample for high velocity }; var instrument = new Instrument( new List { mapping, mapping2 }, fallbackDef ); ``` -------------------------------- ### Record Audio with Effects Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Demonstrates how to initialize audio capture, apply effects like reverb during recording, and save the output to a WAV file. ```csharp var engine = new MiniAudioEngine(); var captureDevice = engine.InitializeCaptureDevice(null, AudioFormat.DvdHq); var recorder = new Recorder(captureDevice, "recording.wav"); var reverb = new ReverbModifier(engine, AudioFormat.DvdHq); recorder.AddModifier(reverb); recorder.Start(); // ... user records ... recorder.Stop(); ``` -------------------------------- ### Initialize Loopback Device Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/audio-engine.md Initializes a loopback capture device for recording system audio output. This feature is available on Windows and macOS. ```APIDOC ## InitializeLoopbackDevice ### Description Initializes a loopback capture device for recording system audio output (available on Windows/macOS). ### Method `abstract AudioCaptureDevice InitializeLoopbackDevice(AudioFormat format, DeviceConfig? config = null)` ### Parameters #### Path Parameters * **format** (`AudioFormat`) - Required - Audio format for the loopback device * **config** (`DeviceConfig?`) - Optional - Optional configuration ### Returns An initialized `AudioCaptureDevice` instance. ### Throws `NotSupportedException` if the system has no playback device or doesn't support loopback recording. ### Example ```csharp var loopback = engine.InitializeLoopbackDevice(AudioFormat.DvdHq); // Records whatever the system is playing ``` ``` -------------------------------- ### Result-Based Error Handling Example Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/README.md Demonstrates how to handle potential errors using the Result type, checking for failures and accessing error messages. ```csharp var result = await AudioEncryptor.EncryptAsync(...); if (result.IsFailure) Console.WriteLine($ ``` -------------------------------- ### Audio Encryption, Signing, and Fingerprinting Workflow Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/api-reference/security.md Demonstrates a complete security workflow: encrypting and signing audio, generating its fingerprint, and later decrypting and verifying it. ```csharp // 1. Encrypt and sign audio var encryptKey = GenerateKey(); var encConfig = new EncryptionConfiguration { EncryptionKey = encryptKey }; var sigConfig = new SignatureConfiguration { /* ... */ }; using var sourceStream = File.OpenRead("original.wav"); var provider = new StreamDataProvider(engine, sourceStream); using var encrypted = File.Create("audio.encrypted"); var signature = await AudioEncryptor.EncryptAsync(provider, encrypted, encConfig, sigConfig, embedSignature: true); // 2. Generate fingerprint using var fpStream = File.OpenRead("original.wav"); var fpProvider = new StreamDataProvider(engine, fpStream); var fingerprint = await AudioIdentifier.GenerateFingerprintAsync(fpProvider, config); // 3. Later: decrypt and verify using var encryptedStream = File.OpenRead("audio.encrypted"); var decryptResult = await AudioEncryptor.DecryptAsync(encryptedStream, encryptKey); if (decryptResult.IsSuccess) { var decryptedProvider = decryptResult.Value; // Audio is decrypted and ready to use } ``` -------------------------------- ### Find Make Executable Source: https://github.com/lsxprime/soundflow/blob/master/Native/ffmpeg-codec/CMakeLists.txt Searches for the 'make' or 'gmake' executable, which is required for building FFmpeg/LAME via autotools. It provides a hint for MSYS2 installations. ```cmake find_program(MAKE_EXECUTABLE NAMES gmake make HINTS "C:/msys64/usr/bin" "/usr/bin") if(NOT MAKE_EXECUTABLE) message(FATAL_ERROR "Could not find 'make' or 'gmake'. It is required to build FFmpeg/LAME via autotools.") endif() message(STATUS "Using Make program: ${MAKE_EXECUTABLE}") ``` -------------------------------- ### Handle MIDI Backend Not Configured Error Source: https://github.com/lsxprime/soundflow/blob/master/_autodocs/errors.md Catch a NotSupportedException when accessing MIDI manager before UseMidiBackend is called and configure the backend. ```csharp try { var inputs = engine.MidiManager.AvailableInputs; // No backend configured } catch (NotSupportedException ex) { Console.WriteLine("MIDI backend not configured"); engine.UseMidiBackend(new PortMidiBackend()); } ```