File indexing completed on 2024-05-12 04:06:03

0001 /*
0002     SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KGAMESOUND_H
0008 #define KGAMESOUND_H
0009 
0010 // own
0011 #include "kdegames_export.h"
0012 // Qt
0013 #include <QObject>
0014 #include <QPointF>
0015 // Std
0016 #include <memory>
0017 
0018 class PlaybackEvent;
0019 
0020 /**
0021  * @class KGameSound kgamesound.h <KGameSound>
0022  *
0023  * This class models a sound file. Because it is implicitly added to this
0024  * application's KGameAudioScene, it can be played at different positions (if
0025  * positional playback is supported, see KGameAudioScene::capabilities()).
0026  *
0027  * Compared to many other media playback classes, the notable difference of
0028  * KGameSound is that one sound instance can be played multiple times at the
0029  * same point in time, by calling start() multiple times (possibly with
0030  * different playback positions). This behavior can be suppressed by calling
0031  * stop() before start().
0032  *
0033  * @note WAV files and Ogg/Vorbis files are guaranteed to work. Other audio
0034  *       files may also work, depending on the KGameAudio backend and its
0035  *       configuration.
0036  */
0037 class KDEGAMES_EXPORT KGameSound : public QObject
0038 {
0039     Q_OBJECT
0040     Q_DISABLE_COPY(KGameSound)
0041     Q_PROPERTY(KGameSound::PlaybackType playbackType READ playbackType WRITE setPlaybackType NOTIFY playbackTypeChanged)
0042     Q_PROPERTY(QPointF pos READ pos WRITE setPos NOTIFY posChanged)
0043     Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
0044 
0045 public:
0046     /// This enumeration describes how a sound can be played back
0047     enum PlaybackType {
0048         /// Positional playback disabled. The sound will appear at the same
0049         /// volume from every listener position, and will not appear to be
0050         /// coming from any direction. The pos() of this sound is ignored.
0051         AmbientPlayback = 1,
0052         /// Positional playback enabled. That means that the sound comes from
0053         /// a certain direction with a distance-depending volume. The pos()
0054         /// of this sound is given in absolute coordinates: Both direction
0055         /// and volume can change when the listener is moved.
0056         AbsolutePlayback,
0057         /// Positional playback enabled. That means that the sound comes from
0058         /// a certain direction with a distance-depending volume. The pos()
0059         /// of this sound is given in relative coordinates: The direction
0060         /// and volume do not depend on the listener's position. (In these
0061         /// relative coordinates, the listener is at the point of origin.)
0062         RelativePlayback
0063     };
0064 
0065     /**
0066      * Loads a new sound from the given @a file. Note that this is an
0067      * expensive operation which you might want to do during application
0068      * startup. However, you can reuse the same Sound instance for multiple
0069      * playback events.
0070      *
0071      * Since version 7.2.0 this constructor supports reading files from Qt
0072      * Resource System, @a file can be for example ":/sound.ogg".
0073      */
0074     explicit KGameSound(const QString &file, QObject *parent = nullptr);
0075     /// Destroys this KGameSound instance.
0076     ~KGameSound() override;
0077 
0078     /// @return whether the sound file could be loaded successfully
0079     bool isValid() const;
0080     /// @return the playback type for this sound
0081     KGameSound::PlaybackType playbackType() const;
0082     /// Sets the playback type for this sound. This affects how the sound
0083     /// will be perceived by the listener. The default is AmbientPlayback.
0084     ///
0085     /// @note Changes to this property will not be propagated to running
0086     ///       playbacks of this sound.
0087     /// @note Effective only if positional playback is supported.
0088     void setPlaybackType(KGameSound::PlaybackType type);
0089     /// @return the position of this sound
0090     QPointF pos() const;
0091     /// Sets the position of this sound. It depends on the playbackType() how
0092     /// this is position interpreted. See the KGameSound::PlaybackType
0093     /// enumeration documentation for details.
0094     ///
0095     /// @note Changes to this property will not be propagated to running
0096     ///       playbacks of this sound.
0097     /// @note Effective only if positional playback is supported.
0098     void setPos(QPointF pos);
0099     /// @return the volume of this sound
0100     qreal volume() const;
0101     /// Sets the volume of this sound. The default is 1.0, which means no
0102     /// volume change, compared to the original sound file. 0.0 means that
0103     /// the sound is inaudible.
0104     ///
0105     /// If you think of the KGameSound as a loudspeaker, the
0106     /// volume which is controlled by this method is what you regulate at its
0107     /// volume control. If positional playback is enabled (see
0108     /// playbackType()), this will not be the actual volume which the
0109     /// listener will perceive, because the playback volume decreases with
0110     /// increasing playback-listener distances.
0111     ///
0112     /// @note Changes to this property will not be propagated to running
0113     ///       playbacks of this sound.
0114     void setVolume(qreal volume);
0115 
0116     /// @returns whether loading or playing this sound failed
0117     ///
0118     /// See KGameAudioScene::hasError() for why you typically do not need to use
0119     /// this method.
0120     bool hasError() const;
0121 public Q_SLOTS:
0122     /// Starts a new playback instance of this sound. This will not interrupt
0123     /// running playbacks of the same sound or any other sounds.
0124     void start();
0125     /// @overload
0126     /// This overload takes an additional position argument which overrides
0127     /// the sound's pos() property.
0128     /// @note @a pos is respected only if positional playback is supported.
0129     void start(QPointF pos);
0130     /// Stops any playbacks of this sounds.
0131     void stop();
0132 Q_SIGNALS:
0133     void playbackTypeChanged(KGameSound::PlaybackType type);
0134     void posChanged(QPointF pos);
0135     void volumeChanged(qreal volume);
0136 
0137 private:
0138     friend class KGamePlaybackEvent;
0139     std::unique_ptr<class KGameSoundPrivate> const d_ptr;
0140     Q_DECLARE_PRIVATE(KGameSound)
0141 };
0142 
0143 #endif // KGAMESOUND_H