diff --git a/debian/control b/debian/control index 8bea1b45..fd54fc34 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Build-depends: debhelper (>= 0.0.0), python:any, qtbase5-dev, qtconnectivity5-dev, + qtmultimedia5-dev, libi2c-dev:all, Standards-Version: 3.9.3 @@ -637,6 +638,7 @@ Package: nymea-plugin-pianohat Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, + libqt5multimedia5, nymea-plugins-translations, Description: nymea.io plugin for the Raspberry Pi Pianohat The nymea daemon is a plugin based IoT (Internet of Things) server. The diff --git a/pianohat/README.md b/pianohat/README.md new file mode 100644 index 00000000..1d697c5f --- /dev/null +++ b/pianohat/README.md @@ -0,0 +1,106 @@ +Pianohat on the Raspberry Pi 3 + +# Make sounds work + +In order to make the sounds work on the raspberry pi jack output you have to do following steps: + +- Add the sound module to the default modules + + $ echo "snd-bcm2835" | sudo tee -a /etc/modules + +- Run `raspi-config` + - `7 Advanced Options` + - `A4 Audio` + - `1 Force 3,5mm (headphone) jack` + +## Install pulseaudio + + $ apt update + $ apt install pulseaudio + +Create the systemd service: + + $ nano /lib/systemd/system/pulseaudio.service + +Insert folowing lines + + [Unit] + Description=PulseAudio Sound System + Before=sound.target + + [Service] + Type=simple + ExecStart=/usr/bin/pulseaudio --daemonize=no --system --realtime --log-target=journal + + [Install] + WantedBy=session.target + + +Configure pulseaudio for systemwide usage + + $ nano /etc/pulse/client.conf + +Add following configurations + + ... + default-server = /var/run/pulse/native + autospawn = no + +Add all users to the pulseaudio groups + + $ nano /etc/group + + ... + pulse:x:114:nymea,root + pulse-access:x:115:nymea,root + +Finally reboot the system + + +# Test audio + +Make sure your master PCM volume is up. You can do that using + + $ alsamixer + +You shoudl see follwoing audio outputs: + + $ aplay -L + + default + Playback/recording through the PulseAudio sound server + null + Discard all samples (playback) or generate zero samples (capture) + sysdefault:CARD=ALSA + bcm2835 ALSA, bcm2835 ALSA + Default Audio Device + dmix:CARD=ALSA,DEV=0 + bcm2835 ALSA, bcm2835 ALSA + Direct sample mixing device + dmix:CARD=ALSA,DEV=1 + bcm2835 ALSA, bcm2835 IEC958/HDMI + Direct sample mixing device + dsnoop:CARD=ALSA,DEV=0 + bcm2835 ALSA, bcm2835 ALSA + Direct sample snooping device + dsnoop:CARD=ALSA,DEV=1 + bcm2835 ALSA, bcm2835 IEC958/HDMI + Direct sample snooping device + hw:CARD=ALSA,DEV=0 + bcm2835 ALSA, bcm2835 ALSA + Direct hardware device without any conversions + hw:CARD=ALSA,DEV=1 + bcm2835 ALSA, bcm2835 IEC958/HDMI + Direct hardware device without any conversions + plughw:CARD=ALSA,DEV=0 + bcm2835 ALSA, bcm2835 ALSA + Hardware device with all software conversions + plughw:CARD=ALSA,DEV=1 + bcm2835 ALSA, bcm2835 IEC958/HDMI + Hardware device with all software conversions + +Finally test if the jack connected speaker works: + + $ aplay /usr/share/sounds/alsa/Front_Center.wav + + diff --git a/pianohat/pianohat.cpp b/pianohat/pianohat.cpp index 849c58b1..72c4c820 100644 --- a/pianohat/pianohat.cpp +++ b/pianohat/pianohat.cpp @@ -23,6 +23,8 @@ #include "pianohat.h" #include "extern-plugininfo.h" +#include + PianoHat::PianoHat(QObject *parent) : QObject(parent) { @@ -43,6 +45,63 @@ PianoHat::PianoHat(QObject *parent) : m_sensorTwo = new TouchSensor(0x2b, 27, 22, this); connect(m_sensorTwo, &TouchSensor::keyPressedChanged, this, &PianoHat::onSensorTwoKeyPressedChanged); + + foreach (const QAudioDeviceInfo &audioInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) { + qCDebug(dcPianohat()) << audioInfo.deviceName(); + } + + // Create sound effects + m_soundKeyC = new QSoundEffect(this); + m_soundKeyC->setVolume(1); + m_soundKeyC->setSource(QUrl::fromLocalFile(":/c1.wav")); + + m_soundKeyCSharp = new QSoundEffect(this); + m_soundKeyCSharp->setVolume(1); + m_soundKeyCSharp->setSource(QUrl::fromLocalFile(":/c1s.wav")); + + m_soundKeyD = new QSoundEffect(this); + m_soundKeyD->setVolume(1); + m_soundKeyD->setSource(QUrl::fromLocalFile(":/d1.wav")); + + m_soundKeyDSharp = new QSoundEffect(this); + m_soundKeyDSharp->setVolume(1); + m_soundKeyDSharp->setSource(QUrl::fromLocalFile(":/d1s.wav")); + + m_soundKeyE = new QSoundEffect(this); + m_soundKeyE->setVolume(1); + m_soundKeyE->setSource(QUrl::fromLocalFile(":/e1.wav")); + + m_soundKeyF = new QSoundEffect(this); + m_soundKeyF->setVolume(1); + m_soundKeyF->setSource(QUrl::fromLocalFile(":/f1.wav")); + + m_soundKeyFSharp = new QSoundEffect(this); + m_soundKeyFSharp->setVolume(1); + m_soundKeyFSharp->setSource(QUrl::fromLocalFile(":/f1s.wav")); + + m_soundKeyG = new QSoundEffect(this); + m_soundKeyG->setVolume(1); + m_soundKeyG->setSource(QUrl::fromLocalFile(":/g1.wav")); + + m_soundKeyGSharp = new QSoundEffect(this); + m_soundKeyGSharp->setVolume(1); + m_soundKeyGSharp->setSource(QUrl::fromLocalFile(":/g1s.wav")); + + m_soundKeyA = new QSoundEffect(this); + m_soundKeyA->setVolume(1); + m_soundKeyA->setSource(QUrl::fromLocalFile(":/a1.wav")); + + m_soundKeyASharp = new QSoundEffect(this); + m_soundKeyASharp->setVolume(1); + m_soundKeyASharp->setSource(QUrl::fromLocalFile(":/a1s.wav")); + + m_soundKeyB = new QSoundEffect(this); + m_soundKeyB->setVolume(1); + m_soundKeyB->setSource(QUrl::fromLocalFile(":/b1.wav")); + + m_soundKeyC2 = new QSoundEffect(this); + m_soundKeyC2->setVolume(1); + m_soundKeyC2->setSource(QUrl::fromLocalFile(":/c2.wav")); } void PianoHat::enable() @@ -59,11 +118,48 @@ void PianoHat::disable() m_sensorTwo->disableSensor(); } +void PianoHat::enableSounds(bool enable) +{ + m_soundsEnabled = enable; +} + void PianoHat::onSensorOneKeyPressedChanged(quint8 key, bool pressed) { // Map the bit number to the actual pianohat key Key pianoHatKey = static_cast(key); emit keyPressed(pianoHatKey, pressed); + + if (!m_soundsEnabled || !pressed) + return; + + switch (key) { + case KeyC: + m_soundKeyC->play(); + break; + case KeyCSharp: + m_soundKeyCSharp->play(); + break; + case KeyD: + m_soundKeyD->play(); + break; + case KeyDSharp: + m_soundKeyDSharp->play(); + break; + case KeyE: + m_soundKeyE->play(); + break; + case KeyF: + m_soundKeyF->play(); + break; + case KeyFSharp: + m_soundKeyFSharp->play(); + break; + case KeyG: + m_soundKeyG->play(); + break; + default: + break; + } } void PianoHat::onSensorTwoKeyPressedChanged(quint8 key, bool pressed) @@ -71,4 +167,27 @@ void PianoHat::onSensorTwoKeyPressedChanged(quint8 key, bool pressed) // Map the bit number to the actual pianohat key (bit + 8) Key pianoHatKey = static_cast(key + 8); emit keyPressed(pianoHatKey, pressed); + + if (!m_soundsEnabled || !pressed) + return; + + switch (pianoHatKey) { + case KeyGSharp: + m_soundKeyGSharp->play(); + break; + case KeyA: + m_soundKeyA->play(); + break; + case KeyASharp: + m_soundKeyASharp->play(); + break; + case KeyB: + m_soundKeyB->play(); + break; + case KeyHighC: + m_soundKeyC2->play(); + break; + default: + break; + } } diff --git a/pianohat/pianohat.h b/pianohat/pianohat.h index b2c38d03..eaea3dfd 100644 --- a/pianohat/pianohat.h +++ b/pianohat/pianohat.h @@ -1,6 +1,3 @@ -#ifndef PIANOHAT_H -#define PIANOHAT_H - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2018 Simon Stürz * @@ -23,12 +20,15 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#ifndef PIANOHAT_H +#define PIANOHAT_H + #include +#include #include "touchsensor.h" #include "plugin/device.h" - class PianoHat : public QObject { Q_OBJECT @@ -60,10 +60,28 @@ public: void enable(); void disable(); + void enableSounds(bool enable); + private: TouchSensor *m_sensorOne = nullptr; TouchSensor *m_sensorTwo = nullptr; + bool m_soundsEnabled = true; + + QSoundEffect *m_soundKeyC = nullptr; + QSoundEffect *m_soundKeyCSharp = nullptr; + QSoundEffect *m_soundKeyD = nullptr; + QSoundEffect *m_soundKeyDSharp = nullptr; + QSoundEffect *m_soundKeyE = nullptr; + QSoundEffect *m_soundKeyF = nullptr; + QSoundEffect *m_soundKeyFSharp = nullptr; + QSoundEffect *m_soundKeyG = nullptr; + QSoundEffect *m_soundKeyGSharp = nullptr; + QSoundEffect *m_soundKeyA = nullptr; + QSoundEffect *m_soundKeyASharp = nullptr; + QSoundEffect *m_soundKeyB = nullptr; + QSoundEffect *m_soundKeyC2 = nullptr; + signals: void keyPressed(const Key &key, bool pressed); diff --git a/pianohat/pianohat.pro b/pianohat/pianohat.pro index ee5b1e47..23e5bbab 100644 --- a/pianohat/pianohat.pro +++ b/pianohat/pianohat.pro @@ -2,6 +2,10 @@ include(../plugins.pri) TARGET = $$qtLibraryTarget(nymea_devicepluginpianohat) +QT += multimedia + +RESOURCES += sounds/sounds.qrc + SOURCES += \ devicepluginpianohat.cpp \ pianohat.cpp \ diff --git a/pianohat/sounds/LICENSE b/pianohat/sounds/LICENSE new file mode 100644 index 00000000..6bb8a291 --- /dev/null +++ b/pianohat/sounds/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/pianohat/sounds/a1.wav b/pianohat/sounds/a1.wav new file mode 100644 index 00000000..1c1ce146 Binary files /dev/null and b/pianohat/sounds/a1.wav differ diff --git a/pianohat/sounds/a1s.wav b/pianohat/sounds/a1s.wav new file mode 100644 index 00000000..d6d087d8 Binary files /dev/null and b/pianohat/sounds/a1s.wav differ diff --git a/pianohat/sounds/b1.wav b/pianohat/sounds/b1.wav new file mode 100644 index 00000000..05dcfea8 Binary files /dev/null and b/pianohat/sounds/b1.wav differ diff --git a/pianohat/sounds/c1.wav b/pianohat/sounds/c1.wav new file mode 100644 index 00000000..1370d679 Binary files /dev/null and b/pianohat/sounds/c1.wav differ diff --git a/pianohat/sounds/c1s.wav b/pianohat/sounds/c1s.wav new file mode 100644 index 00000000..7e916aba Binary files /dev/null and b/pianohat/sounds/c1s.wav differ diff --git a/pianohat/sounds/c2.wav b/pianohat/sounds/c2.wav new file mode 100644 index 00000000..9a1957f6 Binary files /dev/null and b/pianohat/sounds/c2.wav differ diff --git a/pianohat/sounds/d1.wav b/pianohat/sounds/d1.wav new file mode 100644 index 00000000..f82c97cd Binary files /dev/null and b/pianohat/sounds/d1.wav differ diff --git a/pianohat/sounds/d1s.wav b/pianohat/sounds/d1s.wav new file mode 100644 index 00000000..0110649c Binary files /dev/null and b/pianohat/sounds/d1s.wav differ diff --git a/pianohat/sounds/e1.wav b/pianohat/sounds/e1.wav new file mode 100644 index 00000000..41d25721 Binary files /dev/null and b/pianohat/sounds/e1.wav differ diff --git a/pianohat/sounds/f1.wav b/pianohat/sounds/f1.wav new file mode 100644 index 00000000..5b77cd09 Binary files /dev/null and b/pianohat/sounds/f1.wav differ diff --git a/pianohat/sounds/f1s.wav b/pianohat/sounds/f1s.wav new file mode 100644 index 00000000..7fe23c89 Binary files /dev/null and b/pianohat/sounds/f1s.wav differ diff --git a/pianohat/sounds/g1.wav b/pianohat/sounds/g1.wav new file mode 100644 index 00000000..963a6a76 Binary files /dev/null and b/pianohat/sounds/g1.wav differ diff --git a/pianohat/sounds/g1s.wav b/pianohat/sounds/g1s.wav new file mode 100644 index 00000000..04cad576 Binary files /dev/null and b/pianohat/sounds/g1s.wav differ diff --git a/pianohat/sounds/sounds.qrc b/pianohat/sounds/sounds.qrc new file mode 100644 index 00000000..a3a3536c --- /dev/null +++ b/pianohat/sounds/sounds.qrc @@ -0,0 +1,17 @@ + + + a1.wav + a1s.wav + b1.wav + c1.wav + c1s.wav + c2.wav + d1.wav + d1s.wav + e1.wav + f1.wav + f1s.wav + g1.wav + g1s.wav + +