MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / parseWav

Function parseWav

source/core/StarAudio.cpp:78–172  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

76 }
77
78 WaveData parseWav(IODevicePtr device) {
79 const size_t sigLength = 4;
80 unique_ptr<char[]> riffSig(new char[sigLength + 1]()); // RIFF\0
81 unique_ptr<char[]> waveSig(new char[sigLength + 1]()); // WAVE\0
82 unique_ptr<char[]> fmtSig(new char[sigLength + 1]()); // fmt \0
83 unique_ptr<char[]> dataSig(new char[sigLength + 1]()); // data\0
84
85 // RIFF Chunk Descriptor
86 device->seek(0);
87 device->readFull(riffSig.get(), sigLength);
88
89 uint32_t fileSize = readLEType<uint32_t>(device);
90 fileSize += sigLength + sizeof(fileSize);
91 if (fileSize != device->size())
92 throw AudioException(strf("Wav file is wrong size, reports {} is actually {}", fileSize, device->size()));
93
94 device->readFull(waveSig.get(), sigLength);
95
96 if ((strcmp(riffSig.get(), "RIFF") != 0) || (strcmp(waveSig.get(), "WAVE") != 0)) { // bytes are not magic
97 auto p = [](char a) { return isprint(a) ? a : '?'; };
98 throw AudioException(strf("Wav file has wrong magic bytes, got `{:c}{:c}{:c}{:c}' and `{:c}{:c}{:c}{:c}' but expected `RIFF' and `WAVE'",
99 p(riffSig[0]), p(riffSig[1]), p(riffSig[2]), p(riffSig[3]), p(waveSig[0]), p(waveSig[1]), p(waveSig[2]), p(waveSig[3])));
100 }
101
102 // fmt subchunk
103
104 device->readFull(fmtSig.get(), sigLength);
105 if (strcmp(fmtSig.get(), "fmt ") != 0) { // friendship is magic
106 auto p = [](char a) { return isprint(a) ? a : '?'; };
107 throw AudioException(strf("Wav file fmt subchunk has wrong magic bytes, got `{:c}{:c}{:c}{:c}' but expected `fmt '",
108 p(fmtSig[0]),
109 p(fmtSig[1]),
110 p(fmtSig[2]),
111 p(fmtSig[3])));
112 }
113
114 uint32_t fmtSubchunkSize = readLEType<uint32_t>(device);
115 fmtSubchunkSize += sigLength;
116 if (fmtSubchunkSize < 20)
117 throw AudioException(strf("fmt subchunk is sized wrong, expected 20 got {}. Is this wav file not PCM?", fmtSubchunkSize));
118
119 uint16_t audioFormat = readLEType<uint16_t>(device);
120 if (audioFormat != 1)
121 throw AudioException("audioFormat data indicates that wav file is something other than PCM format. Unsupported.");
122
123 uint16_t wavChannels = readLEType<uint16_t>(device);
124 uint32_t wavSampleRate = readLEType<uint32_t>(device);
125 uint32_t wavByteRate = readLEType<uint32_t>(device);
126 uint16_t wavBlockAlign = readLEType<uint16_t>(device);
127 uint16_t wavBitsPerSample = readLEType<uint16_t>(device);
128
129 if (wavBitsPerSample != 16)
130 throw AudioException("Only 16-bit PCM wavs are supported.");
131 if (wavByteRate * 8 != wavSampleRate * wavChannels * wavBitsPerSample)
132 throw AudioException("Sanity check failed, ByteRate is wrong");
133 if (wavBlockAlign * 8 != wavChannels * wavBitsPerSample)
134 throw AudioException("Sanity check failed, BlockAlign is wrong");
135

Callers 1

AudioMethod · 0.85

Calls 9

strfFunction · 0.85
fromByteOrderFunction · 0.85
readFullMethod · 0.80
seekMethod · 0.45
getMethod · 0.45
sizeMethod · 0.45
posMethod · 0.45
resizeMethod · 0.45
ptrMethod · 0.45

Tested by

no test coverage detected