19 .type = ElementType::AudioBox,
20 .group = ElementGroup::Output,
23 .canChangeAppearance =
true,
28 static_assert(
validate(constraints));
33 meta.pixmapPath = []{
return QStringLiteral(
":/Components/Output/AudioBox/audioboxOff.svg"); };
34 meta.titleText = QT_TRANSLATE_NOOP(
"AudioBox",
"Audio Box");
35 meta.translatedName = QT_TRANSLATE_NOOP(
"AudioBox",
"Audio Box");
36 meta.trContext =
"AudioBox";
37 meta.defaultAppearances = QStringList({
38 ":/Components/Output/AudioBox/audioboxOff.svg",
39 ":/Components/Output/AudioBox/audioboxOn.svg",
55 m_player =
new QMediaPlayer(
this);
56 m_audioOutput =
new QAudioOutput(
this);
64 if (audioPath.isEmpty()) {
73 const QString &path = audioPath;
74 if (!path.startsWith(
":/")) {
75 const QFileInfo info(path);
76 if (!info.exists() || !info.isReadable()) {
77 const QString reason = !info.exists()
78 ? tr(
"File does not exist")
79 : tr(
"File is not readable");
80 qCDebug(zero) <<
"Problem loading audio path:" << path;
81 throw PANDACEPTION(
"Couldn't load audio: %1 (%2)", path, reason);
85 m_audio.setFile(path);
92 const QUrl mediaUrl = path.startsWith(
":/")
94 : QUrl::fromLocalFile(path);
97 m_player->setAudioOutput(m_audioOutput);
98 m_player->setSource(mediaUrl);
99 m_player->setLoops(QMediaPlayer::Infinite);
109 return m_audio.filePath();
114 if (m_player->source().isEmpty()) {
132 m_audioOutput->setMuted(
m_muted);
138 const QString audioPath = m_audio.filePath();
139 if (!audioPath.isEmpty() && !audioPath.startsWith(
":/")) {
140 result.append(audioPath);
152 QMap<QString, QVariant> map;
157 if (!slim || !audioPath.startsWith(
":/")) {
158 map.insert(
"audiobox", audioPath);
161 map.insert(
"volume",
static_cast<double>(
m_volume));
188 if (map.contains(
"audiobox")) {
193 if (map.contains(
"volume")) {
195 const float vol = map.value(
"volume").toFloat(&ok);
Graphic element for the AudioBox (external audio file player) output.
Common logging utilities, the Pandaception error type, and helper macros.
#define PANDACEPTION(msg,...)
#define qCDebug(category)
Singleton factory for all circuit element types.
Self-registering element trait template and compile-time constraint validation.
ElementMetadata metadataFromConstraints(const ElementConstraints &c)
Converts ElementConstraints to an ElementMetadata with all constraint-derived fields set.
constexpr bool validate(const ElementConstraints &c)
Validates element constraints at compile time.
Enums::ElementType ElementType
Single, shared implementation of how an element's external-file reference (an appearance image,...
Abstract base class for all graphical circuit elements.
Port classes: Port (base), InputPort, and OutputPort.
Deserialization/serialization context structs passed through load()/save() call chains.
Circuit and waveform file serialization/deserialization utilities.
Named version predicates for file-format compatibility checks.
Audio output element that streams an external audio file when its input is logic-1.
AudioBox(QGraphicsItem *parent=nullptr)
Constructs an AudioBox element.
void load(QDataStream &stream, SerializationContext &context) override
void stopAudio() override
Stops hardware playback (called from stop() when m_hasOutputDevice is true).
void applyMute() override
Applies the current m_muted state to the hardware backend.
static constexpr const char * kDefaultAudioPath
void save(QDataStream &stream, SerializationOptions options) const override
void applyVolume() override
Applies the current m_volume to the hardware backend.
void startAudio() override
Starts hardware playback (called from play() when m_hasOutputDevice is true).
void setAudio(const QString &audioPath) override
Sets the audio source to audioPath and reloads the player.
QStringList externalFiles() const override
QString audio() const override
Returns the file path of the currently loaded audio file.
static constexpr float kDefaultVolume
void setVolume(float vol) override
Sets the audio playback volume to vol (0.0–1.0).
AudioOutputElement(ElementType type, QGraphicsItem *parent=nullptr, float initialVolume=kDefaultVolume)
static void registerCreator(ElementType type, std::function< GraphicElement *()> creator)
Registers a creator lambda for type, used by buildElement().
virtual QStringList externalFiles() const
virtual void load(QDataStream &stream, SerializationContext &context)
Loads the graphic element through a binary data stream.
virtual void save(QDataStream &stream, SerializationOptions options) const
static QString readBoundedString(QDataStream &stream)
Reads a QString from stream, refusing to allocate more bytes than remain in the stream (prevents OOM ...
static QMap< QString, QVariant > readBoundedMetadata(QDataStream &stream)
Reads the file-level metadata QMap<QString,QVariant> from stream without calling QList::reserve() wit...
std::optional< QString > forReading(const QString &storedValue, const QString &contextDir, SerializationPurpose purpose)
QString forWriting(const QString &path, SerializationPurpose purpose)
bool hasQMapFormat(const QVersionNumber &v)
V4.1: Format changed from flat binary to keyed QMap; port serial IDs; rotation fix.
bool hasAudio(const QVersionNumber &v)
V2.4: Audio element support (Buzzer, AudioBox).
Compile-time-validatable subset of ElementMetadata.
static ElementMetadata metadata()
static constexpr ElementConstraints constraints
static const bool registered
Self-registering element information trait.
Bundles all per-deserialization state so that load() overrides receive it through one explicit parame...
QVersionNumber version
File-format version read from the stream header.
SerializationPurpose purpose
What this deserialization is for; see SerializationPurpose.
QString contextDir
Directory of the .panda file (for relative path resolution).
Options passed to GraphicElement::save() (and friends); the save-side counterpart of SerializationCon...
SerializationPurpose purpose
What this serialization is for; see SerializationPurpose. Mandatory, no default.