Если вы разрабатываете Qt-приложение и хотите украсить его звуковыми эффектами, то вы попали по адресу, поскольку эта статья именно об этом. Однако рассматриваемая техника может быть обобщена и для более сложных мультимедийных приложений, но с некоторыми усовершенствованиями, которых мы в этот раз касаться не будем.
Разработаем простую библиотеку SoundPlayer
с использованием QSound
. Заголовочный файл soundplayer.h
:
#ifndef SOUNDPLAYER_H
#define SOUNDPLAYER_H
#include "soundplayer_global.h"
#include <QString>
class SOUNDPLAYERSHARED_EXPORT SoundPlayer {
public:
explicit SoundPlayer( const QString& fileName );
void play();
private:
QString m_fileName;
};
#endif // SOUNDPLAYER_H
Идея довольно проста. Объект SoundPlayer
принимает в конструкторе имя звукового файла. Воспроизведение файла происходит после вызова play()
. Посмотрим на реализацию в soundplayer.cpp
:
#include "soundplayer.h"
#include <QSound>
SoundPlayer::SoundPlayer( const QString& fileName ) :
m_fileName( fileName ) {
}
void SoundPlayer::play() {
if( QSound::isAvailable() ) {
QSound::play( m_fileName );
} else {
#ifdef Q_OS_LINUX
#endif
}
}
Все сводится к вызову функции-члена QSound::play()
, если QSound
поддерживается в текущей конфигурации системы.
Посмотрим на возможный вариант использования нашей библиотеки:
#include <QCoreApplication>
#include <QFile>
#include <soundplayer.h>
int main( int argc, char* argv[] ) {
QCoreApplication a(argc, argv);
static const QString SND_FILE_NAME = "sound.wav";
QFile out( SND_FILE_NAME );
if( !out.exists() ) {
QFile in( ":/sounds/" + SND_FILE_NAME );
in.open( QIODevice::ReadOnly );
out.open( QIODevice::WriteOnly );
out.write( in.readAll() );
out.close();
}
SoundPlayer player( SND_FILE_NAME );
player.play();
return a.exec();
}
Я поместил wav
-файл в ресурсы приложения. Однако QSound
не умеет работать с ресурсами напрямую. Поэтому нам приходится сохранять звуковой файл из ресурсов в некоторый каталог. Для простоты я делаю сохранение в текущий рабочий каталог, однако можно было бы воспользоваться каталогом temp
. Или вовсе хранить звуковые файлы в заранее заготовленном месте без использования ресурсов.
Представленный код хорошо работает Windows, но не все так хорошо под Linux (в других системах я тестирование не проводил, хотя в Mac OS пример должен работать, если верить документации). В Linux для работы QSound
требуется наличие Network Audio System (NAS)
. Типичный совет в этой ситуации сводится не к настройке NAS
, а к использованию Phonon
.
Расширим реализацию нашей библиотеки SoundPlayer
, добавив нужный код в блоках #ifdef Q_OS_LINUX … #endif
:
газовые трубопроводы. изготовление стальных резервуаров.
#ifndef SOUNDPLAYER_H
#define SOUNDPLAYER_H
#include "soundplayer_global.h"
#include <QString>
#ifdef Q_OS_LINUX
# include <phonon/MediaObject>
# include <phonon/AudioOutput>
#endif
class SOUNDPLAYERSHARED_EXPORT SoundPlayer {
public:
explicit SoundPlayer( const QString& fileName );
void play();
private:
QString m_fileName;
#ifdef Q_OS_LINUX
Phonon::MediaObject m_mediaObj;
Phonon::AudioOutput m_ao;
#endif
};
#endif // SOUNDPLAYER_H
И реализация:
#include "soundplayer.h"
#include <QSound>
SoundPlayer::SoundPlayer( const QString& fileName ) :
m_fileName( fileName ) {
#ifdef Q_OS_LINUX
Phonon::createPath( &m_mediaObj, &m_ao );
m_mediaObj.setCurrentSource( Phonon::MediaSource( m_fileName ) );
#endif
}
void SoundPlayer::play() {
if( QSound::isAvailable() ) {
QSound::play( m_fileName );
} else {
#ifdef Q_OS_LINUX
m_mediaObj.play();
#endif
}
}
Обратите внимание, что для успешной сборки и работы этого кода в системе должны быть установлены библиотеки phonon
, а также в pro
- файле проекта должно быть прописано:
linux-g++: QT += phonon
Использование Phonon
чуть более многословно, чем QSound
, но и возможности этой библиотеки намного обширней. Тем временем наш тестовый пример начал отлично работать как под Windows, так и под Linux. Теперь вы должны отчетливо слышать звуковой сигнал после запуска приложения.
Скачать пример использования QSound и Phonon для воспроизведения звуковых эффектов
Спасибо за отзыв =)
Когда будет новая статья ?
Здравствуйте, не волнуйтесь =) Новая статья выйдет на следующей неделе
Anonymous
Хорошая статья