Move routines from oggopus to opus namespace
This commit is contained in:
parent
f3dd0ddc7d
commit
d610c305cf
4 changed files with 78 additions and 78 deletions
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue