Decoding with my own translation of libmad, loading and playback progress, next and prev songs
This commit is contained in:
parent
0e31c5fdf2
commit
e690d67b80
21 changed files with 290 additions and 11796 deletions
|
@ -3,12 +3,8 @@
|
|||
#include <mad.h>
|
||||
|
||||
M::Audio::Audio(W::Blob* p_file, const W::Address& addr, QObject* parent):
|
||||
File(p_file, addr, parent),
|
||||
frames()
|
||||
File(p_file, addr, parent)
|
||||
{
|
||||
W::Handler* requestFrames = W::Handler::create(address + W::Address({u"requestFrames"}), this, &M::Audio::_h_requestFrames);
|
||||
|
||||
addHandler(requestFrames);
|
||||
}
|
||||
|
||||
M::Audio::~Audio()
|
||||
|
@ -32,41 +28,18 @@ void M::Audio::initAdditional(const W::String& p_mime)
|
|||
|
||||
uint64_t length = 0;
|
||||
uint64_t tBits = 0;
|
||||
uint64_t amount = 0;
|
||||
while(stream.error != MAD_ERROR_BUFLEN) { //TODO handle other errors;
|
||||
|
||||
int success = mad_header_decode(&header, &stream);
|
||||
if (success == 0) {
|
||||
frames.emplace_back(stream.this_frame - stream.buffer, stream.next_frame - stream.this_frame);
|
||||
|
||||
amount++;
|
||||
length += header.duration.seconds * MAD_TIMER_RESOLUTION + header.duration.fraction;
|
||||
tBits += header.bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
additional.insert(u"duration", new W::Uint64(length / MAD_TIMER_RESOLUTION));
|
||||
additional.insert(u"bitrate", new W::Uint64(tBits / frames.size()));
|
||||
additional.insert(u"framesAmount", new W::Uint64(frames.size()));
|
||||
}
|
||||
|
||||
void M::Audio::h_requestFrames(const W::Event& ev)
|
||||
{
|
||||
const W::Vocabulary& vc = static_cast<const W::Vocabulary&>(ev.getData());
|
||||
const W::Uint64& index = static_cast<const W::Uint64&>(vc.at(u"index"));
|
||||
const W::Uint64& amount = static_cast<const W::Uint64&>(vc.at(u"amount"));
|
||||
|
||||
W::Vocabulary* evc = new W::Vocabulary();
|
||||
if (index + amount > frames.size()) {
|
||||
evc->insert(u"result", new W::Uint64(1));
|
||||
} else {
|
||||
evc->insert(u"result", new W::Uint64(0));
|
||||
W::Vector* vframes = new W::Vector();
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
const std::pair<uint64_t, uint64_t>& pair = frames[index + i]; //TODO optimize?
|
||||
vframes->push(file->slice(pair.first, pair.second));
|
||||
}
|
||||
|
||||
evc->insert(u"frames", vframes);
|
||||
}
|
||||
|
||||
response(evc, W::Address{u"responseFrames"}, ev);
|
||||
additional.insert(u"bitrate", new W::Uint64(tBits / amount));
|
||||
}
|
||||
|
|
|
@ -24,11 +24,6 @@ namespace M {
|
|||
|
||||
protected:
|
||||
void initAdditional(const W::String& p_mime) override;
|
||||
|
||||
handler(requestFrames);
|
||||
|
||||
private:
|
||||
std::deque<std::pair<uint64_t, uint64_t>> frames;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@ M::File::File(W::Blob* p_file, const W::Address& addr, QObject* parent):
|
|||
{
|
||||
W::Handler* get = W::Handler::create(address + W::Address({u"get"}), this, &M::File::_h_get);
|
||||
W::Handler* getAdditional = W::Handler::create(address + W::Address({u"getAdditional"}), this, &M::File::_h_getAdditional);
|
||||
W::Handler* getSlice = W::Handler::create(address + W::Address({u"getSlice"}), this, &M::File::_h_getSlice);
|
||||
|
||||
addHandler(get);
|
||||
addHandler(getAdditional);
|
||||
addHandler(getSlice);
|
||||
}
|
||||
|
||||
M::File::~File()
|
||||
|
@ -35,7 +37,7 @@ void M::File::initAdditional(const W::String& p_mime)
|
|||
{
|
||||
additional.clear();
|
||||
|
||||
additional.insert(u"size", new W::Uint64(file->size()));
|
||||
additional.insert(u"size", new W::Uint64(file->length()));
|
||||
additional.insert(u"mimeType", p_mime);
|
||||
}
|
||||
|
||||
|
@ -106,3 +108,21 @@ M::File * M::File::create(W::Blob* blob, const W::Address& addr, QObject* parent
|
|||
out->initAdditional(W::String(mime.toStdString()));
|
||||
return out;
|
||||
}
|
||||
|
||||
void M::File::h_getSlice(const W::Event& ev)
|
||||
{
|
||||
const W::Vocabulary& vc = static_cast<const W::Vocabulary&>(ev.getData());
|
||||
const W::Uint64& begin = static_cast<const W::Uint64&>(vc.at(u"begin"));
|
||||
const W::Uint64& size = static_cast<const W::Uint64&>(vc.at(u"size"));
|
||||
|
||||
W::Vocabulary* evc = new W::Vocabulary();
|
||||
if (begin > file->length() || begin + size > file->length()) {
|
||||
evc->insert(u"result", new W::Uint64(1));
|
||||
} else {
|
||||
evc->insert(u"result", new W::Uint64(0));
|
||||
evc->insert(u"slice", file->slice(begin, size));
|
||||
}
|
||||
|
||||
response(evc, W::Address{u"getSlice"}, ev);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace M {
|
|||
|
||||
handler(get);
|
||||
handler(getAdditional);
|
||||
handler(getSlice);
|
||||
|
||||
protected:
|
||||
W::Vocabulary additional;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue