XT-Audio

An open source streaming audio library focused on low latency, platform independence and API simplicity.

Contact

Mail:info@xt-audio.com
Forum:http://xt-audio.com/phpbb

Download

Binaries:All platforms
Source:XT-Audio on GitHub
Screenshot:Exclusive-mode WASAPI example

Features

Docs

Core / C++ / Java / .NET
Only the core (C) API is fully documented. Code samples are provided for all languages except C. Refer to the core documentation's main page for differences between the C API and other language APIs.

Code samples

  • Print device names to stdout.
package com.xtaudio.xt;

public class PrintSimple {

    public static void main(String[] args) {

        try (XtAudio audio = new XtAudio(null, null, null, null)) {
            for (int s = 0; s < XtAudio.getServiceCount(); s++) {
                XtService service = XtAudio.getServiceByIndex(s);
                for (int d = 0; d < service.getDeviceCount(); d++)
                    try (XtDevice device = service.openDevice(d)) {
                        System.out.println(service.getName() + ": " + device.getName());
                    }
            }
        }
    }
}
using System;

namespace Xt {

    public class PrintSimple {

        public static void Main(string[] args) {

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {
                for (int s = 0; s < XtAudio.GetServiceCount(); s++) {
                    XtService service = XtAudio.GetServiceByIndex(s);
                    for (int d = 0; d < service.GetDeviceCount(); d++)
                        using (XtDevice device = service.OpenDevice(d))
                            Console.WriteLine(service.GetName() + ": " + device.GetName());
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#include <iostream>
#include <memory>

int main(int argc, char** argv) {
  Xt::Audio audio("", nullptr, nullptr, nullptr);
  for(int s = 0; s < Xt::Audio::GetServiceCount(); s++) {
    std::unique_ptr<Xt::Service> service = Xt::Audio::GetServiceByIndex(s);
    for(int d = 0; d < service->GetDeviceCount(); d++) {
      std::unique_ptr<Xt::Device> device = service->OpenDevice(d);
      std::cout << service->GetName() << ": " << device->GetName() << "\n";
    }
  }
  return 0;
}
DirectSound: Lijningang (Realtek High Definition Audio)
DirectSound: Microfoon (Realtek High Definition Audio)
DirectSound: Luidsprekers (Realtek High Definition Audio)
DirectSound: Realtek Digital Output (Realtek High Definition Audio)
WASAPI: Microfoon (Realtek High Definition Audio) (Shared)
WASAPI: Lijningang (Realtek High Definition Audio) (Shared)
WASAPI: Realtek Digital Output (Realtek High Definition Audio) (Loopback)
WASAPI: Luidsprekers (Realtek High Definition Audio) (Loopback)
WASAPI: Microfoon (Realtek High Definition Audio) (Exclusive)
WASAPI: Lijningang (Realtek High Definition Audio) (Exclusive)
WASAPI: Realtek Digital Output (Realtek High Definition Audio) (Shared)
WASAPI: Luidsprekers (Realtek High Definition Audio) (Shared)
WASAPI: Realtek Digital Output (Realtek High Definition Audio) (Exclusive)
WASAPI: Luidsprekers (Realtek High Definition Audio) (Exclusive)
ASIO: ASIO4ALL v2
ASIO: E-MU ASIO
  • Query audio setups, service capabilities and default devices.
  • Initialize with application name, logger and fatal error handler.
  • Query device mix, maximum channels and (non)interleaved access support.
package com.xtaudio.xt;

public class PrintDetailed {

    static void onFatal() {
        System.out.println("Fatal error.");
    }

    static void onTrace(XtLevel level, String message) {
        if (level != XtLevel.INFO)
            System.out.println("-- " + level + ": " + message);
    }

    public static void main(String[] args) {

        try (XtAudio audio = new XtAudio("Sample", null, PrintDetailed::onTrace, PrintDetailed::onFatal)) {

            System.out.println("Win32: " + XtAudio.isWin32());
            System.out.println("Version: " + XtAudio.getVersion());
            System.out.println("Pro Audio: " + XtAudio.getServiceBySetup(XtSetup.PRO_AUDIO).getName());
            System.out.println("System Audio: " + XtAudio.getServiceBySetup(XtSetup.SYSTEM_AUDIO).getName());
            System.out.println("Consumer Audio: " + XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO).getName());

            for (int s = 0; s < XtAudio.getServiceCount(); s++) {

                XtService service = XtAudio.getServiceByIndex(s);
                System.out.println("Service " + service.getName() + ":");
                System.out.println("  System: " + service.getSystem());
                System.out.println("  Device count: " + service.getDeviceCount());
                System.out.println("  Capabilities: " + XtPrint.capabilitiesToString(service.getCapabilities()));

                try (XtDevice defaultInput = service.openDefaultDevice(false)) {
                    System.out.println("  Default input: " + defaultInput);
                }
                try (XtDevice defaultOutput = service.openDefaultDevice(true)) {
                    System.out.println("  Default output: " + defaultOutput);
                }

                for (int d = 0; d < service.getDeviceCount(); d++)
                    try (XtDevice device = service.openDevice(d)) {

                        System.out.println("  Device " + device.getName() + ":");
                        System.out.println("    System: " + device.getSystem());
                        System.out.println("    Current mix: " + device.getMix());
                        System.out.println("    Input channels: " + device.getChannelCount(false));
                        System.out.println("    Output channels: " + device.getChannelCount(true));
                        System.out.println("    Interleaved access: " + device.supportsAccess(true));
                        System.out.println("    Non-interleaved access: " + device.supportsAccess(false));
                    }
            }
        } catch (XtException e) {

            System.out.printf("Error: system %s, fault %s, cause %s, text %s, message: %s.\n",
                    XtException.getSystem(e.getError()),
                    XtException.getFault(e.getError()),
                    XtException.getCause(e.getError()),
                    XtException.getText(e.getError()),
                    e.toString());
        }
    }
}
using System;

namespace Xt {

    public class PrintDetailed {

        static void OnFatal() {
            Console.WriteLine("Fatal error.");
        }

        static void OnTrace(XtLevel level, String message) {
            if (level != XtLevel.Info)
                Console.WriteLine("-- " + level + ": " + message);
        }

        public static void Main(String[] args) {

            using (XtAudio audio = new XtAudio("Sample", IntPtr.Zero, OnTrace, OnFatal)) {

                try {
                    Console.WriteLine("Win32: " + XtAudio.IsWin32());
                    Console.WriteLine("Version: " + XtAudio.GetVersion());
                    Console.WriteLine("Pro Audio: " + XtAudio.GetServiceBySetup(XtSetup.ProAudio).GetName());
                    Console.WriteLine("System Audio: " + XtAudio.GetServiceBySetup(XtSetup.SystemAudio).GetName());
                    Console.WriteLine("Consumer Audio: " + XtAudio.GetServiceBySetup(XtSetup.ConsumerAudio).GetName());

                    for (int s = 0; s < XtAudio.GetServiceCount(); s++) {

                        XtService service = XtAudio.GetServiceByIndex(s);
                        Console.WriteLine("Service " + service.GetName() + ":");
                        Console.WriteLine("  System: " + service.GetSystem());
                        Console.WriteLine("  Device count: " + service.GetDeviceCount());
                        Console.WriteLine("  Capabilities: " + XtPrint.CapabilitiesToString(service.GetCapabilities()));

                        using (XtDevice defaultInput = service.OpenDefaultDevice(false))
                            Console.WriteLine("  Default input: " + defaultInput);

                        using (XtDevice defaultOutput = service.OpenDefaultDevice(true))
                            Console.WriteLine("  Default output: " + defaultOutput);


                        for (int d = 0; d < service.GetDeviceCount(); d++)
                            using (XtDevice device = service.OpenDevice(d)) {

                                Console.WriteLine("  Device " + device.GetName() + ":");
                                Console.WriteLine("    System: " + device.GetSystem());
                                Console.WriteLine("    Current mix: " + device.GetMix());
                                Console.WriteLine("    Input channels: " + device.GetChannelCount(false));
                                Console.WriteLine("    Output channels: " + device.GetChannelCount(true));
                                Console.WriteLine("    Interleaved access: " + device.SupportsAccess(true));
                                Console.WriteLine("    Non-interleaved access: " + device.SupportsAccess(false));
                            }
                    }
                } catch (XtException e) {

                    Console.WriteLine("Error: system %s, fault %s, cause %s, text %s, message: %s.\n",
                            XtException.GetSystem(e.GetError()),
                            XtException.GetFault(e.GetError()),
                            XtException.GetCause(e.GetError()),
                            XtException.GetText(e.GetError()),
                            e.ToString());
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#include <iostream>
#include <memory>

static void OnFatal() {
  std::cout << "Fatal error.";
}

static void OnTrace(Xt::Level level, const std::string& message) {
  if(level != Xt::Level::Info)
    std::cout << "-- " << level << ": " << message << "\n";
}

int main(int argc, char** argv) {

  Xt::Audio audio("Sample", nullptr, OnTrace, OnFatal);

  try {
    std::cout << "Win32: " << Xt::Audio::IsWin32() << "\n";
    std::cout << "Version: " << Xt::Audio::GetVersion() << "\n";
    std::cout << "Pro Audio: " << Xt::Audio::GetServiceBySetup(Xt::Setup::ProAudio)->GetName() << "\n";
    std::cout << "System Audio: " << Xt::Audio::GetServiceBySetup(Xt::Setup::SystemAudio)->GetName() << "\n";
    std::cout << "Consumer Audio: " << Xt::Audio::GetServiceBySetup(Xt::Setup::ConsumerAudio)->GetName() << "\n";

    for(int s = 0; s < Xt::Audio::GetServiceCount(); s++) {

      std::unique_ptr<Xt::Service> service = Xt::Audio::GetServiceByIndex(s);
      std::cout << "Service " << service->GetName() + ":\n";
      std::cout << "  System: " << service->GetSystem() << "\n";
      std::cout << "  Device count: " << service->GetDeviceCount() << "\n";
      std::cout << "  Capabilities: " << Xt::Print::CapabilitiesToString(service->GetCapabilities()) << "\n";

      std::unique_ptr<Xt::Device> defaultInput = service->OpenDefaultDevice(false);
      if(defaultInput)
        std::cout << "  Default input: " << *defaultInput << "\n";

      std::unique_ptr<Xt::Device> defaultOutput = service->OpenDefaultDevice(true);
      if(defaultOutput)
        std::cout << "  Default output: " << *defaultOutput << "\n";

      for(int d = 0; d < service->GetDeviceCount(); d++) {
        std::unique_ptr<Xt::Device> device = service->OpenDevice(d);
        std::unique_ptr<Xt::Mix> mix = device->GetMix();
        std::cout << "  Device " << device->GetName() + ":" << "\n";
        std::cout << "    System: " << device->GetSystem() << "\n";
        if(mix)
          std::cout << "    Current mix: " << *mix << "\n";
        std::cout << "    Input channels: " << device->GetChannelCount(false) << "\n";
        std::cout << "    Output channels: " << device->GetChannelCount(true) << "\n";
        std::cout << "    Interleaved access: " << device->SupportsAccess(true) << "\n";
        std::cout << "    Non-interleaved access: " << device->SupportsAccess(false) << "\n";
      }
    }
  }
  catch(const Xt::Exception& e) {
    std::cout << "Error: "
      << "system " << Xt::Exception::GetSystem(e.GetError()) << ", "
      << "fault " << Xt::Exception::GetFault(e.GetError()) << ", "
      << "cause " << Xt::Exception::GetCause(e.GetError()) << ", "
      << "text " << Xt::Exception::GetText(e.GetError()) << ", "
      << "message " << e << ".\n";
  }
  return 0;
}
Win32: 1
Version: 1.0.2
Pro Audio: ASIO
System Audio: WASAPI
Consumer Audio: DirectSound
Service DirectSound:
  System: DSound
  Device count: 4
  Capabilities: [ChannelMask]
  Default input: Primair stuurprogramma voor opnemen van geluid
  Default output: Primair geluidsstuurprogramma
  Device Lijningang (Realtek High Definition Audio):
    System: DSound
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Microfoon (Realtek High Definition Audio):
    System: DSound
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Luidsprekers (Realtek High Definition Audio):
    System: DSound
    Current mix: [48000 Float32]
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
  Device Realtek Digital Output (Realtek High Definition Audio):
    System: DSound
    Current mix: [48000 Float32]
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
Service WASAPI:
  System: Wasapi
  Device count: 10
  Capabilities: [Time | Latency | ChannelMask | XRunDetection]
  Default input: Lijningang (Realtek High Definition Audio) (Shared)
  Default output: Luidsprekers (Realtek High Definition Audio) (Shared)
  Device Microfoon (Realtek High Definition Audio) (Shared):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Lijningang (Realtek High Definition Audio) (Shared):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Realtek Digital Output (Realtek High Definition Audio) (Loopback):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Luidsprekers (Realtek High Definition Audio) (Loopback):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Microfoon (Realtek High Definition Audio) (Exclusive):
    System: Wasapi
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Lijningang (Realtek High Definition Audio) (Exclusive):
    System: Wasapi
    Input channels: 18
    Output channels: 0
    Interleaved access: 1
    Non-interleaved access: 0
  Device Realtek Digital Output (Realtek High Definition Audio) (Shared):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
  Device Luidsprekers (Realtek High Definition Audio) (Shared):
    System: Wasapi
    Current mix: [48000 Float32]
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
  Device Realtek Digital Output (Realtek High Definition Audio) (Exclusive):
    System: Wasapi
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
  Device Luidsprekers (Realtek High Definition Audio) (Exclusive):
    System: Wasapi
    Input channels: 0
    Output channels: 18
    Interleaved access: 1
    Non-interleaved access: 0
Service ASIO:
  System: Asio
  Device count: 2
  Capabilities: [Time | Latency | FullDuplex | ChannelMask]
  Default input: ASIO4ALL v2
  Default output: ASIO4ALL v2
  Device ASIO4ALL v2:
    System: Asio
    Current mix: [44100 Int32]
    Input channels: 2
    Output channels: 8
    Interleaved access: 0
    Non-interleaved access: 1
  Device E-MU ASIO:
    System: Asio
    Current mix: [44100 Int32]
    Input channels: 32
    Output channels: 32
    Interleaved access: 0
    Non-interleaved access: 1
  • Render sinewave to the default output device.
package com.xtaudio.xt;

public class RenderSimple {

    static double phase = 0.0;
    static final double FREQUENCY = 660.0;
    static final XtFormat FORMAT = new XtFormat(new XtMix(44100, XtSample.FLOAT32), 0, 0, 1, 0);

    static void render(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) {

        for (int f = 0; f < frames; f++) {
            phase += FREQUENCY / FORMAT.mix.rate;
            if (phase >= 1.0)
                phase = -1.0;
            ((float[]) output)[f] = (float) Math.sin(phase * Math.PI);
        }
    }

    public static void main(String[] args) throws Exception {

        try (XtAudio audio = new XtAudio(null, null, null, null)) {
            XtService service = XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO);
            try (XtDevice device = service.openDefaultDevice(true)) {
                if (device != null && device.supportsFormat(FORMAT)) {

                    XtBuffer buffer = device.getBuffer(FORMAT);
                    try (XtStream stream = device.openStream(FORMAT, true, false,
                            buffer.current, RenderSimple::render, null, null)) {
                        stream.start();
                        Thread.sleep(1000);
                        stream.stop();
                    }
                }
            }
        }
    }
}
using System;
using System.Threading;

namespace Xt {

    public class RenderSimple {

        static double phase = 0.0;
        const double Frequency = 660.0;
        static readonly XtFormat Format = new XtFormat(new XtMix(44100, XtSample.Float32), 0, 0, 1, 0);

        static void Render(XtStream stream, object input, object output, int frames,
                double time, ulong position, bool timeValid, ulong error, object user) {

            for (int f = 0; f < frames; f++) {
                phase += Frequency / Format.mix.rate;
                if (phase >= 1.0)
                    phase = -1.0;
                ((float[])output)[f] = (float)Math.Sin(phase * Math.PI);
            }
        }

        public static void Main(string[] args) {

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {
                XtService service = XtAudio.GetServiceBySetup(XtSetup.ConsumerAudio);
                using (XtDevice device = service.OpenDefaultDevice(true)) {
                    if (device != null && device.SupportsFormat(Format)) {

                        XtBuffer buffer = device.GetBuffer(Format);
                        using (XtStream stream = device.OpenStream(Format, true, false,
                                buffer.current, Render, null, null)) {
                            stream.Start();
                            Thread.Sleep(1000);
                            stream.Stop();
                        }
                    }
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <climits>
#include <cmath>
#include <iostream>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

static double phase = 0.0;
static const double Frequency = 660.0;
static const Xt::Format Format(Xt::Mix(44100, Xt::Sample::Float32), 0, 0, 1, 0);

static void Render(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  for(int f = 0; f < frames; f++) {
    phase += Frequency / Format.mix.rate;
    if(phase >= 1.0)
      phase = -1.0;
    ((float*)output)[f] = (float)sin(phase * M_PI);
  }
}

int main(int argc, char** argv) {

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr< Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::ConsumerAudio);
  std::unique_ptr<Xt::Device> device = service->OpenDefaultDevice(true);
  if(device  && device->SupportsFormat(Format)) {

    Xt::Buffer buffer = device->GetBuffer(Format);
    std::unique_ptr<Xt::Stream> stream = device->OpenStream(Format, true, buffer.current, Render, nullptr, nullptr);
    stream->Start();
#if _WIN32
    Sleep(1000);
#else
    usleep(1000 * 1000);
#endif
    stream->Stop();
  }
  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service DirectSound, output 1...
-- Info: Opened default device Primair geluidsstuurprogramma: service DirectSound, output 1.
-- Info: Opening stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (0)], interleaved 1...
-- Info: Opened stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (0)], interleaved 1.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Closing device Primair geluidsstuurprogramma...
-- Info: Closed device Primair geluidsstuurprogramma.
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).
  • Record from the default input device to a raw audio file.
package com.xtaudio.xt;

import java.io.FileOutputStream;

public class CaptureSimple {

    static final int SAMPLE_SIZE = 3;
    static final XtFormat FORMAT = new XtFormat(new XtMix(44100, XtSample.INT24), 1, 0, 0, 0);

    static void capture(XtStream stream, Object input, Object output, int frames, double time,
            long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0)
            // Don't do this.
            ((FileOutputStream) user).write((byte[]) input, 0, frames * SAMPLE_SIZE);
    }

    public static void main(String[] args) throws Exception {

        try (XtAudio audio = new XtAudio(null, null, null, null)) {
            XtService service = XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO);
            try (XtDevice device = service.openDefaultDevice(false)) {
                if (device != null && device.supportsFormat(FORMAT)) {

                    XtBuffer buffer = device.getBuffer(FORMAT);
                    try (FileOutputStream recording = new FileOutputStream("xt-audio.raw");
                            XtStream stream = device.openStream(FORMAT, true, false,
                                    buffer.current, CaptureSimple::capture, null, recording)) {
                        stream.start();
                        Thread.sleep(1000);
                        stream.stop();
                    }
                }
            }
        }
    }
}
using System;
using System.IO;
using System.Threading;

namespace Xt {

    public class CaptureSimple {

        const int SampleSize = 3;
        static readonly XtFormat Format = new XtFormat(new XtMix(44100, XtSample.Int24), 1, 0, 0, 0);

        static void Capture(XtStream stream, object input, object output, int frames,
            double time, ulong position, bool timeValid, ulong error, object user) {

            if (frames > 0)
                // Don't do this.
                ((FileStream)user).Write((byte[])input, 0, frames * SampleSize);
        }

        public static void Main(string[] args) {

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {
                XtService service = XtAudio.GetServiceBySetup(XtSetup.ConsumerAudio);
                using (XtDevice device = service.OpenDefaultDevice(false))
                    if (device != null && device.SupportsFormat(Format)) {

                        XtBuffer buffer = device.GetBuffer(Format);
                        using (FileStream recording = new FileStream(
                            "xt-audio.raw", FileMode.Create, FileAccess.Write))
                        using (XtStream stream = device.OpenStream(Format, true, false,
                            buffer.current, Capture, null, recording)) {
                            stream.Start();
                            Thread.Sleep(1000);
                            stream.Stop();
                        }
                    }
            }
        }
    }
}
#include <xt-cpp.hpp>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <fstream>
#include <iostream>
#include <cmath>

static const int SampleSize = 3;
static const Xt::Format Format(Xt::Mix(44100, Xt::Sample::Int24), 1, 0, 0, 0);

static void Capture(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  if(frames > 0)
    // Don't do this.
    static_cast<std::ofstream*>(user)->write(static_cast<const char*>(input), frames * SampleSize);
}

int main(int argc, char** argv) {

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr< Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::ConsumerAudio);
  std::unique_ptr<Xt::Device> device = service->OpenDefaultDevice(false);
  if(device  && device->SupportsFormat(Format)) {

    Xt::Buffer buffer = device->GetBuffer(Format);
    std::ofstream recording("xt-audio.raw", std::ios::out | std::ios::binary);
    std::unique_ptr<Xt::Stream> stream = device->OpenStream(Format, true, buffer.current, Capture, nullptr, &recording);
    stream->Start();
#if _WIN32
    Sleep(1000);
#else
    usleep(1000 * 1000);
#endif
    stream->Stop();
  }
  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service DirectSound, output 0...
-- Info: Opened default device Primair stuurprogramma voor opnemen van geluid: service DirectSound, output 0.
-- Info: Opening stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 1 (0) 0 (0)], interleaved 1...
-- Info: Opened stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 1 (0) 0 (0)], interleaved 1.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Closing device Primair stuurprogramma voor opnemen van geluid...
-- Info: Closed device Primair stuurprogramma voor opnemen van geluid.
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).
  • Get notified on stream under/overflow.
  • Playback using interleaved and non-interleaved buffers.
  • Use channel masks to route a channel to a specific speaker position.
  • (Java and .NET): use raw streams to operate directly on native buffers.
package com.xtaudio.xt;

import com.sun.jna.Pointer;

public class RenderAdvanced {

    static double phase = 0.0;
    static final double FREQUENCY = 660.0;

    static void readLine() {
        System.out.println("Press any key to continue...");
        System.console().readLine();
    }

    static float nextSine(double sampleRate) {
        phase += FREQUENCY / sampleRate;
        if (phase >= 1.0)
            phase = -1.0;
        return (float) Math.sin(phase * Math.PI);
    }

    static void xRun(int index, Object user) {
        // Don't do this.
        System.out.println("XRun on device " + index + ", user = " + user + ".");
    }
    
    static void renderInterleaved(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        XtFormat format = stream.getFormat();
        for (int f = 0; f < frames; f++) {
            float sine = nextSine(format.mix.rate);
            for (int c = 0; c < format.outputs; c++)
                ((float[]) output)[f * format.outputs + c] = sine;
        }
    }

    static void renderInterleavedRaw(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        XtFormat format = stream.getFormat();
        int sampleSize = XtAudio.getSampleAttributes(format.mix.sample).size;
        for (int f = 0; f < frames; f++) {
            float sine = nextSine(format.mix.rate);
            for (int c = 0; c < format.outputs; c++)
                ((Pointer) output).setFloat((f * format.outputs + c) * sampleSize, sine);
        }
    }

    static void renderNonInterleaved(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        XtFormat format = stream.getFormat();
        for (int f = 0; f < frames; f++) {
            float sine = nextSine(format.mix.rate);
            for (int c = 0; c < format.outputs; c++)
                ((float[][]) output)[c][f] = sine;
        }
    }

    static void renderNonInterleavedRaw(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        XtFormat format = stream.getFormat();
        int sampleSize = XtAudio.getSampleAttributes(format.mix.sample).size;
        for (int f = 0; f < frames; f++) {
            float sine = nextSine(format.mix.rate);
            for (int c = 0; c < format.outputs; c++)
                ((Pointer) output).getPointer(c * Pointer.SIZE).setFloat(f * sampleSize, sine);
        }
    }

    public static void main(String[] args) throws Exception {

        try (XtAudio audio = new XtAudio(null, null, null, null)) {

            XtService service = XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO);
            XtFormat format = new XtFormat(new XtMix(44100, XtSample.FLOAT32), 0, 0, 2, 0);
            try (XtDevice device = service.openDefaultDevice(true)) {

                if (device == null) {
                    System.out.println("No default device found.");
                    return;
                }

                if (!device.supportsFormat(format)) {
                    System.out.println("Format not supported.");
                    return;
                }

                XtBuffer buffer = device.getBuffer(format);

                try (XtStream stream = device.openStream(format, true, false, buffer.current,
                        RenderAdvanced::renderInterleaved, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering interleaved...");
                    readLine();
                    stream.stop();
                }

                try (XtStream stream = device.openStream(format, true, true, buffer.current,
                        RenderAdvanced::renderInterleavedRaw, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering interleaved, raw buffers...");
                    readLine();
                    stream.stop();
                }

                try (XtStream stream = device.openStream(format, false, false, buffer.current,
                        RenderAdvanced::renderNonInterleaved, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering non-interleaved...");
                    readLine();
                    stream.stop();
                }

                try (XtStream stream = device.openStream(format, false, true, buffer.current,
                        RenderAdvanced::renderNonInterleavedRaw, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering non-interleaved, raw buffers...");
                    readLine();
                    stream.stop();
                }

                XtFormat sendTo0 = new XtFormat(new XtMix(44100, XtSample.FLOAT32), 0, 0, 1, 1L << 0);
                try (XtStream stream = device.openStream(sendTo0, true, false, buffer.current,
                        RenderAdvanced::renderInterleaved, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering channel mask, channel 0...");
                    readLine();
                    stream.stop();
                }

                XtFormat sendTo1 = new XtFormat(new XtMix(44100, XtSample.FLOAT32), 0, 0, 1, 1L << 1);
                try (XtStream stream = device.openStream(sendTo1, true, false, buffer.current,
                        RenderAdvanced::renderInterleaved, RenderAdvanced::xRun, "user-data")) {
                    stream.start();
                    System.out.println("Rendering channel mask, channel 1...");
                    readLine();
                    stream.stop();
                }
            }
        }
    }
}
using System;

namespace Xt {

    public class RenderAdvanced {

        static double phase = 0.0;
        const double Frequency = 660.0;

        static void ReadLine() {
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }

        static float NextSine(double sampleRate) {
            phase += Frequency / sampleRate;
            if (phase >= 1.0)
                phase = -1.0;
            return (float)Math.Sin(phase * Math.PI);
        }

        static void XRun(int index, object user) {
            // Don't do this.
            Console.WriteLine("XRun on device " + index + ", user = " + user + ".");
        }

        static void RenderInterleaved(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            XtFormat format = stream.GetFormat();
            for (int f = 0; f < frames; f++) {
                float sine = NextSine(format.mix.rate);
                for (int c = 0; c < format.outputs; c++)
                    ((float[])output)[f * format.outputs + c] = sine;
            }
        }

        static unsafe void RenderInterleavedRaw(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            XtFormat format = stream.GetFormat();
            for (int f = 0; f < frames; f++) {
                float sine = NextSine(format.mix.rate);
                for (int c = 0; c < format.outputs; c++)
                    ((float*)(IntPtr)output)[f * format.outputs + c] = sine;
            }
        }

        static void RenderNonInterleaved(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            XtFormat format = stream.GetFormat();
            for (int f = 0; f < frames; f++) {
                float sine = NextSine(format.mix.rate);
                for (int c = 0; c < format.outputs; c++)
                    ((float[][])output)[c][f] = sine;
            }
        }

        static unsafe void RenderNonInterleavedRaw(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            XtFormat format = stream.GetFormat();
            for (int f = 0; f < frames; f++) {
                float sine = NextSine(format.mix.rate);
                for (int c = 0; c < format.outputs; c++)
                    ((float**)(IntPtr)output)[c][f] = sine;
            }
        }

        public static void Main(String[] args) {

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {

                XtService service = XtAudio.GetServiceBySetup(XtSetup.ConsumerAudio);
                XtFormat format = new XtFormat(new XtMix(44100, XtSample.Float32), 0, 0, 2, 0);
                using (XtDevice device = service.OpenDefaultDevice(true)) {

                    if (device == null) {
                        Console.WriteLine("No default device found.");
                        return;
                    }

                    if (!device.SupportsFormat(format)) {
                        Console.WriteLine("Format not supported.");
                        return;
                    }

                    XtBuffer buffer = device.GetBuffer(format);

                    using (XtStream stream = device.OpenStream(format, true, false,
                        buffer.current, RenderInterleaved, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering interleaved...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (XtStream stream = device.OpenStream(format, true, true,
                        buffer.current, RenderInterleavedRaw, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering interleaved, raw buffers...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (XtStream stream = device.OpenStream(format, false, false,
                        buffer.current, RenderNonInterleaved, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering non-interleaved...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (XtStream stream = device.OpenStream(format, false, true,
                        buffer.current, RenderNonInterleavedRaw, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering non-interleaved, raw buffers...");
                        ReadLine();
                        stream.Stop();
                    }

                    XtFormat sendTo0 = new XtFormat(new XtMix(44100, XtSample.Float32), 0, 0, 1, 1L << 0);
                    using (XtStream stream = device.OpenStream(sendTo0, true, false,
                        buffer.current, RenderInterleaved, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering channel mask, channel 0...");
                        ReadLine();
                        stream.Stop();
                    }

                    XtFormat sendTo1 = new XtFormat(new XtMix(44100, XtSample.Float32), 0, 0, 1, 1L << 1);
                    using (XtStream stream = device.OpenStream(sendTo1, true, false, buffer.current,
                            RenderInterleaved, XRun, "user-data")) {
                        stream.Start();
                        Console.WriteLine("Rendering channel mask, channel 1...");
                        ReadLine();
                        stream.Stop();
                    }
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <climits>
#include <iostream>
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

static double phase = 0.0;
static const double Frequency = 660.0;

static void ReadLine() {
  std::string s;
  std::cout << "Press any key to continue...\n";
  std::getline(std::cin, s);
}

static float NextSine(double sampleRate) {
  phase += Frequency / sampleRate;
  if(phase >= 1.0)
    phase = -1.0;
  return (float)sin(phase * M_PI);
}

static void XRun(int index, void* user) {
  // Don't do this.
  std::cout << "XRun on stream " << index << ", user = " << static_cast<char*>(user) << ".\n";
}

static void RenderInterleaved(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  Xt::Format format = stream.GetFormat();
  for(int f = 0; f < frames; f++) {
    float sine = NextSine(format.mix.rate);
    for(int c = 0; c < format.outputs; c++)
      ((float*)output)[f * format.outputs + c] = sine;
  }
}

static void RenderNonInterleaved(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  Xt::Format format = stream.GetFormat();
  for(int f = 0; f < frames; f++) {
    float sine = NextSine(format.mix.rate);
    for(int c = 0; c < format.outputs; c++)
      ((float**)output)[c][f] = sine;
  }
}

int main(int argc, char** argv) {

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr< Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::ConsumerAudio);
  Xt::Format format(Xt::Mix(44100, Xt::Sample::Float32), 0, 0, 2, 0);
  std::unique_ptr<Xt::Device> device = service->OpenDefaultDevice(true);

  if(!device) {
    std::cout << "No default device found.\n";
    return 0;
  }

  if(!device->SupportsFormat(format)) {
    std::cout << "Format not supported.\n";
    return 0;
  }

  std::unique_ptr<Xt::Stream> stream;
  Xt::Buffer buffer = device->GetBuffer(format);

  stream = device->OpenStream(format, true, buffer.current, RenderInterleaved, XRun, const_cast<char*>("user-data"));
  stream->Start();
  std::cout << "Rendering interleaved...\n";
  ReadLine();
  stream->Stop();

  device->OpenStream(format, false, buffer.current, RenderNonInterleaved, XRun, const_cast<char*>("user-data"));
  stream->Start();
  std::cout << "Rendering non-interleaved...\n";
  ReadLine();
  stream->Stop();

  Xt::Format sendTo0(Xt::Mix(44100, Xt::Sample::Float32), 0, 0, 1, 1ULL << 0);
  stream = device->OpenStream(sendTo0, true, buffer.current, RenderInterleaved, XRun, const_cast<char*>("user-data"));
  stream->Start();
  std::cout << "Rendering channel mask, channel 0...\n";
  ReadLine();
  stream->Stop();

  Xt::Format sendTo1(Xt::Mix(44100, Xt::Sample::Float32), 0, 0, 1, 1ULL << 1);
  stream = device->OpenStream(sendTo1, true, buffer.current, RenderInterleaved, XRun, const_cast<char*>("user-data"));
  stream->Start();
  std::cout << "Rendering channel mask, channel 1...\n";
  ReadLine();
  stream->Stop();

  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service DirectSound, output 1...
-- Info: Opened default device Primair geluidsstuurprogramma: service DirectSound, output 1.
-- Info: Opening stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 2 (0)], interleaved 1...
-- Info: Opened stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 2 (0)], interleaved 1.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Rendering interleaved...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Opening stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 2 (0)], interleaved 0...
-- Info: Opened stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 2 (0)], interleaved 0.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Rendering non-interleaved...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Opening stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (1)], interleaved 1...
-- Info: Opened stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (1)], interleaved 1.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Rendering channel mask, channel 0...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Opening stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (2)], interleaved 1...
-- Info: Opened stream: device Primair geluidsstuurprogramma, bufferSize 500.000000, format [44100 Float32 0 (0) 1 (2)], interleaved 1.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Rendering channel mask, channel 1...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Closing device Primair geluidsstuurprogramma...
-- Info: Closed device Primair geluidsstuurprogramma.
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).
  • Get notified on stream under/overflow.
  • Record using interleaved and non-interleaved buffers.
  • (Java and .NET): use raw streams to operate directly on native buffers.
package com.xtaudio.xt;

import com.sun.jna.Pointer;
import java.io.FileOutputStream;

public class CaptureAdvanced {

    static class Context {

        byte[] intermediate;
        FileOutputStream out;
    }

    static void readLine() {
        System.out.println("Press any key to continue...");
        System.console().readLine();
    }

    static int getBufferSize(XtStream stream, int frames) {
        XtFormat format = stream.getFormat();
        int sampleSize = XtAudio.getSampleAttributes(format.mix.sample).size;
        return frames * format.inputs * sampleSize;
    }
    
    static void xRun(int index, Object user) {
        // Don't do this.
        System.out.println("XRun on device " + index + ".");
    }

    static void captureInterleaved(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0)
            // Don't do this.
            ((Context) user).out.write((byte[]) input, 0, getBufferSize(stream, frames));
    }

    static void captureInterleavedRaw(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0) {
            Context ctx = (Context) user;
            ((Pointer) input).read(0, ctx.intermediate, 0, getBufferSize(stream, frames));
            // Don't do this.
            ctx.out.write(ctx.intermediate, 0, getBufferSize(stream, frames));
        }
    }

    static void captureNonInterleaved(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0) {
            Context ctx = (Context) user;
            XtFormat format = stream.getFormat();
            int channels = format.inputs;
            int sampleSize = XtAudio.getSampleAttributes(format.mix.sample).size;
            for (int f = 0; f < frames; f++)
                for (int c = 0; c < channels; c++)
                    // Don't do this.
                    ctx.out.write(((byte[][]) input)[c], f * sampleSize, sampleSize);
        }
    }

    static void captureNonInterleavedRaw(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0) {
            Context ctx = (Context) user;
            XtFormat format = stream.getFormat();
            int channels = format.inputs;
            int sampleSize = XtAudio.getSampleAttributes(format.mix.sample).size;
            for (int f = 0; f < frames; f++)
                for (int c = 0; c < channels; c++) {
                    ((Pointer) input).getPointer(c * Pointer.SIZE).read(f * sampleSize, ctx.intermediate, 0, sampleSize);
                    // Don't do this.
                    ctx.out.write(ctx.intermediate, 0, sampleSize);
                }
        }
    }

    public static void main(String[] args) throws Exception {

        try (XtAudio audio = new XtAudio(null, null, null, null)) {

            XtService service = XtAudio.getServiceBySetup(XtSetup.CONSUMER_AUDIO);
            XtFormat format = new XtFormat(new XtMix(44100, XtSample.INT24), 2, 0, 0, 0);
            try (XtDevice device = service.openDefaultDevice(false)) {

                if (device == null) {
                    System.out.println("No default device found.");
                    return;
                }

                if (!device.supportsFormat(format)) {
                    System.out.println("Format not supported.");
                    return;
                }

                Context context = new Context();
                XtBuffer buffer = device.getBuffer(format);

                try (FileOutputStream recording = new FileOutputStream("xt-audio-interleaved.raw");
                        XtStream stream = device.openStream(format, true, false, buffer.current,
                                CaptureAdvanced::captureInterleaved, CaptureAdvanced::xRun, context)) {
                    context.out = recording;
                    context.intermediate = new byte[getBufferSize(stream, stream.getFrames())];
                    stream.start();
                    System.out.println("Capturing interleaved...");
                    readLine();
                    stream.stop();
                }

                try (FileOutputStream recording = new FileOutputStream("xt-audio-interleaved-raw.raw");
                        XtStream stream = device.openStream(format, true, true, buffer.current,
                                CaptureAdvanced::captureInterleavedRaw, CaptureAdvanced::xRun, context)) {
                    context.out = recording;
                    context.intermediate = new byte[getBufferSize(stream, stream.getFrames())];
                    stream.start();
                    System.out.println("Capturing interleaved, raw buffers...");
                    readLine();
                    stream.stop();
                }

                try (FileOutputStream recording = new FileOutputStream("xt-audio-non-interleaved.raw");
                        XtStream stream = device.openStream(format, false, false, buffer.current,
                                CaptureAdvanced::captureNonInterleaved, CaptureAdvanced::xRun, context)) {
                    context.out = recording;
                    context.intermediate = new byte[getBufferSize(stream, stream.getFrames())];
                    stream.start();
                    System.out.println("Capturing non-interleaved...");
                    readLine();
                    stream.stop();
                }

                try (FileOutputStream recording = new FileOutputStream("xt-audio-non-interleaved-raw.raw");
                        XtStream stream = device.openStream(format, false, true, buffer.current,
                                CaptureAdvanced::captureNonInterleavedRaw, CaptureAdvanced::xRun, context)) {
                    context.out = recording;
                    context.intermediate = new byte[getBufferSize(stream, stream.getFrames())];
                    stream.start();
                    System.out.println("Capturing non-interleaved, raw buffers...");
                    readLine();
                    stream.stop();
                }
            }
        }
    }
}
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace Xt {

    public class CaptureAdvanced {

        class Context {

            internal byte[] intermediate;
            internal FileStream recording;
        }

        static void ReadLine() {
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }

        static int GetBufferSize(XtStream stream, int frames) {
            XtFormat format = stream.GetFormat();
            int sampleSize = XtAudio.GetSampleAttributes(format.mix.sample).size;
            return frames * format.inputs * sampleSize;
        }

        static void XRun(int index, object user) {
            // Don't do this.
            Console.WriteLine("XRun on device " + index + ".");
        }

        static void CaptureInterleaved(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            if (frames > 0)
                // Don't do this.
                ((Context)user).recording.Write((byte[])input, 0, GetBufferSize(stream, frames));
        }

        static void CaptureInterleavedRaw(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            if (frames > 0) {
                Context ctx = (Context)user;
                Marshal.Copy((IntPtr)input, ctx.intermediate, 0, GetBufferSize(stream, frames));
                // Don't do this.
                ctx.recording.Write(ctx.intermediate, 0, GetBufferSize(stream, frames));
            }
        }

        static void CaptureNonInterleaved(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            if (frames > 0) {
                Context ctx = (Context)user;
                XtFormat format = stream.GetFormat();
                int channels = format.inputs;
                int sampleSize = XtAudio.GetSampleAttributes(format.mix.sample).size;
                for (int f = 0; f < frames; f++)
                    for (int c = 0; c < channels; c++)
                        // Don't do this.
                        ctx.recording.Write(((byte[][])input)[c], f * sampleSize, sampleSize);
            }
        }

        static unsafe void CaptureNonInterleavedRaw(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {

            if (frames > 0) {
                Context ctx = (Context)user;
                XtFormat format = stream.GetFormat();
                int channels = format.inputs;
                int sampleSize = XtAudio.GetSampleAttributes(format.mix.sample).size;
                for (int f = 0; f < frames; f++)
                    for (int c = 0; c < channels; c++) {
                        IntPtr source = new IntPtr(&(((byte**)(IntPtr)input)[c][f * sampleSize]));
                        Marshal.Copy(source, ctx.intermediate, 0, sampleSize);
                        // Don't do this.
                        ctx.recording.Write(ctx.intermediate, 0, sampleSize);
                    }
            }
        }

        public static void Main(string[] args) {

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {

                XtService service = XtAudio.GetServiceBySetup(XtSetup.ConsumerAudio);
                XtFormat format = new XtFormat(new XtMix(44100, XtSample.Int24), 2, 0, 0, 0);
                using (XtDevice device = service.OpenDefaultDevice(false)) {

                    if (device == null) {
                        Console.WriteLine("No default device found.");
                        return;
                    }

                    if (!device.SupportsFormat(format)) {
                        Console.WriteLine("Format not supported.");
                        return;
                    }

                    Context context = new Context();
                    XtBuffer buffer = device.GetBuffer(format);

                    using (FileStream recording = new FileStream(
                        "xt-audio-interleaved.raw", FileMode.Create, FileAccess.Write))
                    using (XtStream stream = device.OpenStream(format, true, false,
                        buffer.current, CaptureInterleaved, XRun, context)) {

                        context.recording = recording;
                        context.intermediate = new byte[GetBufferSize(stream, stream.GetFrames())];
                        stream.Start();
                        Console.WriteLine("Capturing interleaved...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (FileStream recording = new FileStream(
                        "xt-audio-interleaved-raw.raw", FileMode.Create, FileAccess.Write))
                    using (XtStream stream = device.OpenStream(format, true, true,
                        buffer.current, CaptureInterleavedRaw, XRun, context)) {

                        context.recording = recording;
                        context.intermediate = new byte[GetBufferSize(stream, stream.GetFrames())];
                        stream.Start();
                        Console.WriteLine("Capturing interleaved, raw buffers...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (FileStream recording = new FileStream(
                        "xt-audio-non-interleaved.raw", FileMode.Create, FileAccess.Write))
                    using (XtStream stream = device.OpenStream(format, false, false,
                        buffer.current, CaptureNonInterleaved, XRun, context)) {

                        context.recording = recording;
                        context.intermediate = new byte[GetBufferSize(stream, stream.GetFrames())];
                        stream.Start();
                        Console.WriteLine("Capturing non-interleaved...");
                        ReadLine();
                        stream.Stop();
                    }

                    using (FileStream recording = new FileStream(
                        "xt-audio-non-interleaved-raw.raw", FileMode.Create, FileAccess.Write))
                    using (XtStream stream = device.OpenStream(format, false, true,
                        buffer.current, CaptureNonInterleavedRaw, XRun, context)) {

                        context.recording = recording;
                        context.intermediate = new byte[GetBufferSize(stream, stream.GetFrames())];
                        stream.Start();
                        Console.WriteLine("Capturing non-interleaved, raw buffers...");
                        ReadLine();
                        stream.Stop();
                    }
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <fstream>
#include <iostream>

static void ReadLine() {
  std::string s;
  std::cout << "Press any key to continue...\n";
  std::getline(std::cin, s);
}

static int GetBufferSize(const Xt::Stream& stream, int frames) {
  const Xt::Format& format = stream.GetFormat();
  int sampleSize = Xt::Audio::GetSampleAttributes(format.mix.sample).size;
  return frames * format.inputs * sampleSize;
}

static void XRun(int index, void* user) {
  // Don't do this.
  std::cout << "XRun on stream " << index << ".\n";
}

static void CaptureInterleaved(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  if(frames > 0)
    // Don't do this.
    static_cast<std::ofstream*>(user)->write(static_cast<const char*>(input), GetBufferSize(stream, frames));
}

static void CaptureNonInterleaved(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  if(frames > 0) {
    const Xt::Format& format = stream.GetFormat();
    int channels = format.inputs;
    int sampleSize = Xt::Audio::GetSampleAttributes(format.mix.sample).size;
    for(int f = 0; f < frames; f++)
      for(int c = 0; c < channels; c++)
        // Don't do this.
        static_cast<std::ofstream*>(user)->write(&static_cast<char* const*>(input)[c][f * sampleSize], sampleSize);
  }
}

int main(int argc, char** argv) {

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr< Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::ConsumerAudio);
  Xt::Format format(Xt::Mix(44100, Xt::Sample::Int24), 2, 0, 0, 0);
  std::unique_ptr<Xt::Device> device = service->OpenDefaultDevice(false);

  if(!device) {
    std::cout << "No default device found.\n";
    return 0;
  }

  if(!device->SupportsFormat(format)) {
    std::cout << "Format not supported.\n";
    return 0;
  }

  std::unique_ptr<Xt::Stream> stream;
  Xt::Buffer buffer = device->GetBuffer(format);

  std::ofstream interleaved("xt-audio-interleaved.raw", std::ios::out | std::ios::binary);
  stream = device->OpenStream(format, true, buffer.current, CaptureInterleaved, XRun, &interleaved);
  stream->Start();
  std::cout << "Capturing interleaved...\n";
  ReadLine();
  stream->Stop();

  std::ofstream nonInterleaved("xt-audio-non-interleaved.raw", std::ios::out | std::ios::binary);
  stream = device->OpenStream(format, false, buffer.current, CaptureNonInterleaved, XRun, &nonInterleaved);
  stream->Start();
  std::cout << "Capturing non-interleaved...\n";
  ReadLine();
  stream->Stop();

  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service DirectSound, output 0...
-- Info: Opened default device Primair stuurprogramma voor opnemen van geluid: service DirectSound, output 0.
-- Info: Opening stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 2 (0) 0 (0)], interleaved 1...
-- Info: Opened stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 2 (0) 0 (0)], interleaved 1.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Capturing interleaved...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Opening stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 2 (0) 0 (0)], interleaved 0...
-- Info: Opened stream: device Primair stuurprogramma voor opnemen van geluid, bufferSize 500.000000, format [44100 Int24 2 (0) 0 (0)], interleaved 0.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Starting stream on system DSound...
-- Info: Started stream on system DSound.
Capturing non-interleaved...
Press any key to continue...
-- Info: Stopping stream on system DSound...
-- Info: Stopped stream on system DSound.
-- Info: Closing stream on system DSound...
-- Info: Closed stream on system DSound.
-- Info: Closing device Primair stuurprogramma voor opnemen van geluid...
-- Info: Closed device Primair stuurprogramma voor opnemen van geluid.
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).
  • Use JACK or ASIO for full-duplex operation.
package com.xtaudio.xt;

public class FullDuplex {

    static void callback(XtStream stream, Object input, Object output, int frames,
            double time, long position, boolean timeValid, long error, Object user) throws Exception {
        System.arraycopy(input, 0, output, 0, frames * 2);
    }

    public static void main(String[] args) throws Exception {

        XtFormat format;
        XtFormat int44100 = new XtFormat(new XtMix(44100, XtSample.INT32), 2, 0, 2, 0);
        XtFormat int48000 = new XtFormat(new XtMix(48000, XtSample.INT32), 2, 0, 2, 0);
        XtFormat float44100 = new XtFormat(new XtMix(44100, XtSample.FLOAT32), 2, 0, 2, 0);
        XtFormat float48000 = new XtFormat(new XtMix(48000, XtSample.FLOAT32), 2, 0, 2, 0);

        try (XtAudio audio = new XtAudio(null, null, null, null)) {
            XtService service = XtAudio.getServiceBySetup(XtSetup.PRO_AUDIO);
            try (XtDevice device = service.openDefaultDevice(true)) {
                if (device != null) {

                    if (device.supportsFormat(int44100))
                        format = int44100;
                    else if (device.supportsFormat(int48000))
                        format = int48000;
                    else if (device.supportsFormat(float44100))
                        format = float44100;
                    else if (device.supportsFormat(float48000))
                        format = float48000;
                    else
                        return;

                    XtBuffer buffer = device.getBuffer(format);
                    try (XtStream stream = device.openStream(format, true, false,
                            buffer.min, FullDuplex::callback, null, null)) {
                        stream.start();
                        System.out.println("Streaming full-duplex, press any key to continue...");
                        System.console().readLine();
                        stream.stop();
                    }
                }
            }
        }
    }
}
using System;

namespace Xt {

    public class FullDuplex {

        static void Callback(XtStream stream, object input, object output,
            int frames, double time, ulong position, bool timeValid, ulong error, object user) {
            Buffer.BlockCopy((Array)input, 0, (Array)output, 0, frames * 2 * 4);
        }

        public static void Main(string[] args) {

            XtFormat format;
            XtFormat int44100 = new XtFormat(new XtMix(44100, XtSample.Int32), 2, 0, 2, 0);
            XtFormat int48000 = new XtFormat(new XtMix(48000, XtSample.Int32), 2, 0, 2, 0);
            XtFormat float44100 = new XtFormat(new XtMix(44100, XtSample.Float32), 2, 0, 2, 0);
            XtFormat float48000 = new XtFormat(new XtMix(48000, XtSample.Float32), 2, 0, 2, 0);

            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {
                XtService service = XtAudio.GetServiceBySetup(XtSetup.ProAudio);
                using (XtDevice device = service.OpenDefaultDevice(true)) {
                    if (device != null) {

                        if (device.SupportsFormat(int44100))
                            format = int44100;
                        else if (device.SupportsFormat(int48000))
                            format = int48000;
                        else if (device.SupportsFormat(float44100))
                            format = float44100;
                        else if (device.SupportsFormat(float48000))
                            format = float48000;
                        else
                            return;

                        XtBuffer buffer = device.GetBuffer(format);
                        using (XtStream stream = device.OpenStream(format, true,
                            false, buffer.min, Callback, null, null)) {
                            stream.Start();
                            Console.WriteLine("Streaming full-duplex, press any key to continue...");
                            Console.ReadLine();
                            stream.Stop();
                        }
                    }
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>

static void Callback(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  memcpy(output, input, frames * 2 * 4);
}

int main(int argc, char** argv) {

  Xt::Format format;
  Xt::Format int44100(Xt::Mix(44100, Xt::Sample::Int32), 2, 0, 2, 0);
  Xt::Format int48000(Xt::Mix(48000, Xt::Sample::Int32), 2, 0, 2, 0);
  Xt::Format float44100(Xt::Mix(44100, Xt::Sample::Float32), 2, 0, 2, 0);
  Xt::Format float48000(Xt::Mix(48000, Xt::Sample::Float32), 2, 0, 2, 0);

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr< Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::ProAudio);
  std::unique_ptr<Xt::Device> device = service->OpenDefaultDevice(true);
  if(device) {

    if(device->SupportsFormat(int44100))
      format = int44100;
    else if(device->SupportsFormat(int48000))
      format = int48000;
    else if(device->SupportsFormat(float44100))
      format = float44100;
    else if(device->SupportsFormat(float48000))
      format = float48000;
    else
      return 0;

    Xt::Buffer buffer = device->GetBuffer(format);
    std::unique_ptr<Xt::Stream> stream = device->OpenStream(format, true, buffer.current, Callback, nullptr, nullptr);
    stream->Start();
    std::cout << "Streaming full-duplex, press any key to continue...\n";
    std::string s;
    std::getline(std::cin, s);
    stream->Stop();
  }

  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service ASIO, output 1...
-- Info: Opening device: service ASIO, index 0...
-- Info: Opened device ASIO4ALL v2: service ASIO, index 0.
-- Info: Opened default device ASIO4ALL v2: service ASIO, output 1.
-- Info: Opening stream: device ASIO4ALL v2, bufferSize 11.609977, format [44100 Int32 2 (0) 2 (0)], interleaved 1...
-- Info: Opened stream: device ASIO4ALL v2, bufferSize 11.609977, format [44100 Int32 2 (0) 2 (0)], interleaved 1.
-- Info: Starting stream on system Asio...
-- Info: Started stream on system Asio.
Streaming full-duplex, press any key to continue...
-- Info: Stopping stream on system Asio...
-- Info: Stopped stream on system Asio.
-- Info: Closing stream on system Asio...
-- Info: Closed stream on system Asio.
-- Info: Closing device ASIO4ALL v2...
-- Info: Closed device ASIO4ALL v2.
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).
  • Combine any number of input, output or full-duplex devices into a single stream.
package com.xtaudio.xt;

public class Aggregate {

    static void readLine() {
        System.out.println("Press any key to continue...");
        System.console().readLine();
    }

    static void xRun(int index, Object user) {
        // Don't do this.
        System.out.println("XRun on device " + index + ", user = " + user + ".");
    }

    static void aggregate(XtStream stream, Object input, Object output, int frames, double time,
            long position, boolean timeValid, long error, Object user) throws Exception {

        if (frames > 0)
            System.arraycopy(input, 0, output, 0, frames * stream.getFormat().inputs);
    }

    public static void main(String[] args) throws Exception {

        XtMix mix = new XtMix(48000, XtSample.INT16);
        XtFormat inputFormat = new XtFormat(mix, 2, 0, 0, 0);
        XtChannels inputChannels = new XtChannels(2, 0, 0, 0);
        XtFormat outputFormat = new XtFormat(mix, 0, 0, 2, 0);
        XtChannels outputChannels = new XtChannels(0, 0, 2, 0);
        try (XtAudio audio = new XtAudio(null, null, null, null)) {
            XtService service = XtAudio.getServiceBySetup(XtSetup.SYSTEM_AUDIO);
            try (XtDevice input = service.openDefaultDevice(false);
                    XtDevice output = service.openDefaultDevice(true)) {
                if (input != null && input.supportsFormat(inputFormat)
                        && output != null && output.supportsFormat(outputFormat))
                    try (XtStream stream = service.aggregateStream(
                            new XtDevice[]{input, output},
                            new XtChannels[]{inputChannels, outputChannels},
                            new double[]{30.0, 30.0},
                            2, mix, true, false, output, Aggregate::aggregate, Aggregate::xRun, "user-data")) {
                        stream.start();
                        System.out.println("Streaming aggregate, press any key to continue...");
                        System.console().readLine();
                        stream.stop();
                    }
            }
        }
    }
}
using System;

namespace Xt {

    public class Aggregate {

        static void ReadLine() {
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }

        static void XRun(int index, object user) {
            // Don't do this.
            Console.WriteLine("XRun on device " + index + ", user = " + user + ".");
        }

        static void OnAggregate(XtStream stream, object input, object output, int frames, double time,
                ulong position, bool timeValid, ulong error, object user) {
            XtFormat format = stream.GetFormat();
            XtAttributes attrs = XtAudio.GetSampleAttributes(format.mix.sample);
            if (frames > 0)
                Buffer.BlockCopy((Array)input, 0, (Array)output, 0, frames * format.inputs * attrs.size);
        }

        public static void Main(string[] args) {

            XtMix mix = new XtMix(48000, XtSample.Int16);
            XtFormat inputFormat = new XtFormat(mix, 2, 0, 0, 0);
            XtChannels inputChannels = new XtChannels(2, 0, 0, 0);
            XtFormat outputFormat = new XtFormat(mix, 0, 0, 2, 0);
            XtChannels outputChannels = new XtChannels(0, 0, 2, 0);
            using (XtAudio audio = new XtAudio(null, IntPtr.Zero, null, null)) {
                XtService service = XtAudio.GetServiceBySetup(XtSetup.SystemAudio);
                using (XtDevice input = service.OpenDefaultDevice(false))
                using (XtDevice output = service.OpenDefaultDevice(true)) {
                    if (input != null && input.SupportsFormat(inputFormat)
                            && output != null && output.SupportsFormat(outputFormat)) {
                        using (XtStream stream = service.AggregateStream(
                                new XtDevice[] { input, output },
                                new XtChannels[] { inputChannels, outputChannels },
                                new double[] { 30.0, 30.0 },
                                2, mix, true, false, output, OnAggregate, XRun, "user-data")) {
                            stream.Start();
                            Console.WriteLine("Streaming aggregate, press any key to continue...");
                            Console.ReadLine();
                            stream.Stop();
                        }
                    }
                }
            }
        }
    }
}
#include <xt-cpp.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>

static void ReadLine() {
  std::string s;
  std::cout << "Press any key to continue...\n";
  std::getline(std::cin, s);
}

static void XRun(int index, void* user) {
  // Don't do this.
  std::cout << "XRun on stream " << index << ", user = " << static_cast<char*>(user) << ".\n";
}

static void Aggregate(
  const Xt::Stream& stream, const void* input, void* output, int32_t frames,
  double time, uint64_t position, bool timeValid, uint64_t error, void* user) {

  const Xt::Format& format = stream.GetFormat();
  Xt::Attributes attrs = Xt::Audio::GetSampleAttributes(format.mix.sample);
  if(frames > 0)
    memcpy(output, input, frames * format.inputs * attrs.size);
}

int main(int argc, char** argv) {

  double bufferSizes[2];
  Xt::Device* devices[2];
  Xt::Channels channels[2];
  Xt::Mix mix(48000, Xt::Sample::Int16);
  Xt::Format inputFormat(mix, 2, 0, 0, 0);
  Xt::Channels inputChannels(2, 0, 0, 0);
  Xt::Format outputFormat(mix, 0, 0, 2, 0);
  Xt::Channels outputChannels(0, 0, 2, 0);

  Xt::Audio audio("", nullptr, nullptr, nullptr);
  std::unique_ptr<Xt::Service> service = Xt::Audio::GetServiceBySetup(Xt::Setup::SystemAudio);
  std::unique_ptr<Xt::Device> input = service->OpenDefaultDevice(false);
  std::unique_ptr<Xt::Device> output = service->OpenDefaultDevice(true);
  if(input && input->SupportsFormat(inputFormat)
    && output && output->SupportsFormat(outputFormat)) {

    devices[0] = input.get();
    devices[1] = output.get();
    channels[0] = inputChannels;
    channels[1] = outputChannels;
    bufferSizes[0] = 30.0;
    bufferSizes[1] = 30.0;
    std::unique_ptr<Xt::Stream> stream = service->AggregateStream(devices, channels,
      bufferSizes, 2, mix, true, *output, Aggregate, XRun, const_cast<char*>("user-data"));
    stream->Start();
    std::cout << "Streaming aggregate, press any key to continue...\n";
    ReadLine();
    stream->Stop();
  }
  return 0;
}
-- Info: Initializing library (version 1.0.2, built May 30 2016 22:53:02) ...
-- Info: Initialized library (version 1.0.2).
-- Info: Opening default device: service WASAPI, output 0...
-- Info: Opened default device Lijningang (Realtek High Definition Audio) (Shared): service WASAPI, output 0.
-- Info: Opening default device: service WASAPI, output 1...
-- Info: Opened default device Luidsprekers (Realtek High Definition Audio) (Shared): service WASAPI, output 1.
-- Info: Opening aggregate: service WASAPI, count 2...
-- Info: Opening stream: device Lijningang (Realtek High Definition Audio) (Shared), bufferSize 30.000000, format [48000 Int16 2 (0) 0 (0)], interleaved 1...
-- Info: Opened stream: device Lijningang (Realtek High Definition Audio) (Shared), bufferSize 30.000000, format [48000 Int16 2 (0) 0 (0)], interleaved 1.
-- Info: Opening stream: device Luidsprekers (Realtek High Definition Audio) (Shared), bufferSize 30.000000, format [48000 Int16 0 (0) 2 (0)], interleaved 1...
-- Info: Opened stream: device Luidsprekers (Realtek High Definition Audio) (Shared), bufferSize 30.000000, format [48000 Int16 0 (0) 2 (0)], interleaved 1.
-- Info: Opened aggregate: service WASAPI, count 2...
-- Info: Starting stream on system Wasapi...
-- Info: Starting stream on system Wasapi...
-- Info: Started stream on system Wasapi.
-- Info: Starting stream on system Wasapi...
-- Info: Started stream on system Wasapi.
-- Info: Started stream on system Wasapi.
Streaming aggregate, press any key to continue...
Press any key to continue...
XRun on stream -1, user = user-data.
XRun on stream -1, user = user-data.
XRun on stream 0, user = user-data.
-- Info: Stopping stream on system Wasapi...
-- Info: Stopping stream on system Wasapi...
-- Info: Stopped stream on system Wasapi.
-- Info: Stopping stream on system Wasapi...
-- Info: Stopped stream on system Wasapi.
-- Info: Stopped stream on system Wasapi.
-- Info: Closing stream on system Wasapi...
-- Info: Stopping stream on system Wasapi...
-- Info: Stopped stream on system Wasapi.
-- Info: Stopping stream on system Wasapi...
-- Info: Stopped stream on system Wasapi.
-- Info: Closed stream on system Wasapi.
-- Info: Closing device Luidsprekers (Realtek High Definition Audio) (Shared)...
-- Info: Closed device Luidsprekers (Realtek High Definition Audio) (Shared).
-- Info: Closing device Lijningang (Realtek High Definition Audio) (Shared)...
-- Info: Closed device Lijningang (Realtek High Definition Audio) (Shared).
-- Info: Terminating library (version 1.0.2)...
-- Info: Terminated library (version 1.0.2).