package xt.sample;
import java.util.EnumSet;
import xt.audio.Enums.XtEnumFlags;
import xt.audio.Enums.XtSystem;
import xt.audio.XtAudio;
import xt.audio.XtDeviceList;
import xt.audio.XtPlatform;
import xt.audio.XtService;
public class PrintSimple {
public static void main() throws Exception {
try(XtPlatform platform = XtAudio.init(null, null)) {
for(XtSystem system: platform.getSystems()) {
XtService service = platform.getService(system);
try(XtDeviceList list = service.openDeviceList(EnumSet.of(XtEnumFlags.ALL))) {
for(int d = 0; d < list.getCount(); d++) {
String id = list.getId(d);
System.out.println(system + ": " + list.getName(id));
}
}
}
}
}
}
using System;
namespace Xt
{
public static class PrintSimple
{
[STAThread]
public static void Main()
{
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
foreach (XtSystem system in platform.GetSystems())
{
XtService service = platform.GetService(system);
using XtDeviceList list = service.OpenDeviceList(XtEnumFlags.All);
for (int d = 0; d < list.GetCount(); d++)
{
string id = list.GetId(d);
Console.WriteLine(system + ": " + list.GetName(id));
}
}
}
}
}
#include <xt/XtAudio.hpp>
#include <memory>
#include <cstdint>
#include <iostream>
int
PrintSimpleMain()
{
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
for(Xt::System system: platform->GetSystems())
{
std::unique_ptr<Xt::Service> service = platform->GetService(system);
std::unique_ptr<Xt::DeviceList> list = service->OpenDeviceList(Xt::EnumFlagsAll);
for(int32_t d = 0; d < list->GetCount(); d++)
{
std::string id = list->GetId(d);
std::cout << system << ": " << list->GetName(id) << "\n";
}
}
return 0;
}
package xt.sample;
import java.util.EnumSet;
import xt.audio.Enums.XtEnumFlags;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtVersion;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtDeviceList;
import xt.audio.XtException;
import xt.audio.XtPlatform;
import xt.audio.XtService;
import java.util.Optional;
public class PrintDetailed {
static void onError(String message) {
System.out.println(message);
}
static void printDevices(XtService service, XtDeviceList list) {
for(int d = 0; d < list.getCount(); d++) {
String id = list.getId(d);
try(XtDevice device = service.openDevice(id)) {
Optional<XtMix> mix = device.getMix();
System.out.println(" Device " + id + ":");
System.out.println(" Name: " + list.getName(id));
System.out.println(" Capabilities: " + list.getCapabilities(id));
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));
if(mix.isPresent())
System.out.println(" Current mix: " + mix.get().rate + " " + mix.get().sample);
} catch(Throwable t) {
t.printStackTrace();
}
}
}
public static void main() throws Exception {
XtAudio.setOnError(PrintDetailed::onError);
try(XtPlatform platform = XtAudio.init("Sample", null)) {
XtVersion version = XtAudio.getVersion();
System.out.println("Version: " + version.major + "." + version.minor);
XtSystem pro = platform.setupToSystem(XtSetup.PRO_AUDIO);
System.out.println("Pro Audio: " + pro + " (" + (platform.getService(pro) != null) + ")");
XtSystem system = platform.setupToSystem(XtSetup.SYSTEM_AUDIO);
System.out.println("System Audio: " + system + " (" + (platform.getService(system) != null) + ")");
XtSystem consumer = platform.setupToSystem(XtSetup.CONSUMER_AUDIO);
System.out.println("Consumer Audio: " + consumer + " (" + (platform.getService(consumer) != null) + ")");
for(XtSystem s: platform.getSystems()) {
XtService service = platform.getService(s);
System.out.println("System " + s + ":");
System.out.println(" Capabilities: " + service.getCapabilities());
try(XtDeviceList all = service.openDeviceList(EnumSet.of(XtEnumFlags.ALL))) {
String defaultInputId = service.getDefaultDeviceId(false);
if(defaultInputId != null) {
String name = all.getName(defaultInputId);
System.out.println(" Default input: " + name + " (" + defaultInputId + ")");
}
String defaultOutputId = service.getDefaultDeviceId(true);
if(defaultOutputId != null) {
String name = all.getName(defaultOutputId);
System.out.println(" Default output: " + name + " (" + defaultOutputId + ")");
}
}
try(XtDeviceList inputs = service.openDeviceList(EnumSet.of(XtEnumFlags.INPUT))) {
System.out.println(" Input device count: " + inputs.getCount());
printDevices(service, inputs);
}
try(XtDeviceList outputs = service.openDeviceList(EnumSet.of(XtEnumFlags.OUTPUT))) {
System.out.println(" Output device count: " + outputs.getCount());
printDevices(service, outputs);
}
}
} catch(Throwable t) {
t.printStackTrace();
}
}
}
using System;
namespace Xt
{
public static class PrintDetailed
{
static void OnError(string message)
=> Console.WriteLine(message);
static void PrintDevices(XtService service, XtDeviceList list)
{
for (int d = 0; d < list.GetCount(); d++)
{
string id = list.GetId(d);
try
{
using XtDevice device = service.OpenDevice(id);
XtMix? mix = device.GetMix();
Console.WriteLine(" Device " + id + ":");
Console.WriteLine(" Name: " + list.GetName(id));
Console.WriteLine(" Capabilities: " + list.GetCapabilities(id));
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));
if (mix != null) Console.WriteLine(" Current mix: " + mix.Value.rate + " " + mix.Value.sample);
} catch (Exception e)
{ Console.WriteLine(e); }
}
}
[STAThread]
public static void Main()
{
XtAudio.SetOnError(OnError);
using XtPlatform platform = XtAudio.Init("Sample", IntPtr.Zero);
try
{
XtVersion version = XtAudio.GetVersion();
Console.WriteLine("Version: " + version.major + "." + version.minor);
XtSystem pro = platform.SetupToSystem(XtSetup.ProAudio);
Console.WriteLine("Pro Audio: " + pro + " (" + (platform.GetService(pro) != null) + ")");
XtSystem system = platform.SetupToSystem(XtSetup.SystemAudio);
Console.WriteLine("System Audio: " + system + " (" + (platform.GetService(system) != null) + ")");
XtSystem consumer = platform.SetupToSystem(XtSetup.ConsumerAudio);
Console.WriteLine("Consumer Audio: " + consumer + " (" + (platform.GetService(consumer) != null) + ")");
foreach (XtSystem s in platform.GetSystems())
{
XtService service = platform.GetService(s);
using XtDeviceList all = service.OpenDeviceList(XtEnumFlags.All);
Console.WriteLine("System: " + s);
Console.WriteLine(" Capabilities: " + service.GetCapabilities());
string defaultInput = service.GetDefaultDeviceId(false);
if (defaultInput != null)
{
string name = all.GetName(defaultInput);
Console.WriteLine(" Default input: " + name + " (" + defaultInput + ")");
}
string defaultOutput = service.GetDefaultDeviceId(true);
if (defaultOutput != null)
{
string name = all.GetName(defaultOutput);
Console.WriteLine(" Default output: " + name + " (" + defaultOutput + ")");
}
using XtDeviceList inputs = service.OpenDeviceList(XtEnumFlags.Input);
Console.WriteLine(" Input device count: " + inputs.GetCount());
PrintDevices(service, inputs);
using XtDeviceList outputs = service.OpenDeviceList(XtEnumFlags.Output);
Console.WriteLine(" Output device count: " + outputs.GetCount());
PrintDevices(service, outputs);
}
} catch (Exception e)
{ Console.WriteLine(e); }
}
}
}
#include <xt/XtAudio.hpp>
#include <memory>
#include <cstdint>
#include <cstdlib>
#include <iostream>
static void
OnError(std::string const& message)
{ std::cout << message << std::endl; }
void
PrintDevices(Xt::Service const* service, Xt::DeviceList const* list)
{
for(int32_t d = 0; d < list->GetCount(); d++)
{
std::string id = list->GetId(d);
try
{
std::unique_ptr<Xt::Device> device = service->OpenDevice(id);
std::optional<Xt::Mix> mix = device->GetMix();
std::cout << " Device " << id << ":\n";
std::cout << " Name: " << list->GetName(id) << "\n";
std::cout << " Capabilities: " << list->GetCapabilities(id) << "\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";
if(mix) std::cout << " Current mix: " << mix->rate << " " << mix->sample << "\n";
} catch(std::exception const& e)
{ std::cout << e.what() << "\n"; }
}
}
int
PrintDetailedMain()
{
Xt::Audio::SetOnError(OnError);
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
try
{
Xt::Version version = Xt::Audio::GetVersion();
std::cout << "Version: " << version.major << "." << version.minor << "\n";
Xt::System pro = platform->SetupToSystem(Xt::Setup::ProAudio);
std::cout << "Pro Audio: " << pro << " (" << (platform->GetService(pro) != nullptr) << ")\n";
Xt::System system = platform->SetupToSystem(Xt::Setup::SystemAudio);
std::cout << "System Audio: " << system << " (" << (platform->GetService(system) != nullptr) << ")\n";
Xt::System consumer = platform->SetupToSystem(Xt::Setup::ConsumerAudio);
std::cout << "Consumer Audio: " << consumer << " (" << (platform->GetService(consumer) != nullptr) << ")\n";
for(Xt::System s: platform->GetSystems())
{
std::unique_ptr<Xt::Service> service = platform->GetService(s);
std::unique_ptr<Xt::DeviceList> all = service->OpenDeviceList(Xt::EnumFlagsAll);
std::cout << "System " << s << ":\n";
std::cout << " Capabilities: " << service->GetCapabilities() << "\n";
std::optional<std::string> defaultInput = service->GetDefaultDeviceId(false);
if(defaultInput.has_value())
{
std::string name = all->GetName(defaultInput.value());
std::cout << " Default input: " << name << " (" << defaultInput.value() << ")\n";
}
std::optional<std::string> defaultOutput = service->GetDefaultDeviceId(true);
if(defaultOutput.has_value())
{
std::string name = all->GetName(defaultOutput.value());
std::cout << " Default output: " << name << " (" << defaultOutput.value() << ")\n";
}
std::unique_ptr<Xt::DeviceList> inputs = service->OpenDeviceList(Xt::EnumFlagsInput);
std::cout << " Input device count: " << inputs->GetCount() << "\n";
PrintDevices(service.get(), inputs.get());
std::unique_ptr<Xt::DeviceList> outputs = service->OpenDeviceList(Xt::EnumFlagsOutput);
std::cout << " Output device count: " << outputs->GetCount() << "\n";
PrintDevices(service.get(), outputs.get());
}
return EXIT_SUCCESS;
} catch(std::exception const& e)
{
std::cout << e.what() << "\n";
return EXIT_FAILURE;
}
}
package xt.sample;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtBufferSize;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtDeviceStreamParams;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
public class RenderSimple {
static float _phase = 0.0f;
static final float FREQUENCY = 440.0f;
static final XtMix MIX = new XtMix(44100, XtSample.FLOAT32);
static final XtChannels CHANNELS = new XtChannels(0, 0, 1, 0);
static final XtFormat FORMAT = new XtFormat(MIX, CHANNELS);
static float nextSample() {
_phase += FREQUENCY / FORMAT.mix.rate;
if(_phase >= 1.0f) _phase = -1.0f;
return (float)Math.sin(2.0 * _phase * Math.PI);
}
static int onBuffer(XtStream stream, XtBuffer buffer, Object user) {
XtSafeBuffer safe = XtSafeBuffer.get(stream);
safe.lock(buffer);
float[] output = (float[])safe.getOutput();
for(int f = 0; f < buffer.frames; f++) output[f] = nextSample();
safe.unlock(buffer);
return 0;
}
public static void main() throws Exception {
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.CONSUMER_AUDIO);
XtService service = platform.getService(system);
if(service == null) return;
String defaultOutput = service.getDefaultDeviceId(true);
if(defaultOutput == null) return;
try(XtDevice device = service.openDevice(defaultOutput)) {
if(!device.supportsFormat(FORMAT)) return;
XtBufferSize size = device.getBufferSize(FORMAT);
streamParams = new XtStreamParams(true, RenderSimple::onBuffer, null, null);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
try(XtStream stream = device.openStream(deviceParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
stream.start();
Thread.sleep(2000);
stream.stop();
}
}
}
}
}
using System;
using System.Threading;
namespace Xt
{
public class RenderSimple
{
static float _phase;
const float Frequency = 440.0f;
static readonly XtMix Mix = new XtMix(44100, XtSample.Float32);
static readonly XtChannels Channels = new XtChannels(0, 0, 1, 0);
static readonly XtFormat Format = new XtFormat(Mix, Channels);
static float NextSample()
{
_phase += Frequency / Mix.rate;
if (_phase >= 1.0f) _phase = -1.0f;
return (float)Math.Sin(2.0 * _phase * Math.PI);
}
static int OnBuffer(XtStream stream, in XtBuffer buffer, object user)
{
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
safe.Lock(in buffer);
float[] output = (float[])safe.GetOutput();
for (int f = 0; f < buffer.frames; f++) output[f] = NextSample();
safe.Unlock(in buffer);
return 0;
}
[STAThread]
public static void Main()
{
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.ConsumerAudio);
XtService service = platform.GetService(system);
if (service == null) return;
string defaultOutput = service.GetDefaultDeviceId(true);
if(defaultOutput == null) return;
using XtDevice device = service.OpenDevice(defaultOutput);
if (!device.SupportsFormat(Format)) return;
XtBufferSize size = device.GetBufferSize(Format);
streamParams = new XtStreamParams(true, OnBuffer, null, null);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using XtStream stream = device.OpenStream(in deviceParams, null);
using XtSafeBuffer safe = XtSafeBuffer.Register(stream);
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
}
}
#define _USE_MATH_DEFINES 1
#include <xt/XtAudio.hpp>
#include <cmath>
#include <chrono>
#include <thread>
#include <cstdint>
static float _phase = 0.0f;
static float const Frequency = 440.0f;
static Xt::Channels const Channels(0, 0, 1, 0);
static Xt::Mix const Mix(44100, Xt::Sample::Float32);
static Xt::Format const Format(Mix, Channels);
static float
NextSample()
{
_phase += Frequency / Mix.rate;
if (_phase >= 1.0f) _phase = -1.0f;
return sinf(2.0f * _phase * static_cast<float>(M_PI));
}
static uint32_t
OnBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
float* output = static_cast<float*>(buffer.output);
for (int32_t f = 0; f < buffer.frames; f++) output[f] = NextSample();
return 0;
}
int
RenderSimpleMain()
{
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::System system = platform->SetupToSystem(Xt::Setup::ConsumerAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if (!service) return 0;
std::optional<std::string> id = service->GetDefaultDeviceId(true);
if(!id.has_value()) return 0;
std::unique_ptr<Xt::Device> device = service->OpenDevice(id.value());
if(!device->SupportsFormat(Format)) return 0;
double bufferSize = device->GetBufferSize(Format).current;
Xt::StreamParams streamParams(true, OnBuffer, nullptr, nullptr);
Xt::DeviceStreamParams deviceParams(streamParams, Format, bufferSize);
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
return 0;
}
package xt.sample;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtBufferSize;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtDeviceStreamParams;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
import java.io.FileOutputStream;
public class CaptureSimple {
static final XtMix MIX = new XtMix(44100, XtSample.INT24);
static final XtChannels CHANNELS = new XtChannels(1, 0, 0, 0);
static final XtFormat FORMAT = new XtFormat(MIX, CHANNELS);
// Normally don't do I/O in the callback.
static int onBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
var output = (FileOutputStream)user;
XtSafeBuffer safe = XtSafeBuffer.get(stream);
safe.lock(buffer);
var input = (byte[])safe.getInput();
int size = XtAudio.getSampleAttributes(MIX.sample).size;
output.write(input, 0, buffer.frames * size);
safe.unlock(buffer);
return 0;
}
public static void main() throws Exception {
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.CONSUMER_AUDIO);
XtService service = platform.getService(system);
if(service == null) return;
String defaultInput = service.getDefaultDeviceId(false);
if(defaultInput == null) return;
try(XtDevice device = service.openDevice(defaultInput)) {
if(!device.supportsFormat(FORMAT)) return;
XtBufferSize size = device.getBufferSize(FORMAT);
streamParams = new XtStreamParams(true, CaptureSimple::onBuffer, null, null);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
try(FileOutputStream recording = new FileOutputStream("xt-audio.raw");
XtStream stream = device.openStream(deviceParams, recording);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
stream.start();
Thread.sleep(2000);
stream.stop();
}
}
}
}
}
using System;
using System.IO;
using System.Threading;
namespace Xt
{
public class CaptureSimple
{
static readonly XtMix Mix = new XtMix(44100, XtSample.Int24);
static readonly XtChannels Channels = new XtChannels(1, 0, 0, 0);
static readonly XtFormat Format = new XtFormat(Mix, Channels);
// Normally don't do I/O in the callback.
static int OnBuffer(XtStream stream, in XtBuffer buffer, object user)
{
var output = (FileStream)user;
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
safe.Lock(buffer);
var input = (byte[])safe.GetInput();
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
if (buffer.frames > 0) output.Write(input, 0, buffer.frames * size);
safe.Unlock(buffer);
return 0;
}
[STAThread]
public static void Main()
{
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.ConsumerAudio);
XtService service = platform.GetService(system);
if (service == null) return;
string defaultInput = service.GetDefaultDeviceId(false);
if(defaultInput == null) return;
using XtDevice device = service.OpenDevice(defaultInput);
if (!device.SupportsFormat(Format)) return;
XtBufferSize size = device.GetBufferSize(Format);
streamParams = new XtStreamParams(true, OnBuffer, null, null);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using var recording = new FileStream("xt-audio.raw", FileMode.Create, FileAccess.Write);
using XtStream stream = device.OpenStream(in deviceParams, recording);
using XtSafeBuffer safe = XtSafeBuffer.Register(stream);
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
}
}
#include <xt/XtAudio.hpp>
#include <thread>
#include <chrono>
#include <fstream>
static Xt::Channels const Channels(1, 0, 0, 0);
static Xt::Mix const Mix(44100, Xt::Sample::Int24);
static Xt::Format const Format(Mix, Channels);
// Normally don't do I/O in the callback.
static uint32_t
OnBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
auto os = static_cast<std::ofstream*>(user);
char const* input = static_cast<char const*>(buffer.input);
int32_t bytes = Xt::Audio::GetSampleAttributes(Mix.sample).size * buffer.frames;
os->write(input, bytes);
return 0;
}
int
CaptureSimpleMain()
{
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::System system = platform->SetupToSystem(Xt::Setup::ConsumerAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if(!service) return 0;
std::optional<std::string> id = service->GetDefaultDeviceId(false);
if(!id.has_value()) return 0;
std::unique_ptr<Xt::Device> device = service->OpenDevice(id.value());
if(!device->SupportsFormat(Format)) return 0;
double bufferSize = device->GetBufferSize(Format).current;
Xt::StreamParams streamParams(true, OnBuffer, nullptr, nullptr);
Xt::DeviceStreamParams deviceParams(streamParams, Format, bufferSize);
std::ofstream recording("xt-audio.raw", std::ios::out | std::ios::binary);
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, &recording);
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
return 0;
}
package xt.sample;
import com.sun.jna.Native;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtBufferSize;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtDeviceStreamParams;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
public class RenderAdvanced {
static float _phase = 0.0f;
static final float FREQUENCY = 440.0f;
static final XtMix MIX = new XtMix(44100, XtSample.FLOAT32);
static float nextSample() {
_phase += FREQUENCY / MIX.rate;
if(_phase >= 1.0) _phase = -1.0f;
return (float)Math.sin(2.0 * _phase * Math.PI);
}
// Normally don't do I/O in the callback.
static void onXRun(XtStream stream, int index, Object user) {
System.out.println("XRun on device " + index + ".");
}
static void onRunning(XtStream stream, boolean running, long error, Object user) {
String evt = running? "Started": "Stopped";
System.out.println("Stream event: " + evt + ", new state: " + stream.isRunning() + ".");
if(error != 0) System.out.println(XtAudio.getErrorInfo(error).toString());
}
static void runStream(XtStream stream) throws Exception {
stream.start();
Thread.sleep(2000);
stream.stop();
}
static int onInterleavedSafeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
XtSafeBuffer safe = XtSafeBuffer.get(stream);
int channels = stream.getFormat().channels.outputs;
safe.lock(buffer);
float[] output = (float[])safe.getOutput();
for(int f = 0; f < buffer.frames; f++) {
float sample = nextSample();
for(int c = 0; c < channels; c++) output[f * channels + c] = sample;
}
safe.unlock(buffer);
return 0;
}
static int onInterleavedNativeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
int channels = stream.getFormat().channels.outputs;
int size = XtAudio.getSampleAttributes(MIX.sample).size;
for(int f = 0; f < buffer.frames; f++) {
float sample = nextSample();
for(int c = 0; c < channels; c++)
buffer.output.setFloat((f * channels + c) * size, sample);
}
return 0;
}
static int onNonInterleavedSafeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
XtSafeBuffer safe = XtSafeBuffer.get(stream);
int channels = stream.getFormat().channels.outputs;
safe.lock(buffer);
float[][] output = (float[][])safe.getOutput();
for(int f = 0; f < buffer.frames; f++) {
float sample = nextSample();
for(int c = 0; c < channels; c++) output[c][f] = sample;
}
safe.unlock(buffer);
return 0;
}
static int onNonInterleavedNativeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
int channels = stream.getFormat().channels.outputs;
int size = XtAudio.getSampleAttributes(MIX.sample).size;
for(int f = 0; f < buffer.frames; f++) {
float sample = nextSample();
for(int c = 0; c < channels; c++)
buffer.output.getPointer(c * Native.POINTER_SIZE).setFloat(f * size, sample);
}
return 0;
}
public static void main() throws Exception {
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.CONSUMER_AUDIO);
XtService service = platform.getService(system);
if(service == null) return;
String defaultOutput = service.getDefaultDeviceId(true);
if(defaultOutput == null) return;
XtFormat format = new XtFormat(MIX, new XtChannels(0, 0, 2, 0));
try(XtDevice device = service.openDevice(defaultOutput)) {
if(!device.supportsFormat(format)) return;
XtBufferSize size = device.getBufferSize(format);
System.out.println("Render interleaved, safe buffers...");
streamParams = new XtStreamParams(true, RenderAdvanced::onInterleavedSafeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, format, size.current);
try(XtStream stream = device.openStream(deviceParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
runStream(stream);
}
System.out.println("Render interleaved, native buffers...");
streamParams = new XtStreamParams(true, RenderAdvanced::onInterleavedNativeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, format, size.current);
try(XtStream stream = device.openStream(deviceParams, null)) {
runStream(stream);
}
System.out.println("Render non-interleaved, safe buffers...");
streamParams = new XtStreamParams(false, RenderAdvanced::onNonInterleavedSafeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, format, size.current);
try(XtStream stream = device.openStream(deviceParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
runStream(stream);
}
System.out.println("Render non-interleaved, native buffers...");
streamParams = new XtStreamParams(false, RenderAdvanced::onNonInterleavedNativeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, format, size.current);
try(XtStream stream = device.openStream(deviceParams, null)) {
runStream(stream);
}
System.out.println("Render interleaved, safe buffers (channel 0)...");
XtFormat sendTo0 = new XtFormat(MIX, new XtChannels(0, 0, 1, 1L << 0));
streamParams = new XtStreamParams(true, RenderAdvanced::onInterleavedSafeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, sendTo0, size.current);
try(XtStream stream = device.openStream(deviceParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
runStream(stream);
}
System.out.println("Render non-interleaved, native buffers (channel 1)...");
XtFormat sendTo1 = new XtFormat(MIX, new XtChannels(0, 0, 1, 1L << 1));
streamParams = new XtStreamParams(false, RenderAdvanced::onNonInterleavedNativeBuffer, RenderAdvanced::onXRun, RenderAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, sendTo1, size.current);
try(XtStream stream = device.openStream(deviceParams, null)) {
runStream(stream);
}
}
}
}
}
using System;
using System.Threading;
namespace Xt
{
public class RenderAdvanced
{
static float _phase = 0.0f;
const float Frequency = 440.0f;
static readonly XtMix Mix = new XtMix(44100, XtSample.Float32);
static float NextSample()
{
_phase += Frequency / Mix.rate;
if (_phase >= 1.0f) _phase = -1.0f;
return (float)Math.Sin(2.0 * _phase * Math.PI);
}
// Normally don't do I/O in the callback.
static void OnXRun(XtStream stream, int index, object user)
=> Console.WriteLine("XRun on device " + index + ".");
static void OnRunning(XtStream stream, bool running, ulong error, object user)
{
string evt = running ? "Started" : "Stopped";
Console.WriteLine("Stream event: " + evt + ", new state: " + stream.IsRunning() + ".");
if (error != 0) Console.WriteLine(XtAudio.GetErrorInfo(error).ToString());
}
static void RunStream(XtStream stream)
{
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
static int OnInterleavedSafeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
int channels = stream.GetFormat().channels.outputs;
safe.Lock(in buffer);
float[] output = (float[])safe.GetOutput();
for (int f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for (int c = 0; c < channels; c++) output[f * channels + c] = sample;
}
safe.Unlock(buffer);
return 0;
}
static unsafe int OnInterleavedNativeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
int channels = stream.GetFormat().channels.outputs;
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
for (int f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for (int c = 0; c < channels; c++) ((float*)buffer.output)[f * channels + c] = sample;
}
return 0;
}
static int OnNonInterleavedSafeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
int channels = stream.GetFormat().channels.outputs;
safe.Lock(buffer);
float[][] output = (float[][])safe.GetOutput();
for (int f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for (int c = 0; c < channels; c++) output[c][f] = sample;
}
safe.Unlock(buffer);
return 0;
}
static unsafe int OnNonInterleavedNativeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
int channels = stream.GetFormat().channels.outputs;
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
for (int f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for (int c = 0; c < channels; c++) ((float**)buffer.output)[c][f] = sample;
}
return 0;
}
[STAThread]
public static void Main()
{
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.ConsumerAudio);
XtService service = platform.GetService(system);
if (service == null) return;
XtFormat format = new XtFormat(Mix, new XtChannels(0, 0, 2, 0));
string defaultOutput = service.GetDefaultDeviceId(true);
if (defaultOutput == null) return;
using XtDevice device = service.OpenDevice(defaultOutput);
if (!device.SupportsFormat(format)) return;
XtBufferSize size = device.GetBufferSize(format);
Console.WriteLine("Render interleaved, safe buffers...");
streamParams = new XtStreamParams(true, OnInterleavedSafeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in format, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
using (XtSafeBuffer safe = XtSafeBuffer.Register(stream))
RunStream(stream);
Console.WriteLine("Render interleaved, native buffers...");
streamParams = new XtStreamParams(true, OnInterleavedNativeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in format, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
RunStream(stream);
Console.WriteLine("Render non-interleaved, safe buffers...");
streamParams = new XtStreamParams(false, OnNonInterleavedSafeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in format, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
using (XtSafeBuffer safe = XtSafeBuffer.Register(stream))
RunStream(stream);
Console.WriteLine("Render non-interleaved, native buffers...");
streamParams = new XtStreamParams(false, OnNonInterleavedNativeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in format, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
RunStream(stream);
Console.WriteLine("Render interleaved, safe buffers (channel 0)...");
XtFormat sendTo0 = new XtFormat(Mix, new XtChannels(0, 0, 1, 1L << 0));
streamParams = new XtStreamParams(true, OnInterleavedSafeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in sendTo0, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
using (XtSafeBuffer safe = XtSafeBuffer.Register(stream))
RunStream(stream);
Console.WriteLine("Render non-interleaved, native buffers (channel 1)...");
XtFormat sendTo1 = new XtFormat(Mix, new XtChannels(0, 0, 1, 1L << 1));
streamParams = new XtStreamParams(false, OnNonInterleavedNativeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in sendTo1, size.current);
using (XtStream stream = device.OpenStream(in deviceParams, null))
RunStream(stream);
}
}
}
#define _USE_MATH_DEFINES 1
#include <xt/XtAudio.hpp>
#include <cmath>
#include <chrono>
#include <thread>
#include <cstdint>
#include <iostream>
static float _phase = 0.0f;
static float const Frequency = 440.0f;
static Xt::Mix const Mix(44100, Xt::Sample::Float32);
// Normally don't do I/O in the callback.
static void
OnXRun(Xt::Stream const& stream, int32_t index, void* user)
{ std::cout << "XRun on device " << index << ".\n"; }
static void
OnRunning(Xt::Stream const& stream, bool running, uint64_t error, void* user)
{
char const* evt = running? "Started": "Stopped";
std::cout << "Stream event: " << evt << ", new state: " << stream.IsRunning() << ".\n";
if(error != 0) std::cout << Xt::Audio::GetErrorInfo(error) << ".\n";
}
static void
RunStream(Xt::Stream* stream)
{
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
}
static float
NextSample()
{
_phase += Frequency / Mix.rate;
if (_phase >= 1.0f) _phase = -1.0f;
return sinf(2.0f * _phase * static_cast<float>(M_PI));
}
static uint32_t
OnInterleavedBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
float* output = static_cast<float*>(buffer.output);
int32_t channels = stream.GetFormat().channels.outputs;
int32_t size = Xt::Audio::GetSampleAttributes(Mix.sample).size;
for(int32_t f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for (int32_t c = 0; c < channels; c++) output[f * channels + c] = sample;
}
return 0;
}
static uint32_t
OnNonInterleavedBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
float** output = static_cast<float**>(buffer.output);
int32_t channels = stream.GetFormat().channels.outputs;
int32_t size = Xt::Audio::GetSampleAttributes(Mix.sample).size;
for(int32_t f = 0; f < buffer.frames; f++)
{
float sample = NextSample();
for(int32_t c = 0; c < channels; c++) output[c][f] = sample;
}
return 0;
}
int
RenderAdvancedMain()
{
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::Format format(Mix, Xt::Channels(0, 0, 2, 0));
Xt::System system = platform->SetupToSystem(Xt::Setup::ConsumerAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if(!service) return 0;
std::optional<std::string> id = service->GetDefaultDeviceId(true);
if(!id.has_value()) return 0;
std::unique_ptr<Xt::Device> device = service->OpenDevice(id.value());
if (!device->SupportsFormat(format)) return 0;
Xt::BufferSize size = device->GetBufferSize(format);
std::cout << "Render interleaved...\n";
Xt::StreamParams streamParams(true, OnInterleavedBuffer, OnXRun, OnRunning);
Xt::DeviceStreamParams deviceParams(streamParams, format, size.current);
{
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
RunStream(stream.get());
}
std::cout << "Render non-interleaved...\n";
streamParams = Xt::StreamParams(false, OnNonInterleavedBuffer, OnXRun, OnRunning);
deviceParams = Xt::DeviceStreamParams(streamParams, format, size.current);
{
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
RunStream(stream.get());
}
std::cout << "Render interleaved (channel 0)...\n";
Xt::Format sendTo0(Mix, Xt::Channels(0, 0, 1, 1ULL << 0));
streamParams = Xt::StreamParams(true, OnInterleavedBuffer, OnXRun, OnRunning);
deviceParams = Xt::DeviceStreamParams(streamParams, sendTo0, size.current);
{
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
RunStream(stream.get());
}
std::cout << "Render non-interleaved (channel 1)...\n";
Xt::Format sendTo1(Mix, Xt::Channels(0, 0, 1, 1ULL << 1));
streamParams = Xt::StreamParams(false, OnNonInterleavedBuffer, OnXRun, OnRunning);
deviceParams = Xt::DeviceStreamParams(streamParams, sendTo1, size.current);
{
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
RunStream(stream.get());
}
return 0;
}
package xt.sample;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtBufferSize;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtDeviceStreamParams;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
import java.io.FileOutputStream;
public class CaptureAdvanced {
static class Context {
byte[] intermediate;
FileOutputStream out;
}
static final XtMix MIX = new XtMix(44100, XtSample.INT24);
static final XtChannels CHANNELS = new XtChannels(2, 0, 0, 0);
static final XtFormat FORMAT = new XtFormat(MIX, CHANNELS);
// Normally don't do I/O in the callback.
static void onXRun(XtStream stream, int index, Object user) {
System.out.println("XRun on device " + index + ".");
}
static void onRunning(XtStream stream, boolean running, long error, Object user) {
String evt = running? "Started": "Stopped";
System.out.println("Stream event: " + evt + ", new state: " + stream.isRunning() + ".");
if(error != 0) System.out.println(XtAudio.getErrorInfo(error).toString());
}
static int getBufferSize(int channels, int frames) {
int size = XtAudio.getSampleAttributes(MIX.sample).size;
return channels * frames * size;
}
static void runStream(XtStream stream) throws Exception {
stream.start();
Thread.sleep(2000);
stream.stop();
}
// Normally don't do I/O in the callback.
static int onInterleavedSafeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
var out = (FileOutputStream)user;
XtSafeBuffer safe = XtSafeBuffer.get(stream);
int bytes = getBufferSize(CHANNELS.inputs, buffer.frames);
safe.lock(buffer);
out.write((byte[])safe.getInput(), 0, bytes);
safe.unlock(buffer);
return 0;
}
// Normally don't do I/O in the callback.
static int onInterleavedNativeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
var ctx = (Context)user;
int bytes = getBufferSize(CHANNELS.inputs, buffer.frames);
buffer.input.read(0, ctx.intermediate, 0, bytes);
ctx.out.write(ctx.intermediate, 0, bytes);
return 0;
}
// Normally don't do I/O in the callback.
static int onNonInterleavedSafeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
var out = (FileOutputStream)user;
XtSafeBuffer safe = XtSafeBuffer.get(stream);
int size = XtAudio.getSampleAttributes(MIX.sample).size;
safe.lock(buffer);
for(int f = 0; f < buffer.frames; f++)
for(int c = 0; c < CHANNELS.inputs; c++)
out.write(((byte[][])safe.getInput())[c], f * size, size);
safe.unlock(buffer);
return 0;
}
// Normally don't do I/O in the callback.
static int onNonInterleavedNativeBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
var ctx = (Context)user;
int size = XtAudio.getSampleAttributes(MIX.sample).size;
for(int f = 0; f < buffer.frames; f++)
for(int c = 0; c < CHANNELS.inputs; c++) {
Pointer channel = buffer.input.getPointer(c * Native.POINTER_SIZE);
channel.read(f * size, ctx.intermediate, 0, size);
ctx.out.write(ctx.intermediate, 0, size);
}
return 0;
}
public static void main() throws Exception {
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.CONSUMER_AUDIO);
XtService service = platform.getService(system);
if(service == null) return;
String defaultInput = service.getDefaultDeviceId(false);
if(defaultInput == null) return;
try(XtDevice device = service.openDevice(defaultInput)) {
if(!device.supportsFormat(FORMAT)) return;
XtBufferSize size = device.getBufferSize(FORMAT);
System.out.println("Capture interleaved, safe buffers...");
streamParams = new XtStreamParams(true, CaptureAdvanced::onInterleavedSafeBuffer, CaptureAdvanced::onXRun, CaptureAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
try(FileOutputStream recording = new FileOutputStream("xt-audio-interleaved-safe.raw");
XtStream stream = device.openStream(deviceParams, recording);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
runStream(stream);
}
System.out.println("Capture interleaved, native buffers...");
streamParams = new XtStreamParams(true, CaptureAdvanced::onInterleavedNativeBuffer, CaptureAdvanced::onXRun, CaptureAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
Context context = new Context();
try(FileOutputStream recording = new FileOutputStream("xt-audio-interleaved-native.raw");
XtStream stream = device.openStream(deviceParams, context)) {
context.out = recording;
context.intermediate = new byte[getBufferSize(CHANNELS.inputs, stream.getFrames())];
runStream(stream);
}
System.out.println("Capture non-interleaved, safe buffers...");
streamParams = new XtStreamParams(false, CaptureAdvanced::onNonInterleavedSafeBuffer, CaptureAdvanced::onXRun, CaptureAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
try(FileOutputStream recording = new FileOutputStream("xt-audio-non-interleaved-safe.raw");
XtStream stream = device.openStream(deviceParams, recording);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
runStream(stream);
}
System.out.println("Capture non-interleaved, native buffers...");
context = new Context();
streamParams = new XtStreamParams(false, CaptureAdvanced::onNonInterleavedNativeBuffer, CaptureAdvanced::onXRun, CaptureAdvanced::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, FORMAT, size.current);
try(FileOutputStream recording = new FileOutputStream("xt-audio-non-interleaved-native.raw");
XtStream stream = device.openStream(deviceParams, context)) {
context.out = recording;
context.intermediate = new byte[getBufferSize(1, stream.getFrames())];
runStream(stream);
}
}
}
}
}
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
namespace Xt
{
public class CaptureAdvanced
{
class Context
{
internal byte[] intermediate;
internal FileStream recording;
}
static readonly XtMix Mix = new XtMix(44100, XtSample.Int24);
static readonly XtChannels Channels = new XtChannels(2, 0, 0, 0);
static readonly XtFormat Format = new XtFormat(Mix, Channels);
// Normally don't do I/O in the callback.
static void OnXRun(XtStream stream, int index, object user)
=> Console.WriteLine("XRun on device " + index + ".");
static void OnRunning(XtStream stream, bool running, ulong error, object user)
{
string evt = running ? "Started" : "Stopped";
Console.WriteLine("Stream event: " + evt + ", new state: " + stream.IsRunning() + ".");
if (error != 0) Console.WriteLine(XtAudio.GetErrorInfo(error).ToString());
}
static void RunStream(XtStream stream)
{
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
static int GetBufferSize(int channels, int frames)
{
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
return channels * frames * size;
}
// Normally don't do I/O in the callback.
static int OnInterleavedSafeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
var output = (FileStream)user;
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
int bytes = GetBufferSize(Channels.inputs, buffer.frames);
safe.Lock(in buffer);
output.Write((byte[])safe.GetInput(), 0, bytes);
safe.Unlock(in buffer);
return 0;
}
// Normally don't do I/O in the callback.
static int OnInterleavedNativeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
var ctx = (Context)user;
int bytes = GetBufferSize(Channels.inputs, buffer.frames);
Marshal.Copy(buffer.input, ctx.intermediate, 0, bytes);
ctx.recording.Write(ctx.intermediate, 0, bytes);
return 0;
}
// Normally don't do I/O in the callback.
static int OnNonInterleavedSafeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
var output = (FileStream)user;
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
safe.Lock(in buffer);
for (int f = 0; f < buffer.frames; f++)
for (int c = 0; c < Channels.inputs; c++)
output.Write(((byte[][])safe.GetInput())[c], f * size, size);
safe.Unlock(in buffer);
return 0;
}
// Normally don't do I/O in the callback.
static unsafe int OnNonInterleavedNativeBuffer(XtStream stream, in XtBuffer buffer, object user)
{
var ctx = (Context)user;
int size = XtAudio.GetSampleAttributes(Mix.sample).size;
for (int f = 0; f < buffer.frames; f++)
for (int c = 0; c < Channels.inputs; c++)
{
IntPtr source = new IntPtr(&(((byte**)buffer.input)[c][f * size]));
Marshal.Copy(source, ctx.intermediate, 0, size);
ctx.recording.Write(ctx.intermediate, 0, size);
}
return 0;
}
[STAThread]
public static void Main()
{
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.ConsumerAudio);
XtService service = platform.GetService(system);
if (service == null) return;
string defaultInput = service.GetDefaultDeviceId(false);
if (defaultInput == null) return;
using XtDevice device = service.OpenDevice(defaultInput);
if (!device.SupportsFormat(Format)) return;
XtBufferSize size = device.GetBufferSize(Format);
Console.WriteLine("Capture interleaved, safe buffers...");
streamParams = new XtStreamParams(true, OnInterleavedSafeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using (FileStream recording = new FileStream("xt-audio-interleaved-safe.raw", FileMode.Create, FileAccess.Write))
using (XtStream stream = device.OpenStream(in deviceParams, recording))
using (XtSafeBuffer safe = XtSafeBuffer.Register(stream))
RunStream(stream);
Console.WriteLine("Capture interleaved, native buffers...");
var context = new Context();
streamParams = new XtStreamParams(true, OnInterleavedNativeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using (FileStream recording = new FileStream("xt-audio-interleaved-native.raw", FileMode.Create, FileAccess.Write))
using (XtStream stream = device.OpenStream(in deviceParams, context))
{
context.recording = recording;
context.intermediate = new byte[GetBufferSize(Channels.inputs, stream.GetFrames())];
RunStream(stream);
}
Console.WriteLine("Capture non-interleaved, safe buffers...");
streamParams = new XtStreamParams(false, OnNonInterleavedSafeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using (FileStream recording = new FileStream("xt-audio-non-interleaved-safe.raw", FileMode.Create, FileAccess.Write))
using (XtStream stream = device.OpenStream(in deviceParams, recording))
using (XtSafeBuffer safe = XtSafeBuffer.Register(stream))
RunStream(stream);
Console.WriteLine("Capture non-interleaved, native buffers...");
context = new Context();
streamParams = new XtStreamParams(false, OnNonInterleavedNativeBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in Format, size.current);
using (FileStream recording = new FileStream("xt-audio-non-interleaved-native.raw", FileMode.Create, FileAccess.Write))
using (XtStream stream = device.OpenStream(in deviceParams, context))
{
context.recording = recording;
context.intermediate = new byte[GetBufferSize(Channels.inputs, stream.GetFrames())];
RunStream(stream);
}
}
}
}
#include <xt/XtAudio.hpp>
#include <chrono>
#include <thread>
#include <fstream>
#include <iostream>
static Xt::Channels const Channels(2, 0, 0, 0);
static Xt::Mix const Mix(44100, Xt::Sample::Int24);
static Xt::Format const Format(Mix, Channels);
// Normally don't do I/O in the callback.
static void
OnXRun(Xt::Stream const& stream, int32_t index, void* user)
{ std::cout << "XRun on device " << index << ".\n"; }
static void
OnRunning(Xt::Stream const& stream, bool running, uint64_t error, void* user)
{
char const* evt = running? "Started": "Stopped";
std::cout << "Stream event: " << evt << ", new state: " << stream.IsRunning() << ".\n";
if(error != 0) std::cout << Xt::Audio::GetErrorInfo(error) << ".\n";
}
static void
RunStream(Xt::Stream* stream)
{
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
}
static int32_t
GetBufferSize(int32_t channels, int32_t frames)
{
int32_t size = Xt::Audio::GetSampleAttributes(Mix.sample).size;
return channels * frames * size;
}
// Normally don't do I/O in the callback.
static uint32_t
OnInterleavedBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
auto output = static_cast<std::ofstream*>(user);
auto input = static_cast<char const*>(buffer.input);
int32_t bytes = GetBufferSize(Channels.inputs, buffer.frames);
output->write(input, bytes);
return 0;
}
// Normally don't do I/O in the callback.
static uint32_t
OnNonInterleavedBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
auto output = static_cast<std::ofstream*>(user);
auto input = static_cast<char const* const*>(buffer.input);
int32_t size = Xt::Audio::GetSampleAttributes(Mix.sample).size;
for(int32_t f = 0; f < buffer.frames; f++)
for(int32_t c = 0; c < Channels.inputs; c++)
output->write(&input[c][f * size], size);
return 0;
}
int
CaptureAdvancedMain()
{
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::System system = platform->SetupToSystem(Xt::Setup::ConsumerAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if(!service) return 0;
std::optional<std::string> id = service->GetDefaultDeviceId(false);
if(!id.has_value()) return 0;
std::unique_ptr<Xt::Device> device = service->OpenDevice(id.value());
if(!device->SupportsFormat(Format)) return 0;
Xt::BufferSize size = device->GetBufferSize(Format);
std::cout << "Capture interleaved...\n";
Xt::StreamParams streamParams(true, OnInterleavedBuffer, OnXRun, OnRunning);
Xt::DeviceStreamParams deviceParams(streamParams, Format, size.current);
{
std::ofstream interleaved("xt-audio-interleaved.raw", std::ios::out | std::ios::binary);
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, &interleaved);
RunStream(stream.get());
}
std::cout << "Capture non-interleaved...\n";
streamParams = Xt::StreamParams(false, OnNonInterleavedBuffer, OnXRun, OnRunning);
deviceParams = Xt::DeviceStreamParams(streamParams, Format, size.current);
{
std::ofstream nonInterleaved("xt-audio-non-interleaved.raw", std::ios::out | std::ios::binary);
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, &nonInterleaved);
RunStream(stream.get());
}
return 0;
}
package xt.sample;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtServiceCaps;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtBufferSize;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtDeviceStreamParams;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
public class FullDuplex {
// Normally don't do I/O in the callback.
static void onXRun(XtStream stream, int index, Object user) {
System.out.println("XRun on device " + index + ".");
}
static void onRunning(XtStream stream, boolean running, long error, Object user) {
String evt = running? "Started": "Stopped";
System.out.println("Stream event: " + evt + ", new state: " + stream.isRunning() + ".");
if(error != 0) System.out.println(XtAudio.getErrorInfo(error).toString());
}
static int onBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
XtSafeBuffer safe = XtSafeBuffer.get(stream);
safe.lock(buffer);
System.arraycopy(safe.getInput(), 0, safe.getOutput(), 0, buffer.frames * 2);
safe.unlock(buffer);
return 0;
}
public static void main() throws Exception {
XtFormat format;
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
XtFormat int44100 = new XtFormat(new XtMix(44100, XtSample.INT32), new XtChannels(2, 0, 2, 0));
XtFormat int48000 = new XtFormat(new XtMix(48000, XtSample.INT32), new XtChannels(2, 0, 2, 0));
XtFormat float44100 = new XtFormat(new XtMix(44100, XtSample.FLOAT32), new XtChannels(2, 0, 2, 0));
XtFormat float48000 = new XtFormat(new XtMix(48000, XtSample.FLOAT32), new XtChannels(2, 0, 2, 0));
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.PRO_AUDIO);
XtService service = platform.getService(system);
if(service == null || !service.getCapabilities().contains(XtServiceCaps.FULL_DUPLEX)) return;
String defaultOutput = service.getDefaultDeviceId(true);
if(defaultOutput == null) return;
try(XtDevice device = service.openDevice(defaultOutput)) {
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;
XtBufferSize size = device.getBufferSize(format);
streamParams = new XtStreamParams(true, FullDuplex::onBuffer, FullDuplex::onXRun, FullDuplex::onRunning);
deviceParams = new XtDeviceStreamParams(streamParams, format, size.current);
try(XtStream stream = device.openStream(deviceParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
stream.start();
Thread.sleep(2000);
stream.stop();
}
}
}
}
}
using System;
using System.Threading;
namespace Xt
{
public class FullDuplex
{
// Normally don't do I/O in the callback.
static void OnXRun(XtStream stream, int index, object user)
=> Console.WriteLine("XRun on device " + index + ".");
static void OnRunning(XtStream stream, bool running, ulong error, object user)
{
string evt = running ? "Started" : "Stopped";
Console.WriteLine("Stream event: " + evt + ", new state: " + stream.IsRunning() + ".");
if (error != 0) Console.WriteLine(XtAudio.GetErrorInfo(error).ToString());
}
static int OnBuffer(XtStream stream, in XtBuffer buffer, object user)
{
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
safe.Lock(in buffer);
Buffer.BlockCopy(safe.GetInput(), 0, safe.GetOutput(), 0, buffer.frames * 2 * 4);
safe.Unlock(in buffer);
return 0;
}
[STAThread]
public static void Main()
{
XtFormat format;
XtStreamParams streamParams;
XtDeviceStreamParams deviceParams;
XtFormat int44100 = new XtFormat(new XtMix(44100, XtSample.Int32), new XtChannels(2, 0, 2, 0));
XtFormat int48000 = new XtFormat(new XtMix(48000, XtSample.Int32), new XtChannels(2, 0, 2, 0));
XtFormat float44100 = new XtFormat(new XtMix(44100, XtSample.Float32), new XtChannels(2, 0, 2, 0));
XtFormat float48000 = new XtFormat(new XtMix(48000, XtSample.Float32), new XtChannels(2, 0, 2, 0));
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.ProAudio);
XtService service = platform.GetService(system);
if (service == null || (service.GetCapabilities() & XtServiceCaps.FullDuplex) == 0) return;
string defaultId = service.GetDefaultDeviceId(true);
if (defaultId == null) return;
using XtDevice device = service.OpenDevice(defaultId);
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;
XtBufferSize size = device.GetBufferSize(format);
streamParams = new XtStreamParams(true, OnBuffer, OnXRun, OnRunning);
deviceParams = new XtDeviceStreamParams(in streamParams, in format, size.current);
using XtStream stream = device.OpenStream(in deviceParams, null);
using XtSafeBuffer safe = XtSafeBuffer.Register(stream);
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
}
}
#include <xt/XtAudio.hpp>
#include <thread>
#include <chrono>
#include <cstring>
#include <iostream>
// Normally don't do I/O in the callback.
static void
OnXRun(Xt::Stream const& stream, int32_t index, void* user)
{ std::cout << "XRun on device " << index << ".\n"; }
static uint32_t
OnBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
int32_t bytes = buffer.frames * 2 * 4;
std::memcpy(buffer.output, buffer.input, bytes);
return 0;
}
static void
OnRunning(Xt::Stream const& stream, bool running, uint64_t error, void* user)
{
char const* evt = running? "Started": "Stopped";
std::cout << "Stream event: " << evt << ", new state: " << stream.IsRunning() << ".\n";
if(error != 0) std::cout << Xt::Audio::GetErrorInfo(error) << ".\n";
}
int
FullDuplexMain()
{
Xt::Format format;
Xt::Format int44100(Xt::Mix(44100, Xt::Sample::Int32), Xt::Channels(2, 0, 2, 0));
Xt::Format int48000(Xt::Mix(48000, Xt::Sample::Int32), Xt::Channels(2, 0, 2, 0));
Xt::Format float44100(Xt::Mix(44100, Xt::Sample::Float32), Xt::Channels(2, 0, 2, 0));
Xt::Format float48000(Xt::Mix(48000, Xt::Sample::Float32), Xt::Channels(2, 0, 2, 0));
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::System system = platform->SetupToSystem(Xt::Setup::ProAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if(!service || (service->GetCapabilities() & Xt::ServiceCapsFullDuplex) == 0) return 0;
std::optional<std::string> id = service->GetDefaultDeviceId(true);
if(!id.has_value()) return 0;
std::unique_ptr<Xt::Device> device = service->OpenDevice(id.value());
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;
double bufferSize = device->GetBufferSize(format).current;
Xt::StreamParams streamParams(true, OnBuffer, OnXRun, OnRunning);
Xt::DeviceStreamParams deviceParams(streamParams, format, bufferSize);
std::unique_ptr<Xt::Stream> stream = device->OpenStream(deviceParams, nullptr);
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
return 0;
}
package xt.sample;
import xt.audio.Enums.XtSample;
import xt.audio.Enums.XtServiceCaps;
import xt.audio.Enums.XtSetup;
import xt.audio.Enums.XtSystem;
import xt.audio.Structs.XtAggregateDeviceParams;
import xt.audio.Structs.XtAggregateStreamParams;
import xt.audio.Structs.XtBuffer;
import xt.audio.Structs.XtChannels;
import xt.audio.Structs.XtFormat;
import xt.audio.Structs.XtMix;
import xt.audio.Structs.XtStreamParams;
import xt.audio.XtAudio;
import xt.audio.XtDevice;
import xt.audio.XtPlatform;
import xt.audio.XtSafeBuffer;
import xt.audio.XtService;
import xt.audio.XtStream;
public class Aggregate {
// Normally don't do I/O in the callback.
static void onXRun(XtStream stream, int index, Object user) {
System.out.println("XRun on device " + index + ".");
}
static void onRunning(XtStream stream, boolean running, long error, Object user) {
String evt = running? "Started": "Stopped";
System.out.println("Stream event: " + evt + ", new state: " + stream.isRunning() + ".");
if(error != 0) System.out.println(XtAudio.getErrorInfo(error).toString());
}
static int onBuffer(XtStream stream, XtBuffer buffer, Object user) throws Exception {
XtSafeBuffer safe = XtSafeBuffer.get(stream);
safe.lock(buffer);
int count = buffer.frames * stream.getFormat().channels.inputs;
System.arraycopy(safe.getInput(), 0, safe.getOutput(), 0, count);
safe.unlock(buffer);
return 0;
}
public static void main() throws Exception {
XtAggregateStreamParams aggregateParams;
XtMix mix = new XtMix(48000, XtSample.INT16);
XtFormat inputFormat = new XtFormat(mix, new XtChannels(2, 0, 0, 0));
XtFormat outputFormat = new XtFormat(mix, new XtChannels(0, 0, 2, 0));
try(XtPlatform platform = XtAudio.init(null, null)) {
XtSystem system = platform.setupToSystem(XtSetup.SYSTEM_AUDIO);
XtService service = platform.getService(system);
if(service == null || !service.getCapabilities().contains(XtServiceCaps.AGGREGATION)) return;
String defaultInput = service.getDefaultDeviceId(false);
String defaultOutput = service.getDefaultDeviceId(true);
if(defaultInput == null || defaultOutput == null) return;
try(XtDevice input = service.openDevice(defaultInput);
XtDevice output = service.openDevice(defaultOutput)) {
if(!input.supportsFormat(inputFormat)) return;
if(!output.supportsFormat(outputFormat)) return;
XtAggregateDeviceParams[] deviceParams = new XtAggregateDeviceParams[2];
deviceParams[0] = new XtAggregateDeviceParams(input, inputFormat.channels, 30.0);
deviceParams[1] = new XtAggregateDeviceParams(output, outputFormat.channels, 30.0);
XtStreamParams streamParams = new XtStreamParams(true, Aggregate::onBuffer, Aggregate::onXRun, Aggregate::onRunning);
aggregateParams = new XtAggregateStreamParams(streamParams, deviceParams, 2, mix, output);
try(XtStream stream = service.aggregateStream(aggregateParams, null);
XtSafeBuffer safe = XtSafeBuffer.register(stream)) {
stream.start();
Thread.sleep(2000);
stream.stop();
}
}
}
}
}
using System;
using System.Threading;
namespace Xt
{
public class Aggregate
{
// Normally don't do I/O in the callback.
static void OnXRun(XtStream stream, int index, object user)
=> Console.WriteLine("XRun on device " + index + ".");
static void OnRunning(XtStream stream, bool running, ulong error, object user)
{
string evt = running ? "Started" : "Stopped";
Console.WriteLine("Stream event: " + evt + ", new state: " + stream.IsRunning() + ".");
if (error != 0) Console.WriteLine(XtAudio.GetErrorInfo(error).ToString());
}
static int OnBuffer(XtStream stream, in XtBuffer buffer, object user)
{
XtSafeBuffer safe = XtSafeBuffer.Get(stream);
safe.Lock(buffer);
XtFormat format = stream.GetFormat();
XtAttributes attrs = XtAudio.GetSampleAttributes(format.mix.sample);
int bytes = buffer.frames * stream.GetFormat().channels.inputs * attrs.size;
Buffer.BlockCopy(safe.GetInput(), 0, safe.GetOutput(), 0, bytes);
safe.Unlock(buffer);
return 0;
}
[STAThread]
public static void Main()
{
XtAggregateStreamParams aggregateParams;
XtMix mix = new XtMix(48000, XtSample.Int16);
XtFormat inputFormat = new XtFormat(mix, new XtChannels(2, 0, 0, 0));
XtFormat outputFormat = new XtFormat(mix, new XtChannels(0, 0, 2, 0));
using XtPlatform platform = XtAudio.Init(null, IntPtr.Zero);
XtSystem system = platform.SetupToSystem(XtSetup.SystemAudio);
XtService service = platform.GetService(system);
if (service == null || (service.GetCapabilities() & XtServiceCaps.Aggregation) == 0) return;
string defaultInput = service.GetDefaultDeviceId(false);
if (defaultInput == null) return;
using XtDevice input = service.OpenDevice(defaultInput);
if (!input.SupportsFormat(inputFormat)) return;
string defaultOutput = service.GetDefaultDeviceId(true);
if (defaultOutput == null) return;
using XtDevice output = service.OpenDevice(defaultOutput);
if (!output.SupportsFormat(outputFormat)) return;
XtAggregateDeviceParams[] deviceParams = new XtAggregateDeviceParams[2];
deviceParams[0] = new XtAggregateDeviceParams(input, in inputFormat.channels, 30.0);
deviceParams[1] = new XtAggregateDeviceParams(output, in outputFormat.channels, 30.0);
XtStreamParams streamParams = new XtStreamParams(true, OnBuffer, OnXRun, OnRunning);
aggregateParams = new XtAggregateStreamParams(in streamParams, deviceParams, 2, mix, output);
using XtStream stream = service.AggregateStream(in aggregateParams, null);
using XtSafeBuffer safe = XtSafeBuffer.Register(stream);
stream.Start();
Thread.Sleep(2000);
stream.Stop();
}
}
}
#include <xt/XtAudio.hpp>
#include <chrono>
#include <thread>
#include <cstdint>
#include <cstring>
#include <iostream>
// Normally don't do I/O in the callback.
static void
OnXRun(Xt::Stream const& stream, int32_t index, void* user)
{ std::cout << "XRun on device " << index << ".\n"; }
static void
OnRunning(Xt::Stream const& stream, bool running, uint64_t error, void* user)
{
char const* evt = running? "Started": "Stopped";
std::cout << "Stream event: " << evt << ", new state: " << stream.IsRunning() << ".\n";
if(error != 0) std::cout << Xt::Audio::GetErrorInfo(error) << ".\n";
}
static uint32_t
OnBuffer(Xt::Stream const& stream, Xt::Buffer const& buffer, void* user)
{
Xt::Format const& format = stream.GetFormat();
Xt::Attributes attrs = Xt::Audio::GetSampleAttributes(format.mix.sample);
int32_t bytes = buffer.frames * format.channels.inputs * attrs.size;
std::memcpy(buffer.output, buffer.input, bytes);
return 0;
}
int
AggregateMain()
{
Xt::Mix mix(48000, Xt::Sample::Int16);
Xt::Format inputFormat(mix, Xt::Channels(2, 0, 0, 0));
Xt::Format outputFormat(mix, Xt::Channels(0, 0, 2, 0));
std::unique_ptr<Xt::Platform> platform = Xt::Audio::Init("", nullptr);
Xt::System system = platform->SetupToSystem(Xt::Setup::SystemAudio);
std::unique_ptr<Xt::Service> service = platform->GetService(system);
if(!service || (service->GetCapabilities() & Xt::ServiceCapsAggregation) == 0) return 0;
std::optional<std::string> defaultInput = service->GetDefaultDeviceId(false);
if(!defaultInput.has_value()) return 0;
std::unique_ptr<Xt::Device> input = service->OpenDevice(defaultInput.value());
if(!input->SupportsFormat(inputFormat)) return 0;
std::optional<std::string> defaultOutput = service->GetDefaultDeviceId(true);
if(!defaultOutput.has_value()) return 0;
std::unique_ptr<Xt::Device> output = service->OpenDevice(defaultOutput.value());
if(!output->SupportsFormat(outputFormat)) return 0;
Xt::AggregateDeviceParams deviceParams[2];
deviceParams[0] = Xt::AggregateDeviceParams(input.get(), inputFormat.channels, 30.0);
deviceParams[1] = Xt::AggregateDeviceParams(output.get(), outputFormat.channels, 30.0);
Xt::StreamParams streamParams(true, OnBuffer, OnXRun, OnRunning);
Xt::AggregateStreamParams aggregateParams(streamParams, deviceParams, 2, mix, output.get());
std::unique_ptr<Xt::Stream> stream = service->AggregateStream(aggregateParams, nullptr);
stream->Start();
std::this_thread::sleep_for(std::chrono::seconds(2));
stream->Stop();
return 0;
}