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

View File

@ -89,6 +89,7 @@ if (WIN32)
find_package(glfw3 REQUIRED)
find_package(spng REQUIRED)
find_package(glm REQUIRED)
find_package(libogg REQUIRED)
set(PNGLIB spng::spng)
else()
find_package(Lua REQUIRED)
@ -118,7 +119,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
include_directories(${LUA_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${LIBS} glfw OpenGL::GL ${OPENAL_LIBRARY} GLEW::GLEW ZLIB::ZLIB ${PNGLIB} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
target_link_libraries(${PROJECT_NAME} ${LIBS} glfw OpenGL::GL ${OPENAL_LIBRARY} GLEW::GLEW ZLIB::ZLIB vorbis vorbisfile ${PNGLIB} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -21,6 +21,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
libpng-dev \
libopenal-dev \
libluajit-5.1-dev \
libvorbis-dev \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

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
src/coders/ogg.cpp Normal file
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
src/coders/ogg.h Normal file
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_