11#include " AudioBuffer.hpp"
2- #include " AudioBuffer.hpp"
32#include < al.h>
43#include < vorbis\codec.h>
54#include < vorbis\vorbisenc.h>
@@ -17,7 +16,7 @@ AudioBuffer::AudioBuffer(char* buffer, int channel, int sampleRate, int bps, int
1716{
1817}
1918
20- std::optional <AudioBuffer> AudioBuffer::FromWAV (const std::filesystem::path& path)
19+ std::expected <AudioBuffer, AudioBuffer::WAVLoadError > AudioBuffer::FromWAV (const std::filesystem::path& path)
2120{
2221 // https://stackoverflow.com/questions/36949957/loading-a-wav-file-for-openal
2322 auto convertToInt = [](char * buffer, int len) -> int
@@ -38,45 +37,51 @@ std::optional<AudioBuffer> AudioBuffer::FromWAV(const std::filesystem::path& pat
3837 int size;
3938 char buffer[4 ];
4039
41- std::ifstream in (path);
40+ std::ifstream in (path, std::ios::binary);
41+
42+ if (in.bad () || in.fail ())
43+ {
44+ return std::unexpected (AudioBuffer::WAVLoadError::CannotOpen);
45+ }
46+
4247 in.read (buffer, 4 );
4348
4449 if (strncmp (buffer, " RIFF" , 4 ) != 0 )
4550 {
46- // "Error here, not a valid WAV file, RIFF not found in header\n This was found instead: "
47- return std::nullopt ;
51+ // RIFF not found in header
52+ return std::unexpected (AudioBuffer::WAVLoadError::RIFFNotFound) ;
4853 }
4954
5055 in.read (buffer, 4 );// size of file. Not used. Read it to skip over it.
5156 in.read (buffer, 4 );// Format, should be WAVE
5257 if (strncmp (buffer, " WAVE" , 4 ) != 0 )
5358 {
5459 // not a valid WAV file, RIFF not found in header
55- return std::nullopt ;
60+ return std::unexpected (AudioBuffer::WAVLoadError::RIFFNotFound) ;
5661 }
5762
5863 in.read (buffer, 4 );// Format Space Marker. should equal fmt (space)
5964
6065 if (strncmp (buffer, " fmt " , 4 ) != 0 )
6166 {
6267 // not a valid WAV file, Format Marker not found in header
63- return std::nullopt ;
68+ return std::unexpected (AudioBuffer::WAVLoadError::NoFormatMarker) ;
6469 }
6570
6671 in.read (buffer, 4 );// Length of format data. Should be 16 for PCM, meaning uncompressed.
6772
6873 if (convertToInt (buffer, 4 ) != 16 )
6974 {
7075 // not a valid WAV file, format length wrong in header
71- return std::nullopt ;
76+ return std::unexpected (AudioBuffer::WAVLoadError::WrongFormatLength) ;
7277 }
7378
7479 in.read (buffer, 2 );// Type of format, 1 = PCM
7580
7681 if (convertToInt (buffer, 2 ) != 1 )
7782 {
7883 // not a valid WAV file, file not in PCM format
79- return std::nullopt ;
84+ return std::unexpected (AudioBuffer::WAVLoadError::NotPCM) ;
8085 }
8186
8287 in.read (buffer, 2 );// Get number of channels.
@@ -97,7 +102,7 @@ std::optional<AudioBuffer> AudioBuffer::FromWAV(const std::filesystem::path& pat
97102 bps = convertToInt (buffer, 2 );
98103
99104 // Skip character data, which marks the start of the data that we care about.
100- in.read (buffer, 4 );// "data" chunk.
105+ in.read (buffer, 4 ); // "data" chunk.
101106
102107 in.read (buffer, 4 ); // Get size of the data
103108
@@ -106,10 +111,14 @@ std::optional<AudioBuffer> AudioBuffer::FromWAV(const std::filesystem::path& pat
106111 if (size < 0 )
107112 {
108113 // not a valid WAV file, size of file reports 0
109- return std::nullopt ;
114+ return std::unexpected (AudioBuffer::WAVLoadError::NullSize) ;
110115 }
111116
112117 char * data = new char [size];
118+ if (data == nullptr )
119+ {
120+ return std::unexpected (AudioBuffer::WAVLoadError::OutOfMemory);
121+ }
113122
114123 in.read (data, size);// Read audio data into buffer, return.
115124
@@ -118,29 +127,17 @@ std::optional<AudioBuffer> AudioBuffer::FromWAV(const std::filesystem::path& pat
118127 int format;
119128 if (channels == 1 )
120129 {
121- if (bps == 8 )
122- {
123- format = AL_FORMAT_MONO8 ;
124- }
125- else {
126- format = AL_FORMAT_MONO16 ;
127- }
130+ format = bps == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16 ;
128131 }
129132 else
130133 {
131- if (bps == 8 )
132- {
133- format = AL_FORMAT_STEREO8 ;
134- }
135- else {
136- format = AL_FORMAT_STEREO16 ;
137- }
134+ format = bps == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16 ;
138135 }
139136
140137 return AudioBuffer (data, channels, sampleRate, bps, format, size);
141138}
142139
143- std::optional <AudioBuffer> AudioBuffer::FromOGG (const std::filesystem::path& path)
140+ std::expected <AudioBuffer, AudioBuffer::OGGLoadError > AudioBuffer::FromOGG (const std::filesystem::path& path)
144141{
145142 // https://gist.github.com/tilkinsc/f91d2a74cff62cc3760a7c9291290b29
146143
@@ -150,21 +147,21 @@ std::optional<AudioBuffer> AudioBuffer::FromOGG(const std::filesystem::path& pat
150147 if (file == nullptr )
151148 {
152149 // Failed to open OGG file.
153- return std::nullopt ;
150+ return std::unexpected (AudioBuffer::OGGLoadError::CannotOpen) ;
154151 }
155152
156153 if (ov_open_callbacks (file, &vf, nullptr , 0 , OV_CALLBACKS_NOCLOSE ) < 0 )
157154 {
158155 // Not a valid OGG file.
159- return std::nullopt ;
156+ return std::unexpected (AudioBuffer::OGGLoadError::Invalid) ;
160157 }
161158
162159 vorbis_info* info = ov_info (&vf, -1 );
163160 if (info == nullptr )
164161 {
165162 // Failed to get OGG info
166163 ov_clear (&vf);
167- return std::nullopt ;
164+ return std::unexpected (AudioBuffer::OGGLoadError::InfoFail) ;
168165 }
169166 int channels = info->channels ;
170167 int sampleRate = info->rate ;
@@ -177,7 +174,7 @@ std::optional<AudioBuffer> AudioBuffer::FromOGG(const std::filesystem::path& pat
177174 {
178175 // Failed to allocate memory for OGG buffer
179176 ov_clear (&vf);
180- return std::nullopt ;
177+ return std::unexpected (AudioBuffer::OGGLoadError::OutOfMemory) ;
181178 }
182179
183180 for (size_t bytesRead = 0 , offset = 0 , sel=0 ; ; offset += bytesRead)
@@ -198,7 +195,7 @@ std::optional<AudioBuffer> AudioBuffer::FromOGG(const std::filesystem::path& pat
198195 // Faulty OGG file.
199196 delete[] buffer;
200197 ov_clear (&vf);
201- return std::nullopt ;
198+ return std::unexpected (AudioBuffer::OGGLoadError::Invalid) ;
202199 }
203200 }
204201 ov_clear (&vf);
0 commit comments