-
Notifications
You must be signed in to change notification settings - Fork 350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First implementation of the visualization
output plugin
#1910
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// SPDX-License-Identifier: BSD-2-Clause | ||
// author: Max Kellermann <[email protected]> | ||
|
||
#ifndef THREAD_ID_FORMATTER_HXX | ||
#define THREAD_ID_FORMATTER_HXX | ||
|
||
#include <fmt/format.h> | ||
#include <sstream> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please please please no iostreams in MPD! |
||
#include <thread> | ||
|
||
template<> | ||
struct fmt::formatter<std::thread::id> : formatter<string_view> | ||
{ | ||
template<typename FormatContext> | ||
auto format(std::thread::id id, FormatContext &ctx) const { | ||
std::stringstream stm; | ||
stm << id; | ||
return formatter<string_view>::format(stm.str(), ctx); | ||
} | ||
}; | ||
|
||
#endif // THREAD_ID_FORMATTER_HXX |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,28 @@ else | |
wasapi_dep = dependency('', required: false) | ||
endif | ||
|
||
libfftw3_dep = dependency('fftw3f', version: '>= 3.3.8', required: get_option('fftw3')) | ||
output_features.set('ENABLE_FFTW3', libfftw3_dep.found()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This macro is never used |
||
|
||
enable_visualization_output = get_option('visualization') | ||
conf.set('ENABLE_VISUALIZATION_OUTPUT', enable_visualization_output) | ||
|
||
output_features.set('ENABLE_VISUALIZATION_OUTPUT', get_option('visualization')) | ||
if get_option('visualization') | ||
if not libfftw3_dep.found() | ||
error('libfftw3 not available, but is required for the visualization plugin') | ||
endif | ||
output_plugins_sources += [ | ||
'visualization/VisualizationOutputPlugin.cxx', | ||
'visualization/SoundAnalysis.cxx', | ||
'visualization/SoundInfoCache.cxx', | ||
'visualization/VisualizationServer.cxx', | ||
'visualization/VisualizationClient.cxx', | ||
'visualization/Protocol.cxx', | ||
] | ||
output_plugins_deps += [ event_dep, net_dep, libfftw3_dep ] | ||
endif | ||
|
||
output_plugins = static_library( | ||
'output_plugins', | ||
output_plugins_sources, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
// Copyright The Music Player Daemon Project | ||
|
||
#ifndef LOW_LEVEL_PROTOCOL_HXX_INCLUDED | ||
#define LOW_LEVEL_PROTOCOL_HXX_INCLUDED | ||
|
||
#include "util/PackedBigEndian.hxx" | ||
|
||
#include <fftw3.h> | ||
|
||
#include <algorithm> | ||
#include <cstdint> | ||
#include <limits> | ||
|
||
namespace Visualization { | ||
|
||
/* Write a uint16_t to an output iterator over byte in wire format; return the | ||
* iterator in its new position | ||
*/ | ||
template <typename OutIter> | ||
OutIter | ||
SerializeU16(uint16_t n, OutIter pout) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason you decided to make this a template instead of just passing a |
||
auto m = PackedBE16(n); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird coding style. |
||
auto p = (std::byte*)(&m); | ||
return std::copy(p, p + 2, pout); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
} | ||
|
||
static_assert(std::numeric_limits<float>::is_iec559); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not clear why this line exists - if you move it into the function that relies on this assertion, it would be clearer. |
||
|
||
/* Convert an IEEE 754 single-precision floating-point number to wire format; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a |
||
* write it to an output iterator & return the iterator in its new position | ||
*/ | ||
template <typename OutIter> | ||
OutIter | ||
SerializeFloat(float f, OutIter pout) { | ||
auto m = PackedBE32(*(uint32_t*)&f); | ||
auto p = (std::byte*)(&m); | ||
return std::copy(p, p + 4, pout); | ||
} | ||
|
||
/* Convert an fftwf_complex to wire format; write it to an output iterator & | ||
* return the iterator in its new position | ||
*/ | ||
template <typename OutIter> | ||
OutIter | ||
SerializeComplex(const fftwf_complex c, OutIter pout) { | ||
auto r = PackedBE32(*(const uint32_t*)&(c[0])); | ||
auto i = PackedBE32(*(const uint32_t*)&(c[1])); | ||
Comment on lines
+47
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yet more undefined behavior here. Why are you not calling |
||
auto pr = (std::byte*)(&r); | ||
auto pi = (std::byte*)(&i); | ||
pout = std::copy(pr, pr + 4, pout); | ||
return std::copy(pi, pi + 4, pout); | ||
} | ||
|
||
} // namespace Visualization | ||
|
||
#endif // LOW_LEVEL_PROTOCOL_HXX_INCLUDED |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
// Copyright The Music Player Daemon Project | ||
|
||
#include "Protocol.hxx" | ||
|
||
#include "Log.hxx" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? |
||
#include "util/ByteOrder.hxx" | ||
#include "util/Domain.hxx" | ||
|
||
Visualization::ParseResult | ||
Visualization::ParseClihlo(void *data, | ||
size_t length, | ||
ClientHello &clihlo) noexcept { | ||
|
||
// CLIHLO payload is 6 bytes, header & footer are five more. | ||
if (length < sizeof(ClientHello) + 5) { | ||
return ParseResult::NEED_MORE_DATA; | ||
} | ||
|
||
uint8_t *buf = (uint8_t *)data; | ||
|
||
uint16_t msg_type = FromBE16(*(uint16_t *)buf); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cast is undefined behavior. |
||
if (msg_type != 0) { | ||
return ParseResult::ERROR; | ||
} | ||
|
||
buf += 2; | ||
uint16_t payload_len = FromBE16(*(uint16_t *)buf); | ||
if (payload_len != 6) { | ||
return ParseResult::ERROR; | ||
} | ||
|
||
buf += 2; | ||
clihlo.major_version = *buf++; | ||
clihlo.minor_version = *buf++; | ||
|
||
clihlo.requested_fps = FromBE16(*(uint16_t *)(buf)); | ||
buf += 2; | ||
clihlo.tau = FromBE16(*(int16_t *)(buf)); | ||
buf += 2; | ||
|
||
if (*buf != 0) { | ||
return ParseResult::ERROR; | ||
} | ||
|
||
return ParseResult::OK; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
??