| 1 | // Copyright (c) 2025 Delyan Angelov. All rights reserved. Use of this source code |
| 2 | // is governed by an MIT license that can be found in the LICENSE file. |
| 3 | module vorbis |
| 4 | |
| 5 | // DecodedSong contains the information about a fully decoded song, that was loaded either by decode_file/1 or by decode_memory/1 . |
| 6 | pub struct DecodedSong { |
| 7 | pub mut: |
| 8 | path string |
| 9 | channels i32 |
| 10 | sample_rate i32 |
| 11 | sample_len i32 |
| 12 | data &i16 = unsafe { nil } |
| 13 | } |
| 14 | |
| 15 | // free frees all the resources allocated for the decoded song |
| 16 | pub fn (mut song DecodedSong) free() { |
| 17 | unsafe { |
| 18 | C.free(song.data) |
| 19 | song.data = nil |
| 20 | song.path.free() |
| 21 | song.path.str = nil |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | // decode_file completely decodes the given file from `path` in memory. |
| 26 | // NOTE: for bigger songs, the memory usage may be disproportionate, since vorbis/ogg songs |
| 27 | // are usually highly compressed with a lossy encoder. |
| 28 | pub fn decode_file(path string) !DecodedSong { |
| 29 | mut res := DecodedSong{ |
| 30 | path: path |
| 31 | } |
| 32 | unsafe { |
| 33 | size := C.stb_vorbis_decode_filename(&char(res.path.str), &res.channels, &res.sample_rate, |
| 34 | &res.data) |
| 35 | if size == -1 { |
| 36 | return error('could not decode ogg file') |
| 37 | } |
| 38 | res.sample_len = size |
| 39 | } |
| 40 | return res |
| 41 | } |
| 42 | |
| 43 | // decode_memory completely decodes the given encoded memory block that is pointed by `ptr`. |
| 44 | // NOTE: for bigger songs, the memory usage may be disproportionate. Consider using decoding while |
| 45 | // playing instead, which can conserve the used RAM, at the cost of slightly higher CPU usage. |
| 46 | pub fn decode_memory(ptr &u8, len i32) !DecodedSong { |
| 47 | mut res := DecodedSong{ |
| 48 | path: ':memory:' |
| 49 | } |
| 50 | unsafe { |
| 51 | size := C.stb_vorbis_decode_memory(ptr, len, &res.channels, &res.sample_rate, &res.data) |
| 52 | if size == -1 { |
| 53 | return error('could not decode ogg/vorbis memory block') |
| 54 | } |
| 55 | res.sample_len = size |
| 56 | } |
| 57 | return res |
| 58 | } |
| 59 | |