Move routines from oggopus to opus namespace

This commit is contained in:
Ilari Liusvaara 2013-12-19 19:31:13 +02:00
parent f3dd0ddc7d
commit d610c305cf
4 changed files with 78 additions and 78 deletions

View file

@ -1,13 +1,16 @@
#ifndef _library__oggopus__hpp__included__
#define _library__oggopus__hpp__included__
#ifndef _library__opus_ogg__hpp__included__
#define _library__opus_ogg__hpp__included__
#include "ogg.hpp"
#include <functional>
#include <cstdint>
#include "ogg.hpp"
namespace opus
{
/**
* OggOpus header structure.
*/
struct oggopus_header
struct ogg_header
{
uint8_t version;
uint8_t channels;
@ -18,54 +21,46 @@ struct oggopus_header
uint8_t streams;
uint8_t coupled;
uint8_t chanmap[255];
/**
* Parse Ogg packet as OggOpus header.
*
* Parameter pacekt: The packet to parse.
* Throws std::runtime_error: Not valid OggOpus header page.
*/
void parse(struct ogg::packet& packet) throw(std::runtime_error);
/**
* Serialize OggOpus header as an Ogg page.
*
* Returns: The serialized page.
* Throws std::runtime_error: Not valid OggOpus header packet.
*/
struct ogg::page serialize() throw(std::runtime_error);
};
/**
* OggOpus tags structure
*/
struct oggopus_tags
struct ogg_tags
{
std::string vendor;
std::vector<std::string> comments;
};
/**
* Parse Ogg packet as OggOpus header.
*
* Parameter pacekt: The packet to parse.
* Returns: Parsed data.
* Throws std::runtime_error: Not valid OggOpus header page.
*/
struct oggopus_header parse_oggopus_header(struct ogg::packet& packet) throw(std::runtime_error);
/**
* Serialize OggOpus header as an Ogg page.
*
* Parameter header: The header.
* Returns: The serialized page.
* Throws std::runtime_error: Not valid OggOpus header packet.
*/
struct ogg::page serialize_oggopus_header(struct oggopus_header& header) throw(std::runtime_error);
/**
* Parse Ogg packet as OggOpus comment.
*
* Parameter packet: The packet to parse.
* Returns: Parsed data.
* Throws std::runtime_error: Not valid OggOpus comment packet.
*/
struct oggopus_tags parse_oggopus_tags(struct ogg::packet& packet) throw(std::bad_alloc, std::runtime_error);
void parse(struct ogg::packet& packet) throw(std::bad_alloc, std::runtime_error);
/**
* Serialize OggOpus comments as Ogg pages.
*
* Parameter tags: The comments.
* Parameter output: Callback to call on each serialized page on turn.
* Parameter strmid: The stream id to use.
* Returns: Next sequence number to use.
* Throws std::runtime_error: Not valid OggOpus comments.
*/
uint32_t serialize_oggopus_tags(struct oggopus_tags& tags, std::function<void(const ogg::page& p)> output,
uint32_t strmid) throw(std::bad_alloc, std::runtime_error);
uint32_t serialize(std::function<void(const ogg::page& p)> output, uint32_t strmid)
throw(std::bad_alloc, std::runtime_error);
};
}
#endif

View file

@ -6,7 +6,7 @@
#include "library/serialization.hpp"
#include "library/string.hpp"
#include "library/ogg.hpp"
#include "library/oggopus.hpp"
#include "library/opus-ogg.hpp"
#include "library/opus.hpp"
#include "core/audioapi.hpp"
#include "core/command.hpp"
@ -443,8 +443,8 @@ out_parsing:
{
ogg::stream_reader_iostreams reader(data);
reader.set_errors_to(messages);
struct oggopus_header h;
struct oggopus_tags t;
struct opus::ogg_header h;
struct opus::ogg_tags t;
ogg::page page;
ogg::demuxer d(messages);
int state = 0;
@ -464,7 +464,7 @@ out_parsing:
d.packet_out(p);
switch(state) {
case 0: //Not locked.
h = parse_oggopus_header(p);
h.parse(p);
if(h.streams != 1)
throw std::runtime_error("Multistream OggOpus streams are not "
"supported");
@ -473,7 +473,7 @@ out_parsing:
gain = h.gain;
break;
case 1: //Expecting comment.
t = parse_oggopus_tags(p);
t.parse(p);
state = 2; //Data page.
if(page.get_eos())
throw std::runtime_error("Empty OggOpus stream");
@ -618,8 +618,8 @@ out:
{
if(!packets.size())
throw std::runtime_error("Empty oggopus stream is not valid");
oggopus_header header;
oggopus_tags tags;
opus::ogg_header header;
opus::ogg_tags tags;
ogg::stream_writer_iostreams writer(data);
unsigned stream_id = 1;
uint64_t true_granule = 0;
@ -639,10 +639,10 @@ out:
tags.comments.push_back((stringfmt() << "ENCODER=lsnes rr" + lsnes_version).str());
tags.comments.push_back((stringfmt() << "LSNES_STREAM_TS=" << s_timebase).str());
struct ogg::page hpage = serialize_oggopus_header(header);
struct ogg::page hpage = header.serialize();
hpage.set_stream(stream_id);
writer.put_page(hpage);
seq = serialize_oggopus_tags(tags, [&writer](const ogg::page& p) { writer.put_page(p); }, stream_id);
seq = tags.serialize([&writer](const ogg::page& p) { writer.put_page(p); }, stream_id);
struct ogg::page ppage;
ogg::muxer mux(stream_id, seq);

View file

@ -4,7 +4,7 @@
#include <cmath>
#include "library/minmax.hpp"
#include "library/ogg.hpp"
#include "library/oggopus.hpp"
#include "library/opus-ogg.hpp"
#include "library/string.hpp"
#include "core/window.hpp"
#include "state.hpp"
@ -67,7 +67,7 @@ namespace sky
}
}
void fill_msc_from_header(struct multistream_characteristics& c, const oggopus_header& h)
void fill_msc_from_header(struct multistream_characteristics& c, const opus::ogg_header& h)
{
c.channels = h.channels;
c.gain = h.gain;
@ -404,7 +404,8 @@ namespace sky
void song_buffer::parse_ogg_header(ogg::packet& p, subsong_context& ctx)
{
struct oggopus_header h = ::parse_oggopus_header(p);
struct opus::ogg_header h;
h.parse(p);
fill_msc_from_header(mscharacteristics[ctx.psid], h);
ctx.pregap = h.preskip;
ctx.gain = h.gain;
@ -412,7 +413,8 @@ namespace sky
void song_buffer::parse_ogg_tags(ogg::packet& p, subsong_context& ctx, const ogg::page& debug)
{
struct oggopus_tags t = ::parse_oggopus_tags(p);
struct opus::ogg_tags t;
t.parse(p);
for(auto& i : t.comments) {
try {
regex_results r = regex("SKY-([^-]+)-([^=]+)=(.*)", i);

View file

@ -1,11 +1,13 @@
#include "oggopus.hpp"
#include "opus-ogg.hpp"
#include <cstring>
#include "serialization.hpp"
#include "minmax.hpp"
struct oggopus_header parse_oggopus_header(struct ogg::packet& packet) throw(std::runtime_error)
namespace opus
{
struct oggopus_header h;
void ogg_header::parse(struct ogg::packet& packet) throw(std::runtime_error)
{
struct ogg_header h;
if(!packet.get_atomic())
throw std::runtime_error("OggOpus header page must have one complete packet");
if(packet.get_granulepos() != 0)
@ -47,12 +49,12 @@ struct oggopus_header parse_oggopus_header(struct ogg::packet& packet) throw(std
h.chanmap[0] = 0;
if(h.channels == 2) h.chanmap[1] = 1;
}
return h;
*this = h;
}
struct oggopus_tags parse_oggopus_tags(struct ogg::packet& packet) throw(std::bad_alloc, std::runtime_error)
void ogg_tags::parse(struct ogg::packet& packet) throw(std::bad_alloc, std::runtime_error)
{
struct oggopus_tags h;
struct ogg_tags h;
if(!packet.get_first_page() || !packet.get_last_page())
throw std::runtime_error("OggOpus tags packet must be alone on its pages");
if(packet.get_granulepos() != 0)
@ -84,36 +86,36 @@ struct oggopus_tags parse_oggopus_tags(struct ogg::packet& packet) throw(std::ba
h.comments.push_back(std::string(&p[oitr + 4], &p[itr]));
oitr = itr;
}
return h;
*this = h;
}
struct ogg::page serialize_oggopus_header(struct oggopus_header& header) throw(std::runtime_error)
ogg::page ogg_header::serialize() throw(std::runtime_error)
{
struct ogg::page page;
unsigned char buffer[276];
size_t bsize = 19;
if(header.version != 1)
if(version != 1)
throw std::runtime_error("Don't how to serialize this oggopus version");
if(!header.channels || (header.channels > 2 && !header.map_family))
if(!channels || (channels > 2 && !map_family))
throw std::runtime_error("Illegal channel count");
if(header.map_family && static_cast<int>(header.streams) > 255 - header.coupled)
if(map_family && static_cast<int>(streams) > 255 - coupled)
throw std::runtime_error("Maximum of 255 physical channels exceeded");
if(header.map_family)
for(unsigned i = 0; i < header.channels; i++)
if(header.chanmap[i] != 255 && header.chanmap[i] > header.streams + header.coupled)
if(map_family)
for(unsigned i = 0; i < channels; i++)
if(chanmap[i] != 255 && chanmap[i] > streams + coupled)
throw std::runtime_error("Logical channel mapped to invalid physical channel");
serialization::u64b(buffer, 0x4F70757348656164ULL);
buffer[8] = header.version;
buffer[9] = header.channels;
serialization::u16l(buffer + 10, header.preskip);
serialization::u32l(buffer + 12, header.rate);
serialization::s16l(buffer + 16, header.gain);
buffer[18] = header.map_family;
if(header.map_family) {
buffer[19] = header.streams;
buffer[20] = header.coupled;
memcpy(buffer + 21, header.chanmap, header.channels);
bsize = 21 + header.channels;
buffer[8] = version;
buffer[9] = channels;
serialization::u16l(buffer + 10, preskip);
serialization::u32l(buffer + 12, rate);
serialization::s16l(buffer + 16, gain);
buffer[18] = map_family;
if(map_family) {
buffer[19] = streams;
buffer[20] = coupled;
memcpy(buffer + 21, chanmap, channels);
bsize = 21 + channels;
} else
bsize = 19;
if(!page.append_packet(buffer, bsize))
@ -124,13 +126,13 @@ struct ogg::page serialize_oggopus_header(struct oggopus_header& header) throw(s
return page;
}
uint32_t serialize_oggopus_tags(struct oggopus_tags& tags, std::function<void(const ogg::page& p)> output,
uint32_t ogg_tags::serialize(std::function<void(const ogg::page& p)> output,
uint32_t strmid) throw(std::bad_alloc, std::runtime_error)
{
size_t needed = 8;
needed += tags.vendor.length();
needed += vendor.length();
needed += 4;
for(auto i : tags.comments)
for(auto i : comments)
needed += (i.length() + 4);
//TODO: Do without this buffer.
@ -138,12 +140,12 @@ uint32_t serialize_oggopus_tags(struct oggopus_tags& tags, std::function<void(co
contents.resize(needed);
size_t itr = 0;
serialization::u64b(&contents[0], 0x4F70757354616773ULL);
serialization::u32l(&contents[8], tags.vendor.length());
std::copy(tags.vendor.begin(), tags.vendor.end(), reinterpret_cast<char*>(&contents[12]));
itr = 12 + tags.vendor.length();
serialization::u32l(&contents[itr], tags.comments.size());
serialization::u32l(&contents[8], vendor.length());
std::copy(vendor.begin(), vendor.end(), reinterpret_cast<char*>(&contents[12]));
itr = 12 + vendor.length();
serialization::u32l(&contents[itr], comments.size());
itr += 4;
for(auto i : tags.comments) {
for(auto i : comments) {
serialization::u32l(&contents[itr], i.length());
std::copy(i.begin(), i.end(), reinterpret_cast<char*>(&contents[itr + 4]));
itr += (i.length() + 4);
@ -168,3 +170,4 @@ uint32_t serialize_oggopus_tags(struct oggopus_tags& tags, std::function<void(co
written = ptr - &contents[0];
}
}
}