Moode Audio Player for Raspberry Pi

I have recently purchased one of these:
<Stuff about="code" />: Raspberry Pi and KY040 Rotary Encoder

I am wondering if there is any way of adding support for this encoder to act as a volume control?

I tried knocking together an in-place replacement for the IQ_rot command. It seems to work. (Python script attached)

Since the dial only reports direction and not position, is there any reason for disabling the web interface's volume dial? It would be great to have the ability to use either method for adjusting the volume.

As an added bonus, I was able to have the push button toggle play/pause.

I am thinking about making it possible to use a long / double press to do other things. But if anyone has any suggestions for how I can tweak / improve the code, just shout.

Thanks
 

Attachments

  • ky040.py.txt
    2.4 KB · Views: 109
I have recently purchased one of these:
<Stuff about="code" />: Raspberry Pi and KY040 Rotary Encoder

I am wondering if there is any way of adding support for this encoder to act as a volume control?

I tried knocking together an in-place replacement for the IQ_rot command. It seems to work. (Python script attached)

Since the dial only reports direction and not position, is there any reason for disabling the web interface's volume dial? It would be great to have the ability to use either method for adjusting the volume.

As an added bonus, I was able to have the push button toggle play/pause.

I am thinking about making it possible to use a long / double press to do other things. But if anyone has any suggestions for how I can tweak / improve the code, just shout.

Thanks

Hi,

I'll add to the TODO list :)

email tim at moodeaudio dot org and I can provide modification that will enable the volume knob.

-Tim
 
Hi,

As the next Moode 2.6 update nears completion I'd like to mention that one of the new features is support for the Meridian Explorer 2 DAC including its hardware volume controller and MQA audio CODEC :)

This means that audio files encoded using MQA and MQA Studio format can be played using this DAC. Other audio devices that support MQA format may also work.

Many thanks to user MSimon for spending the time to work through the code changes to enable this exciting new capability.

Regards,
Tim
 

Attachments

  • mqa_logo.jpg
    mqa_logo.jpg
    10.9 KB · Views: 350
I have recently purchased one of these:
<Stuff about="code" />: Raspberry Pi and KY040 Rotary Encoder

I am wondering if there is any way of adding support for this encoder to act as a volume control?

I tried knocking together an in-place replacement for the IQ_rot command. It seems to work. (Python script attached)

Since the dial only reports direction and not position, is there any reason for disabling the web interface's volume dial? It would be great to have the ability to use either method for adjusting the volume.

As an added bonus, I was able to have the push button toggle play/pause.

I am thinking about making it possible to use a long / double press to do other things. But if anyone has any suggestions for how I can tweak / improve the code, just shout.

Thanks
Hi,

I'll add to the TODO list :)

email tim at moodeaudio dot org and I can provide modification that will enable the volume knob.

-Tim

Tim, I've been looking at other ways of generating up/down volume and selection signals besides switch-closing rotary encoders and I'm sure I'm not the only one pursuing Moode panel controls besides noonereallycares. I haven't had time this weekend to map out a proposal, but it would be nice if you could generalize your addition so it allows a user to link to one or more initialization functions (speaking unPythonic-ly) during configuration, rather than just to turn on or off an instance of the KY040 Python class. I realize this is opening a Pandora's Box and won't pout if you decide not to:)

noonereallycares, I have not used and am not familiar with the RPi Python GPIO class but stylistically, your code looks solid. Thanks for appending it.

Note added in edit: Anyone know how to strike through text on this board? I've had second thoughts the following. Better ignore for now. The trick in differentiating a long vs short press, of course, is to wait for the "long" amount of time after GPIO.FALLING is detected and look to see if the pin is still low. If low, it was a long press; if high, it was a short press. Act accordingly.

I don't know if RPi Python allows one to define an interrupt-driven timer. If not, I'd drop into C to define one so the long wait can be done efficiently, or even use a simple off-board electronic solution also triggered by the switch press.

Regards,
Kent
 
Last edited:
Last edited:
Tim, I've been looking at other ways of generating up/down volume and selection signals besides switch-closing rotary encoders and I'm sure I'm not the only one pursuing Moode panel controls besides noonereallycares. I haven't had time this weekend to map out a proposal, but it would be nice if you could generalize your addition so it allows a user to link to one or more initialization functions (speaking unPythonic-ly) during configuration, rather than just to turn on or off an instance of the KY040 Python class. I realize this is opening a Pandora's Box and won't pout if you decide not to:)

noonereallycares, I have not used and am not familiar with the RPi Python GPIO class but stylistically, your code looks solid. Thanks for appending it.

Note added in edit: Anyone know how to strike through text on this board? I've had second thoughts the following. Better ignore for now. The trick in differentiating a long vs short press, of course, is to wait for the "long" amount of time after GPIO.FALLING is detected and look to see if the pin is still low. If low, it was a long press; if high, it was a short press. Act accordingly.

I don't know if RPi Python allows one to define an interrupt-driven timer. If not, I'd drop into C to define one so the long wait can be done efficiently, or even use a simple off-board electronic solution also triggered by the switch press.

Regards,
Kent

Hi Kent,

For rotary encoder support I could provide an input field next to the ON/OFF slider that would contain the path to an encoder driver or script. User would be responsible for writing the driver or script.

As long as the script or driver calls vol.sh or vol.php to set the volume level, or alternatively performs the same operations as these scripts, Moode volume knob will be updated.

-Tim
 
After seeing all of the talk about artwork for albums, how do you remove it?
Using my mobile decide with the interface means scrolling down and I want to make the audio player as basic as possible

How would I remove the album cover info in Moode?

Hi,

Can you make some screen shots of your vision of simplified/basic UI for smartphone?

-Tim
 
it would be nice if you could generalize your addition so it allows a user to link to one or more initialization functions (speaking unPythonic-ly) during configuration, rather than just to turn on or off an instance of the KY040 Python class. I realize this is opening a Pandora's Box and won't pout if you decide not to:)

In effect, the IQ_rot is already a universal daemon which just sits there and waits for an input from somewhere. The code is what makes it specific to the IQaudio hardware.

This could make it possible for the same program to monitor any kind of button or dial you want to attach. The trick is just to modify the code in such a way as to understand the input and then act upon it.

I hope to have enough of a general coding skill set to hack together a C version of the code.

https://planb.nicecupoftea.org/2013/06/30/rotary-encoder-for-the-raspberry-pi/

This would be the base for the rotary encoding bit and then I just need to add the button press stuff.

Since the code simply calls the vol.php / vol.sh script for changing the volume, the button press stuff is the only missing link.

It may be possible to have a second daemon for monitoring a GPIO button. This would make it possible to have an API which lets the user select the action for each type of button press. In the same way that vol.php accepts 'up' and 'dn', it may be possible to have 'long', 'short' and 'double' as accepted types of presses.

e.g. a short press toggles between play and pause, while a double press will skips to the next track, and a long press will initiate a shutdown or simply stop playback.

While my code makes a direct call to mpc, the overheads of calling an intermediary API shouldn't add too much overhead.

Before I play with the code further, I hope to solder the required headers onto the PiFace Shim unit which is currently being used to expose the GPIO. Once I get that done, I'll start playing with the button stuff.

To begin with, I'll keep the code as an in-place replacement for IQ_rot. I will aim to make it extendable for any future uses. e.g. making IQ_rot a simple script which calls my daemon with command line switches that remove the need for hard coding the GPIO pins.
 
In effect, the IQ_rot is already a universal daemon which just sits there and waits for an input from somewhere. The code is what makes it specific to the IQaudio hardware.

This could make it possible for the same program to monitor any kind of button or dial you want to attach. The trick is just to modify the code in such a way as to understand the input and then act upon it.

I hope to have enough of a general coding skill set to hack together a C version of the code.

https://planb.nicecupoftea.org/2013/06/30/rotary-encoder-for-the-raspberry-pi/

This would be the base for the rotary encoding bit and then I just need to add the button press stuff.

Since the code simply calls the vol.php / vol.sh script for changing the volume, the button press stuff is the only missing link.

It may be possible to have a second daemon for monitoring a GPIO button. This would make it possible to have an API which lets the user select the action for each type of button press. In the same way that vol.php accepts 'up' and 'dn', it may be possible to have 'long', 'short' and 'double' as accepted types of presses.

e.g. a short press toggles between play and pause, while a double press will skips to the next track, and a long press will initiate a shutdown or simply stop playback.

While my code makes a direct call to mpc, the overheads of calling an intermediary API shouldn't add too much overhead.

Before I play with the code further, I hope to solder the required headers onto the PiFace Shim unit which is currently being used to expose the GPIO. Once I get that done, I'll start playing with the button stuff.

To begin with, I'll keep the code as an in-place replacement for IQ_rot. I will aim to make it extendable for any future uses. e.g. making IQ_rot a simple script which calls my daemon with command line switches that remove the need for hard coding the GPIO pins.

Hi,

Good idea to have Rotary encoder ON/OFF setting simply call a script that can then exec the IQ_rot or other driver, or call some other script.

I'll change code for next update so that it calls /var/www/command/encoder.sh. Something like that.

-Tim
 
I'll change code for next update so that it calls /var/www/command/encoder.sh. Something like that.

-Tim

I realise I am only a newbie to the forum, but I would suggest making the name as generic as 'gpio.sh' and then it can load both the IQ_rot and IQ_ir daemons from there.

e.g. I have another Pi running as an RF controller for the power points around my home. The config is done via a set of '.ini'-style config files such as:

Code:
[Socket7]
name = "Living Room"
icon = "kodi"
code = 3135500

[Socket1]
name = "Hackintosh"
icon = "tonymacx86"
code = 13578586

[Socket2]
name = "Printer"
icon = "clx3175fn"
code = 13578587

[Socket6]
name = "Living Room"
icon = "light"
code = 13578591

This makes it possible to add an unlimited number of devices. The code simply loads each section and then parses the section for the relevant settings.

While I don't expect the UI to offer the ability to edit such a file, would it be hard to have the UI offer a list of IO devices and then enable / disable a helper program?

e.g.

Code:
[IQ_rot]
enabled = 1
name = "IQaudio rotary encoder"
helper = "IQ_rot"

[IQ_ir]
enabled = 1
name = "IQaudio IR receiver"
helper = "IQ_ir"

[KY-040]
enabled = 0
name = "Arduino rotary encoder"
helper = "ky040_rot"
parameters = "--rot_gpio 5 --sw_gpio 6"

The UI would need only to enable / disable the device and the shell script could simply parse the config and load the helpers for any enabled devices.

The only code I have that uses this setup is a C program which loads some temperature sensors and the PHP code which displays the UI for the temperature sensors or the power controls. Neither are coded with the ability to edit the config file.

Side note: Due to a user error with a soldering iron, I'll have to wait until a replacement part arrives before I can resume tinkering with the GPIO ports on my Moode setup :(
 
Problem with Chrome on phone.
Chrome V51.0.2704.81
MoOde V2.6 2016-05-DD

Volume control is not released after making an adjustment. The next tap or side option on the screen (typically to view the playlist) causes the volume to track that tap.
This seems the same as the previous Firefox issue.
Chrome on Windows desktop does NOT exhibit the problem at V51.0.2704.106 m

J
 
Problem with Chrome on phone.
Chrome V51.0.2704.81
MoOde V2.6 2016-05-DD

Volume control is not released after making an adjustment. The next tap or side option on the screen (typically to view the playlist) causes the volume to track that tap.
This seems the same as the previous Firefox issue.
Chrome on Windows desktop does NOT exhibit the problem at V51.0.2704.106 m

J

Noticed the same issue with chrome on 2 android phone and an android tablet.
 
In effect, the IQ_rot is already a universal daemon which just sits there and waits for an input from somewhere. The code is what makes it specific to the IQaudio hardware.

This could make it possible for the same program to monitor any kind of button or dial you want to attach. The trick is just to modify the code in such a way as to understand the input and then act upon it.

I hope to have enough of a general coding skill set to hack together a C version of the code.

https://planb.nicecupoftea.org/2013/06/30/rotary-encoder-for-the-raspberry-pi/

This would be the base for the rotary encoding bit and then I just need to add the button press stuff.

Since the code simply calls the vol.php / vol.sh script for changing the volume, the button press stuff is the only missing link.

It may be possible to have a second daemon for monitoring a GPIO button. This would make it possible to have an API which lets the user select the action for each type of button press. In the same way that vol.php accepts 'up' and 'dn', it may be possible to have 'long', 'short' and 'double' as accepted types of presses.

e.g. a short press toggles between play and pause, while a double press will skips to the next track, and a long press will initiate a shutdown or simply stop playback.

While my code makes a direct call to mpc, the overheads of calling an intermediary API shouldn't add too much overhead.

Before I play with the code further, I hope to solder the required headers onto the PiFace Shim unit which is currently being used to expose the GPIO. Once I get that done, I'll start playing with the button stuff.

To begin with, I'll keep the code as an in-place replacement for IQ_rot. I will aim to make it extendable for any future uses. e.g. making IQ_rot a simple script which calls my daemon with command line switches that remove the need for hard coding the GPIO pins.

Basically agree. I got cold feet about my first musings because I hadn't thought through the various states of the press/release cycle and saw a flaw in my reasoning almost as soon as I pressed "Submit" . Interrupting on both the falling and rising edges (only after debouncing!) resolves my issue. Look at the bottom of raspberry pi - Time between button press and release in python? - Stack Overflow to see the basic outline of the Python approach I have in mind for the interrupts. Thanks again for pointing out the RPi.GPIO class.

Regards,
Kent
 
Hello,

I don`t want to take advantage of this tread, just wanna leave a short thank you here.
Everything I need is working well (Playback over USB, Spotify Connect, Tidal etc.) and
the sound is really impressing (in comparison to the costs).
Please keep up the good work. :)

Greetings
 
Last edited: