mirror of
https://github.com/IllusionMan1212/flac-odin.git
synced 2026-10-24 18:12:29 +00:00
Compare commits
2
Commits
dfaca585fd
...
1142d83adb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1142d83adb
|
||
|
|
f444efc5af
|
@@ -6,6 +6,7 @@ Files:-
|
|||||||
Playback issues in the example program that may relate to the decoder:-
|
Playback issues in the example program that may relate to the decoder:-
|
||||||
23 - Crunchy loud noise mixed with the actual audio data
|
23 - Crunchy loud noise mixed with the actual audio data
|
||||||
|
|
||||||
|
uncommon/02 -> 6 channel audio might be incorrect (not a decoder issue afaik)
|
||||||
uncommon/04 -> We get a bits per sample mismatch
|
uncommon/04 -> We get a bits per sample mismatch
|
||||||
uncommon/10 -> We error with Invalid Signature. I assume for these two I should look for the frame sync bits. But maybe my decoder should reject these. idk.
|
uncommon/10 -> We error with Invalid Signature. I assume for these two I should look for the frame sync bits. But maybe my decoder should reject these. idk.
|
||||||
uncommon/11 -> We error with Invalid Signature
|
uncommon/11 -> We error with Invalid Signature
|
||||||
@@ -34,8 +35,10 @@ Things:-
|
|||||||
[ ] Speed optimizations
|
[ ] Speed optimizations
|
||||||
[ ] Seeking
|
[ ] Seeking
|
||||||
[ ] Fuzzing to test the stability of the code
|
[ ] Fuzzing to test the stability of the code
|
||||||
[ ] Check if the use-after-free bug happens on Windows, and if so, if the address sanitizer will show us the full stacktrace
|
[x] Check if the use-after-free bug happens on Windows, and if so, if the address sanitizer will show us the full stacktrace
|
||||||
instead of skipping some procs.
|
instead of skipping some procs.
|
||||||
|
This was caused by `read_data()` and the tee reader writing into the buffer and us using some memory that was freed while the buffer
|
||||||
|
resized. Solution is to use buffer data BEFORE calling `read_data()`
|
||||||
|
|
||||||
[ ] Encoder (low priority for now)
|
[ ] Encoder (low priority for now)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package flac_example
|
package flac_linux_example
|
||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
@@ -51,13 +51,13 @@ main :: proc() {
|
|||||||
os.exit(1)
|
os.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_rate := flac_data.metadata.sample_rate
|
// TODO: channel mapping is incorrect for anything with more than 2 channels.
|
||||||
channels := flac_data.metadata.channels
|
channels := flac_data.metadata.channels
|
||||||
|
|
||||||
md5_ctx: md5.Context
|
md5_ctx: md5.Context
|
||||||
md5.init(&md5_ctx)
|
md5.init(&md5_ctx)
|
||||||
for {
|
for {
|
||||||
frame, err := flac.read_next_frame(reader, flac_data)
|
frame, err := flac.read_next_frame(reader, flac_data, allocator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == .EOF {
|
if err == .EOF {
|
||||||
break
|
break
|
||||||
@@ -67,20 +67,24 @@ main :: proc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if frame.sample_rate != sample_rate || frame.channels != channels {
|
if frame.channels != channels {
|
||||||
// sample_rate = frame.sample_rate
|
// Finish playing the previous frame before changing the hw params.
|
||||||
// channels = frame.channels
|
alsa.pcm_drain(handle)
|
||||||
// alsa_err = alsa.pcm_set_params(handle, .S16_LE, .RW_INTERLEAVED, u32(channels), sample_rate, 1, 0)
|
|
||||||
// if alsa_err < 0 {
|
channels = frame.channels
|
||||||
// fmt.eprintln("Playback open error:", alsa.strerror(alsa_err))
|
alsa_err = alsa.pcm_set_params(handle, .S16_LE, .RW_INTERLEAVED, u32(channels), flac_data.metadata.sample_rate, 1, 500000)
|
||||||
// os.exit(1)
|
if alsa_err < 0 {
|
||||||
// }
|
fmt.eprintln("Playback open error:", alsa.strerror(alsa_err))
|
||||||
//}
|
os.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: resampling
|
||||||
|
|
||||||
// 8 bps audio
|
// 8 bps audio
|
||||||
//converted_samples := make([]u8, len(samples))
|
//converted_samples := make([]u8, len(frame.samples))
|
||||||
//defer delete(converted_samples)
|
//defer delete(converted_samples)
|
||||||
//for sample, i in samples {
|
//for sample, i in frame.samples {
|
||||||
// converted_samples[i] = u8(sample & 0xFF)
|
// converted_samples[i] = u8(sample & 0xFF)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@@ -102,13 +106,6 @@ main :: proc() {
|
|||||||
|
|
||||||
flac.md5hash(&md5_ctx, flac_data.metadata.bits_per_sample, frame.samples)
|
flac.md5hash(&md5_ctx, flac_data.metadata.bits_per_sample, frame.samples)
|
||||||
}
|
}
|
||||||
end := time.now()
|
|
||||||
|
|
||||||
err = flac.md5sum(&md5_ctx, flac_data)
|
|
||||||
if err == .MD5_Mismatch {
|
|
||||||
fmt.println("Decoded audio data is not correct.")
|
|
||||||
os.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
alsa_err = alsa.pcm_drain(handle)
|
alsa_err = alsa.pcm_drain(handle)
|
||||||
if alsa_err < 0 {
|
if alsa_err < 0 {
|
||||||
@@ -116,6 +113,14 @@ main :: proc() {
|
|||||||
}
|
}
|
||||||
alsa.pcm_close(handle)
|
alsa.pcm_close(handle)
|
||||||
|
|
||||||
|
end := time.now()
|
||||||
|
|
||||||
|
err = flac.md5sum(&md5_ctx, flac_data)
|
||||||
|
if err == .MD5_Mismatch {
|
||||||
|
fmt.printfln("Decoded audio data is not correct. Expected MD5: %v, Got: %v", flac_data.metadata.expected_md5, flac_data.metadata.calculated_md5)
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
elapsed := time.diff(start, end)
|
elapsed := time.diff(start, end)
|
||||||
fmt.println("Decoding took", elapsed)
|
fmt.println("Decoding took", elapsed)
|
||||||
}
|
}
|
||||||
@@ -591,10 +591,6 @@ read_next_frame :: proc(r: ^Reader, flac: ^Flac, allocator := context.allocator)
|
|||||||
tee_r: io.Tee_Reader
|
tee_r: io.Tee_Reader
|
||||||
|
|
||||||
crc_buffer: Buffer
|
crc_buffer: Buffer
|
||||||
// NOTE: using the default heap allocator here causes a use-after-free bug on files subset/05, subset/06, and subset/25
|
|
||||||
// No idea what the cause of the bug is.
|
|
||||||
//
|
|
||||||
// Resolved without understanding the root issue. See below code for a note on this.
|
|
||||||
buffer_init_allocator(&crc_buffer, 0, 128)
|
buffer_init_allocator(&crc_buffer, 0, 128)
|
||||||
defer buffer_destroy(&crc_buffer)
|
defer buffer_destroy(&crc_buffer)
|
||||||
|
|
||||||
@@ -806,13 +802,6 @@ read_next_frame :: proc(r: ^Reader, flac: ^Flac, allocator := context.allocator)
|
|||||||
// Frame Footer
|
// Frame Footer
|
||||||
//
|
//
|
||||||
crc16_bytes := buffer_to_bytes(&crc_buffer)
|
crc16_bytes := buffer_to_bytes(&crc_buffer)
|
||||||
// NOTE: The order of these two calls is important. If we're using the default heap allocator
|
|
||||||
// for crc_buffer and we call read_data before calculate_crc16 then we run into a memory bug.
|
|
||||||
// I'm still not sure the root cause of the bug but it disappears when they're in this order.
|
|
||||||
//
|
|
||||||
// In the below cases the bug doesn't happen and the order doesn't matter.
|
|
||||||
// When using the temp allocator or an arena allocator.
|
|
||||||
// When using the reader from the arguments instead of the tee reader.
|
|
||||||
calculated_frame_crc := calculate_crc16(crc16_bytes)
|
calculated_frame_crc := calculate_crc16(crc16_bytes)
|
||||||
frame_crc := u16(read_data(r, u16be) or_return)
|
frame_crc := u16(read_data(r, u16be) or_return)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import "core:crypto/legacy/md5"
|
|||||||
FLAC_MAGIC :: 'f' << 24 | 'L' << 16 | 'a' << 8 | 'C'
|
FLAC_MAGIC :: 'f' << 24 | 'L' << 16 | 'a' << 8 | 'C'
|
||||||
|
|
||||||
//odinfmt: disable
|
//odinfmt: disable
|
||||||
|
@(rodata)
|
||||||
crc8_lookup := [256]u8 {
|
crc8_lookup := [256]u8 {
|
||||||
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
|
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
|
||||||
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
|
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
|
||||||
@@ -41,6 +42,7 @@ crc8_lookup := [256]u8 {
|
|||||||
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3,
|
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(rodata)
|
||||||
crc16_lookup := [256]u16 {
|
crc16_lookup := [256]u16 {
|
||||||
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
|
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
|
||||||
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
|
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
|
||||||
|
|||||||
Reference in New Issue
Block a user