Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
88badc6
- Start The Decoder with DataConverter
Logickin-Lambda Aug 25, 2025
9df0f3c
- Ported DataConverter
Logickin-Lambda Aug 25, 2025
cb48c06
- Daily Commit
Logickin-Lambda Aug 26, 2025
f5d1880
- Completed the C part of the zaudio
Logickin-Lambda Aug 27, 2025
6b1ef44
- All Required Coding is Done
Logickin-Lambda Aug 27, 2025
1a2ea91
- Cleared The Compile Time Errors, but...
Logickin-Lambda Aug 28, 2025
c54c2ec
- Successfully created Decoder and its Config, but...
Logickin-Lambda Aug 28, 2025
d08ac9b
- bug fixes
Logickin-Lambda Aug 29, 2025
b102c8a
- Updated decoder function involving channel_map
Logickin-Lambda Sep 1, 2025
38098b0
Merge branch 'zig-gamedev:main' into Resampler_Decoder_Prototype
Logickin-Lambda Sep 1, 2025
8cf3eca
- Added Missing Functions For DataConverter
Logickin-Lambda Sep 2, 2025
0d6d2f7
- Updated README With The New Type
Logickin-Lambda Sep 2, 2025
7652850
- Updated Naming and Type Inconsistency
Logickin-Lambda Sep 8, 2025
0fe8f17
- Remove bad comments
Logickin-Lambda Sep 14, 2025
61d036b
Merge branch 'main' of https://github.com/Logickin-Lambda/zaudio
Logickin-Lambda Sep 20, 2025
484f599
- Encoder! It has begun!
Logickin-Lambda Sep 20, 2025
a875fe5
- Completed test for Encoder and Data Converter
Logickin-Lambda Sep 22, 2025
f90774c
- Decoder has also been tested!
Logickin-Lambda Sep 22, 2025
80a8738
- Added getUserData for Decoder
Logickin-Lambda Sep 22, 2025
bc4e474
- Commit for code for testing in linux
Logickin-Lambda Sep 23, 2025
1f91bcf
- Cleared the code for the testing type
Logickin-Lambda Sep 23, 2025
1e8cec7
- Corrected Errors Reported By the Copilot
Logickin-Lambda Sep 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Provided structs:
- [x] `DelayNode`
- [x] custom nodes
- [x] `Decoder` (missing methods)
- [x] `Encoder` (missing methods)
- [x] `DataConverter`

## Getting started
Expand All @@ -50,7 +51,7 @@ pub fn build(b: *std.Build) void {
}
```

Now in your code you may import and use `zaudio`:
Now in your code you may import and use the high level API of `zaudio`:

```zig
const zaudio = @import("zaudio");
Expand All @@ -72,3 +73,60 @@ pub fn main() !void {
...
}
```

Or use the low level API which is similar to the original miniaudio library, but because the callback function is bridged from the original C library, you must explicitly handle the errors at the callback level:

```zig
const zaudio = @import("zaudio");

pub fn main() !void {
...
zaudio.init(std.heap.smp_allocator);
defer zaudio.deinit();

const decoder_config = zaudio.Decoder.Config.initDefault();
var mp3_decoder = try zaudio.Decoder.createFromFile("testing_media/Accipiter Supersaw Demo.mp3", decoder_config);
defer mp3_decoder.destroy();

// device
var device_config = zaudio.Device.Config.init(.playback);
device_config.playback.format = zaudio.Format.float32;
device_config.playback.channels = 2;
device_config.sample_rate = SAMPLE_RATE;
device_config.data_callback = data_callback; // we will fill that with actual signal source
device_config.user_data = mp3_decoder;

const device = zaudio.Device.create(null, device_config) catch {
@panic("Failed to open playback device");
};
defer device.destroy();

zaudio.Device.start(device) catch {
zaudio.Device.destroy(device);
@panic("Failed to start playback device");
};
...
}

fn data_callback(device: *zaudio.Device, pOutput: ?*anyopaque, _: ?*const anyopaque, frame_count: u32) callconv(.c) void {
const decoder_opt: ?*zaudio.Decoder = @ptrCast(device.getUserData());

if (decoder_opt) |decoder| {
var frames_read: u64 = 0;

_ = try decoder.readPCMFrames(pOutput.?, frame_count) catch |err| {
std.debug.print("ERROR: {any}", .{err});
return;
};

if (frames_read < frame_count) {
decoder.seekToPCMFrames(0) catch {
@panic("cannot seek");
};
}
} else {
return;
}
}

```
1 change: 0 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub fn build(b: *std.Build) void {
.file = b.path("libs/miniaudio/miniaudio.c"),
.flags = &.{
"-DMA_NO_WEBAUDIO",
"-DMA_NO_ENCODING",
"-DMA_NO_NULL",
"-DMA_NO_JACK",
"-DMA_NO_DSOUND",
Expand Down
80 changes: 80 additions & 0 deletions src/zaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,84 @@ void zaudioDecoderDestroy(
s_mem.onFree(handle, s_mem.pUserData);
}

void* zaudioDecoderGetUserData(ma_decoder* handle) {
assert(handle != NULL);
return handle->pUserData;
}

//--------------------------------------------------------------------------------------------------
void zaudioEncoderConfigInit(
ma_encoding_format encoding_format,
ma_format format,
ma_uint32 channels,
ma_uint32 sample_rate,
ma_encoder_config* out_config
){
assert(out_config != NULL);
*out_config = ma_encoder_config_init(encoding_format, format, channels, sample_rate);
}


ma_result zaudioEncoderCreate(
ma_encoder_write_proc on_write,
ma_encoder_seek_proc on_seek,
void* user_data,
const ma_encoder_config* config,
ma_encoder** out_handle
){
assert(user_data != NULL && config != NULL && out_handle != NULL);
*out_handle = s_mem.onMalloc(sizeof(ma_encoder), s_mem.pUserData);
ma_result res = ma_encoder_init(on_write, on_seek, user_data, config, *out_handle);
if (res != MA_SUCCESS){
s_mem.onFree(*out_handle, s_mem.pUserData);
*out_handle = NULL;
}
return res;
}

ma_result zaudioEncoderCreateFromVfs(
ma_vfs* vfs,
const char* file_path,
const ma_encoder_config* config,
ma_encoder** out_handle
){
assert(vfs != NULL && file_path != NULL && config != NULL && out_handle != NULL);
*out_handle = s_mem.onMalloc(sizeof(ma_encoder), s_mem.pUserData);
ma_result res = ma_encoder_init_vfs(vfs, file_path, config, *out_handle);
if(res != MA_SUCCESS){
s_mem.onFree(*out_handle, s_mem.pUserData);
*out_handle = NULL;
}
return res;
}

ma_result zaudioEncoderCreateFromFile(
const char* file_path,
const ma_encoder_config* config,
ma_encoder** out_handle
){
assert(file_path != NULL && config != NULL && out_handle != NULL);
*out_handle = s_mem.onMalloc(sizeof(ma_encoder), s_mem.pUserData);
ma_result res = ma_encoder_init_file(file_path, config, *out_handle);
if (res != MA_SUCCESS){
s_mem.onFree(*out_handle, s_mem.pUserData);
*out_handle = NULL;
}
return res;
}

void zaudioEncoderDestroy(
ma_encoder* handle
){
assert(handle != NULL);
ma_encoder_uninit(handle);
s_mem.onFree(handle, s_mem.pUserData);
}

void* zaudioEncoderGetUserData(ma_encoder* handle) {
assert(handle != NULL);
return handle->pUserData;
}

//--------------------------------------------------------------------------------------------------

Loading
Loading