Mercurial > games > semicongine
annotate semiconginev2/old/resources/audio.nim @ 1235:c70fee6568f6
did: improv render tests to run without user input
author | sam <sam@basx.dev> |
---|---|
date | Sat, 20 Jul 2024 15:45:02 +0700 |
parents | 56781cc0fc7c |
children |
rev | line source |
---|---|
840
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
1 import std/os |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
2 import std/streams |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
3 import std/strformat |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
4 import std/endians |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
5 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
6 import ../core/audiotypes |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
7 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
8 type |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
9 Encoding {.size: sizeof(uint32).} = enum |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
10 # Unspecified = 0 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
11 # Uint8Ulaw = 1 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
12 # Int8 = 2 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
13 Int16 = 3 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
14 # Int24 = 4 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
15 # Int32 = 5 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
16 # Float32 = 6 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
17 # Float64 = 7 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
18 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
19 AuHeader = object |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
20 magicNumber: uint32 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
21 dataOffset: uint32 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
22 dataSize: uint32 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
23 encoding: Encoding |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
24 sampleRate: uint32 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
25 channels: uint32 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
26 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
27 proc readSample(stream: Stream, encoding: Encoding, channels: int): Sample = |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
28 result[0] = stream.readint16() |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
29 swapEndian16(addr result[0], addr result[0]) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
30 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
31 if channels == 2: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
32 result[1] = stream.readint16() |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
33 swapEndian16(addr result[1], addr result[1]) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
34 else: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
35 result[1] = result[0] |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
36 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
37 # https://en.wikipedia.org/wiki/Au_file_format |
1138 | 38 proc ReadAU*(stream: Stream): Sound = |
840
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
39 var header: AuHeader |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
40 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
41 for name, value in fieldPairs(header): |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
42 var bytes: array[4, uint8] |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
43 stream.read(bytes) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
44 swap(bytes[0], bytes[3]) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
45 swap(bytes[1], bytes[2]) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
46 value = cast[typeof(value)](bytes) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
47 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
48 assert header.magicNumber == 0x2e736e64 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
49 if header.sampleRate != AUDIO_SAMPLE_RATE: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
50 raise newException(Exception, &"Only support sample rate of {AUDIO_SAMPLE_RATE} Hz but got {header.sampleRate} Hz, please resample (e.g. ffmpeg -i <infile> -ar {AUDIO_SAMPLE_RATE} <outfile>)") |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
51 if not (header.channels in [1'u32, 2'u32]): |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
52 raise newException(Exception, "Only support mono and stereo audio at the moment (1 or 2 channels), but found " & $header.channels) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
53 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
54 var annotation: string |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
55 stream.read(annotation) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
56 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
57 result = new Sound |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
58 stream.setPosition(int(header.dataOffset)) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
59 while not stream.atEnd(): |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
60 result[].add stream.readSample(header.encoding, int(header.channels)) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
61 |
902 | 62 {.compile: currentSourcePath.parentDir() & "/stb_vorbis.c".} |
840
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
63 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
64 proc stb_vorbis_decode_memory(mem: pointer, len: cint, channels: ptr cint, sample_rate: ptr cint, output: ptr ptr cshort): cint {.importc.} |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
65 proc free(p: pointer) {.importc.} |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
66 |
1138 | 67 proc ReadVorbis*(stream: Stream): Sound = |
840
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
68 var |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
69 data = stream.readAll() |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
70 channels: cint |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
71 sampleRate: cint |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
72 output: ptr cshort |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
73 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
74 var nSamples = stb_vorbis_decode_memory(addr data[0], cint(data.len), addr channels, addr sampleRate, addr output) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
75 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
76 if nSamples < 0: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
77 raise newException(Exception, &"Unable to read ogg/vorbis sound file, error code: {nSamples}") |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
78 if sampleRate != AUDIO_SAMPLE_RATE: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
79 raise newException(Exception, &"Only support sample rate of {AUDIO_SAMPLE_RATE} Hz but got {sampleRate} Hz, please resample (e.g. ffmpeg -i <infile> -acodec libvorbis -ar {AUDIO_SAMPLE_RATE} <outfile>)") |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
80 |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
81 result = new Sound |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
82 if channels == 2: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
83 result[].setLen(int(nSamples)) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
84 copyMem(addr result[][0], output, nSamples * sizeof(Sample)) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
85 free(output) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
86 elif channels == 1: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
87 for i in 0 ..< nSamples: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
88 let value = cast[ptr UncheckedArray[int16]](output)[i] |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
89 result[].add [value, value] |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
90 free(output) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
91 else: |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
92 free(output) |
44ec744fbedc
did: package restructuring according to nimble recommendation for libraries
Sam <sam@basx.dev>
parents:
diff
changeset
|
93 raise newException(Exception, "Only support mono and stereo audio at the moment (1 or 2 channels), but found " & $channels) |