101 lines
2.6 KiB
C++
101 lines
2.6 KiB
C++
/*
|
|
* Copyright 2003-2020 The Music Player Daemon Project
|
|
* http://www.musicpd.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "DecoderClient.hxx"
|
|
#include "pcm/Convert.hxx"
|
|
#include "input/InputStream.hxx"
|
|
#include "util/ConstBuffer.hxx"
|
|
|
|
ChromaprintDecoderClient::ChromaprintDecoderClient() = default;
|
|
ChromaprintDecoderClient::~ChromaprintDecoderClient() noexcept = default;
|
|
|
|
void
|
|
ChromaprintDecoderClient::Finish()
|
|
{
|
|
if (error)
|
|
std::rethrow_exception(error);
|
|
|
|
if (!ready)
|
|
throw std::runtime_error("Decoding failed");
|
|
|
|
if (convert) {
|
|
auto flushed = convert->Flush();
|
|
auto data = ConstBuffer<int16_t>::FromVoid(flushed);
|
|
chromaprint.Feed(data.data, data.size);
|
|
}
|
|
|
|
chromaprint.Finish();
|
|
}
|
|
|
|
void
|
|
ChromaprintDecoderClient::Ready(AudioFormat audio_format, bool,
|
|
SignedSongTime) noexcept
|
|
{
|
|
/* feed the first two minutes into libchromaprint */
|
|
remaining_bytes = audio_format.TimeToSize(std::chrono::minutes(2));
|
|
|
|
if (audio_format.format != SampleFormat::S16) {
|
|
const AudioFormat src_audio_format = audio_format;
|
|
audio_format.format = SampleFormat::S16;
|
|
|
|
convert = std::make_unique<PcmConvert>(src_audio_format,
|
|
audio_format);
|
|
}
|
|
|
|
chromaprint.Start(audio_format.sample_rate, audio_format.channels);
|
|
|
|
ready = true;
|
|
}
|
|
|
|
DecoderCommand
|
|
ChromaprintDecoderClient::SubmitData(InputStream *,
|
|
const void *_data, size_t length,
|
|
uint16_t) noexcept
|
|
{
|
|
if (length > remaining_bytes)
|
|
remaining_bytes = 0;
|
|
else
|
|
remaining_bytes -= length;
|
|
|
|
ConstBuffer<void> src{_data, length};
|
|
ConstBuffer<int16_t> data;
|
|
|
|
if (convert) {
|
|
auto result = convert->Convert(src);
|
|
data = ConstBuffer<int16_t>::FromVoid(result);
|
|
} else
|
|
data = ConstBuffer<int16_t>::FromVoid(src);
|
|
|
|
chromaprint.Feed(data.data, data.size);
|
|
|
|
return GetCommand();
|
|
}
|
|
|
|
size_t
|
|
ChromaprintDecoderClient::Read(InputStream &is,
|
|
void *buffer, size_t length) noexcept
|
|
{
|
|
try {
|
|
return is.LockRead(buffer, length);
|
|
} catch (...) {
|
|
error = std::current_exception();
|
|
return 0;
|
|
}
|
|
}
|