ogg decoder

This commit is contained in:
MihailRis
2024-02-28 13:22:33 +03:00
parent e3c2a1da52
commit 145ebf8468
5 changed files with 77 additions and 2 deletions
+4 -1
View File
@@ -7,6 +7,7 @@
#include "NoAudio.h"
#include "../coders/wav.h"
#include "../coders/ogg.h"
namespace audio {
static speakerid_t nextId = 1;
@@ -30,7 +31,9 @@ PCM* audio::loadPCM(const fs::path& file, bool headerOnly) {
std::string ext = file.extension().u8string();
if (ext == ".wav" || ext == ".WAV") {
return wav::load_pcm(file, headerOnly);
} // TODO: OGG support
} else if (ext == ".ogg" || ext == ".OGG") {
return ogg::load_pcm(file, headerOnly);
}
throw std::runtime_error("unsupported audio format");
}
+56
View File
@@ -0,0 +1,56 @@
#include "ogg.h"
#include <iostream>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include "../audio/audio.h"
#include "../typedefs.h"
static inline const char* vorbis_error_message(int code) {
switch (code) {
case 0: return "no error";
case OV_EREAD: return "a read from media returned an error";
case OV_ENOTVORBIS: return "bitstream does not contain any Vorbis data";
case OV_EVERSION: return "vorbis version mismatch";
case OV_EBADHEADER: return "invalid Vorbis bitstream header";
case OV_EFAULT: return "internal logic fault";
default:
return "unknown";
}
}
audio::PCM* ogg::load_pcm(const std::filesystem::path& file, bool headerOnly) {
OggVorbis_File vf;
int code;
if ((code = ov_fopen(file.u8string().c_str(), &vf))) {
throw std::runtime_error(vorbis_error_message(code));
}
std::vector<char> data;
vorbis_info* info = ov_info(&vf, -1);
uint channels = info->channels;
uint sampleRate = info->rate;
if (!headerOnly) {
const int bufferSize = 4096;
int section = 0;
char buffer[bufferSize];
bool eof = false;
while (!eof) {
long ret = ov_read(&vf, buffer, bufferSize, 0, 2, true, &section);
if (ret == 0) {
eof = true;
} else if (ret < 0) {
std::cerr << "ogg::load_pcm: " << vorbis_error_message(ret) << std::endl;
} else {
data.insert(data.end(), std::begin(buffer), std::end(buffer));
}
}
}
ov_clear(&vf);
return new audio::PCM(data, channels, 16, sampleRate);
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef CODERS_OGG_H_
#define CODERS_OGG_H_
#include <filesystem>
namespace audio {
struct PCM;
}
namespace ogg {
extern audio::PCM* load_pcm(const std::filesystem::path& file, bool headerOnly);
}
#endif // CODERS_OGG_H_