Moode Audio Player for Raspberry Pi

I understand the reasoning behind your approach (although I don't know how instantaneously your amp can respond). We just don't know enough about what causes the idle() method to return.

I'm volunteering at Project Reboot all day today (we refurbish computers for the poor and disabled) and don't have time to experiment, but if I did, I'd first try extending your code to test whether the state is "play" when the idle() method returns and, if not, to reenter the idle() method. Usual caveats about getting locked in a loop apply.

As an alternative, one might stick a probe into Tim's code to trigger when it detects the user has selected "play", but I'm a php noob.

Regards,
Kent

Hi Kent

Good suggestion. I'll dig into that and hopefully find something :)

Best Regards Max
 
The networking doesn't seem as robust in the latest version, I have been sharing an ethernet cable as a temp. work-around and just unplugging/replugging when needed. In the new version it now requires a hard reboot since it won't reactivate the interface. Not a biggie since few people would be doing this but thought I would mention it in any case.
 
Hi Tim!

Just have discovered a difference in behaviour between Pi 2 and Pi 3 with Moode.
Pi 3 doesn't want to power off an external HDD with 12V power supply. With Pi 2 it is done automatically after shutdown. So HDD- power supply has to be switched off on Pi 3. Not a big issue, but I think worth to mention.

Greetingz, Robert
 
Hi,

Issue was not that files couldn't be copied but how much free space was reported which would affect how many or how large a file could be copied.

-Tim

I enabled Expand SD Card storage... on mine 16gb sd, at the end of the process now i'm able to copy and move (even big) files directly from network, without the step about creating the network drive.
Is it possible this issue has to do with image dimension on sd card?
Thanks
 
I enabled Expand SD Card storage... on mine 16gb sd, at the end of the process now i'm able to copy and move (even big) files directly from network, without the step about creating the network drive.
Is it possible this issue has to do with image dimension on sd card?
Thanks

Hi,

I think its bug in Samba that causes it to report available space of root partition instead of USB disk when accessing the "USB" share. On a fresh Moode image /root only has about 200MB free.

-Tim
 
I understand the reasoning behind your approach (although I don't know how instantaneously your amp can respond). We just don't know enough about what causes the idle() method to return.

I'm volunteering at Project Reboot all day today (we refurbish computers for the poor and disabled) and don't have time to experiment, but if I did, I'd first try extending your code to test whether the state is "play" when the idle() method returns and, if not, to reenter the idle() method. Usual caveats about getting locked in a loop apply.

As an alternative, one might stick a probe into Tim's code to trigger when it detects the user has selected "play", but I'm a php noob.

Regards,
Kent

I just tried reading the status before calling the idle statement, and in all cases, when the player stops, the status returns stop as well, but still the client.idle statement skips the first time through the loop.

My thought initially was also, that there myst be some change happening, in the player subsystem of the mpd, since the idle statement skips the first call, but it doesn't seem to be the case.

Best Regards Max
 
I just tried reading the status before calling the idle statement, and in all cases, when the player stops, the status returns stop as well, but still the client.idle statement skips the first time through the loop.

My thought initially was also, that there myst be some change happening, in the player subsystem of the mpd, since the idle statement skips the first call, but it doesn't seem to be the case.

Best Regards Max

Sorry, I should have been more specific. It's not that the idle() method "skips the first time", it's that it returns because if has something to report (like ['playlist','play']).

I had in mind something like

Code:
if counter >= 4:
    while client.status()['state'] == 'stop':
        Id = client.idle()

A quick test here succeeds whether the player is in 'stop' or 'play' status when I start the script.

Good luck.

Regards,
Kent
 
I just tried reading the status before calling the idle statement, and in all cases, when the player stops, the status returns stop as well, but still the client.idle statement skips the first time through the loop.

My thought initially was also, that there myst be some change happening, in the player subsystem of the mpd, since the idle statement skips the first call, but it doesn't seem to be the case.

Best Regards Max

Hi,

Symptom suggests a bug in the library that provides "client.Idle".

An easy way to test MPD idle function is by using MPC on cmd line:

mpc idle (this should wait for change in any of MPD's subsystems)
mpc current (returns title of currently playing song, or if player is stopped, returns nothing)

-Tim
 
Hi Tim,

I observed a strange behaviour in moode's library view.

The artists Santana and Neil Young respectively released an album call 'Freedom'. When I click the particular artist-name under 'ARTISTS' in 'Library', then the album will be listed on both of them. Fine. But when I do a 'search albums' for 'Freedom' then it will be listed in one line as 'Freedom Various Artists'. I would expect two lines, one for each artist. There are many albums called 'Greatest Hits' which have this correct behavior.

I checked mp3-tags and file attributes but can't figure out, what's the problem. I.e. foobar2000 does now have a problem with that.

Do you have any ideas ?

Regards, Klaus
 
Sorry, I should have been more specific. It's not that the idle() method "skips the first time", it's that it returns because if has something to report (like ['playlist','play']).

I had in mind something like

Code:
if counter >= 4:
    while client.status()['state'] == 'stop':
        Id = client.idle()
A quick test here succeeds whether the player is in 'stop' or 'play' status when I start the script.

Good luck.

Regards,
Kent

Hi Kent

Code:
while Client.status()['state']=='stop':
            Id = Client.idle('player')
works great.

Although it has about 200% redundancy, apparently "redundancy can be used for good":D.

I'll post the finished script tomorrow, when I've polished it a bit.
 
Hi Tim,

I observed a strange behaviour in moode's library view.

The artists Santana and Neil Young respectively released an album call 'Freedom'. When I click the particular artist-name under 'ARTISTS' in 'Library', then the album will be listed on both of them. Fine. But when I do a 'search albums' for 'Freedom' then it will be listed in one line as 'Freedom Various Artists'. I would expect two lines, one for each artist. There are many albums called 'Greatest Hits' which have this correct behavior.

I checked mp3-tags and file attributes but can't figure out, what's the problem. I.e. foobar2000 does not have a problem with that.

Do you have any ideas ?

Regards, Klaus

Sorry, typo ...
 
Hi,

Symptom suggests a bug in the library that provides "client.Idle".

An easy way to test MPD idle function is by using MPC on cmd line:

mpc idle (this should wait for change in any of MPD's subsystems)
mpc current (returns title of currently playing song, or if player is stopped, returns nothing)

-Tim

Hey Tim

I seems like it could be a bug, but Kents suggestion works great, and since it is only one time the client.idle call fails, the script is still just as effective CPUwise.

I'll post the finished "standby" script tomorrow, when I've finished it.

Best regards
Max
 
Hi Tim,

I observed a strange behaviour in moode's library view.

The artists Santana and Neil Young respectively released an album call 'Freedom'. When I click the particular artist-name under 'ARTISTS' in 'Library', then the album will be listed on both of them. Fine. But when I do a 'search albums' for 'Freedom' then it will be listed in one line as 'Freedom Various Artists'. I would expect two lines, one for each artist. There are many albums called 'Greatest Hits' which have this correct behavior.

I checked mp3-tags and file attributes but can't figure out, what's the problem. I.e. foobar2000 does now have a problem with that.

Do you have any ideas ?

Regards, Klaus

Hi Klaus,

The code that displays content on the Library panel has a section that iterates through the sorted Album array and rolls up multiple occurrences of the same Album name into a single virtual compilation album with artist = "Various Artists". That code skips Albums with the common name "Greatest Hits".

I'm not familiar with foobar2000 but maybe its reading some sort of compilation tag in those files. The reason Moode handles compilation albums in the way described above is that there is no standard for compilation tag.

-Tim
 
Hi Klaus,

The code that displays content on the Library panel has a section that iterates through the sorted Album array and rolls up multiple occurrences of the same Album name into a single virtual compilation album with artist = "Various Artists". That code skips Albums with the common name "Greatest Hits".

I'm not familiar with foobar2000 but maybe its reading some sort of compilation tag in those files. The reason Moode handles compilation albums in the way described above is that there is no standard for compilation tag.

-Tim

Ok, but I think, fb2k only displays the tag information directly, without your special processing construction 'virtual compilation album'. BTW: The albums are no compilations. Why don't you wipe this code ? That would make it easier, to add an album to the playlist. Also the listing in 'ALBUMS' would be more clearly, like they is for the 'Greatest Hits' albums.

Regards, Klaus
 
Ok, but I think, fb2k only displays the tag information directly, without your special processing construction 'virtual compilation album'. BTW: The albums are no compilations. Why don't you wipe this code ? That would make it easier, to add an album to the playlist. Also the listing in 'ALBUMS' would be more clearly, like they is for the 'Greatest Hits' albums.

Regards, Klaus

Hi Klaus,

If I wipe the code what do I replace it with? Below are some MPD tag dumps from three compilation albums in my collection. As you can see there is no "compilation tag" in these files. ID3v2 has no standard tag for compilations.

-Tim

pi@rp1:~ $ telnet localhost 6600
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
OK MPD 0.19.0

lsinfo "NAS/Music/Compilations/Groove Salad, Volume 2/01 Ouranos.m4a"
file: NAS/Music/Compilations/Groove Salad, Volume 2/01 Ouranos.m4a
Last-Modified: 2016-02-26T21:40:30Z
Time: 347
Artist: Holmes Ives
Album: Groove Salad, Volume 2
Title: Ouranos
Track: 1/13
Genre: Alternative
Date: 2013
Disc: 1/1
AlbumArtist: Various Artists

lsinfo "NAS/Music/Compilations/Sunset Nights/01 Booster.m4a"
file: NAS/Music/Compilations/Sunset Nights/01 Booster.m4a
Last-Modified: 2014-12-05T12:54:37Z
Time: 205
Artist: Manzana
Album: Sunset Nights
Title: Booster
Track: 1/13
Genre: Electronica
Date: 2003
Disc: 1/1

lsinfo "NAS/Music/Compilations/On Canvas - Exhibition #1/01 Ocean Beach [Cybophonia Cenematic.m4a"
file: NAS/Music/Compilations/On Canvas - Exhibition #1/01 Ocean Beach [Cybophonia Cenematic.m4a
Last-Modified: 2014-12-05T12:54:25Z
Time: 525
Artist: The Black Mighty Orchestra
Album: On Canvas - Exhibition #1
Title: Ocean Beach [Cybophonia Cenematic Remix]
Track: 1/11
Genre: Electronica
Date: 2002
Composer: Cybophonia
Disc: 1/1
 
Hi Klaus,

...

I'm not familiar with foobar2000 but maybe its reading some sort of compilation tag in those files. The reason Moode handles compilation albums in the way described above is that there is no standard for compilation tag.

-Tim

ROFL! If you have a few hours, try using your favorite search engine to find hits on "how to tag your music library". There are at least a dozen tools and hundreds of opinions on how best to do it. And even for MP3, there are multiple "standards" defining the metadata container and the tag set within it, such as ID3v1, ID3v2.3, and ID3v2.4; IMHO, all inadequate. What a mess. Rubrics for using these tag sets which seem to work for pop music fail for classical music, yada, yada, yada. Collectives, whether composers, artists, groups (themselves collectives), works, etc, are the worst. One way or another, you find yourself forced to abuse the predefined tags and to be, shall we say, creative with the free-form extended tags.

Then, to add insult to injury, different popular players treat the tags differently.

I went crazy with this topic when I started ripping my legacy collection of hundreds of CDs, spread over a dozen genres. The more I ripped, the more problems I found with the rubric I started with. Like others before me, I ended up retagging en masse more than once.

To be frank, I was relieved to find how much of my previous work still make sense in Tim's Library frame. Not all of it, to be sure, but close enough.

Things could be worse. We could be forced to use a hierarchical file structure to account for the metadata. Uff da.

Regards,
Kent
 
Amplifier standby script for MoOde audioplayer

Here is my finished amplifier standby script for MoOde audioplayer.

This script is relevant for those who use MoOde as an AlwaysOnDevice with an external amplifier class A or AB and would like to be able to turn off the amplifier when MoOde is not playing.

Only caveat: If your amplifier has a speaker relay with a long delay, typically seen in newer class D amplifiers, there is a good chance that the script won’t work. Time your amplifier, is it takes more than 1 second before you hear the click, it probably won’t work well (the initial sound will be clipped when MoOde starts playing).

Requirements: MoOde device, amplifier and an external power relay for Raspberry Pi that can switch off the power to your amplifier.

The script uses the status of the mpd daemon, and checks once every minute, and if nothing has been playing for four minutes, the amplifier is turned off, and the script uses the idle command to wait for changes in the ‘player’ subsystem. As soon as MoOde starts playing, the script receives a change from idle and turns the amplifier on again, and so on.


The script probably works equally well on Rune Audio and Volumio, but I have only tested it on MoOde.

For the script to run, you need to install two packages (copy the link location):

https://pypi.python.org/pypi/python-mpd/
WGET https://pypi.python.org/packages/d3...0.tar.gz#md5=5b3849b131e2fb12f251434597d65635
(or which ever package suits your system)
tar -xvf python-mpd-0.3.0.tar.gz
cd python-mpd-0.3.0
python setup.py install

GPIO for python:
wget http://sourceforge.net/projects/rasp...zy-1_armhf.deb
dpkg -i python-rpi.gpio_0.6.2~wheezy-1_armhf.deb

Otherwise there is not much to it. If you don’t need the LED’s, just comment them out and if you want output remove comments from all print statements.
If you want the script to run at startup, put:

Code:
python /home/pi/ampcontroller.py &
in /etc/rc.local right before exit 0. If you do that, remember to comment out all the lines with print, otherwise you are going to completely junk your command prompt ;-).


Code:
# Import the libraries to use time delays, send os commands and access GPIO pins
import RPi.GPIO as GPIO 
import time 
import os 
import mpd 

# Setup Variables
RedLedPin = 13 # Set pin number for "Standby" LED
GreenLedPin = 15 # Set pin number for "ON" LED
MainRelayPin = 11 # Set pin number for relay output
counter = 0 # counter for determining the time that has passed since MoOde player has stopped
SleepTime = 60 # The delay between each Status check, set to 60 = 1 minute to save CPU 
StandbyTime = 4 # The amount of time before "Standby" defined in multiples of SleepTime: StandbyTime*SleepTime (60*4 = 240sec = 4 minutes)

# Setup GPIO pins
GPIO.setmode(GPIO.BOARD) # Set pin numbering to board numbering 
GPIO.setup(MainRelayPin, GPIO.OUT) # Setup pin MainRelayPin as an output 
GPIO.setup(RedLedPin, GPIO.OUT) # Setup pin RedLedPin as an output 
GPIO.setup(GreenLedPin, GPIO.OUT) # Setup pin GreenLedPin as an output 

# Setup MDPClient and connect to MPD on localhost
Client = mpd.MPDClient() # create client object 
while True:
    try:
        Client.connect("localhost", 6600) # connect to localhost:6600 
    except:
        continue
    break


# Set GPIO pins to their initial ON state
GPIO.output(MainRelayPin, GPIO.HIGH) 
GPIO.output(RedLedPin, GPIO.LOW) 
GPIO.output(GreenLedPin, GPIO.HIGH) 

# main loop
while True: # Setup a while loop to wait for a button press
    
    counter = counter + 1
    # print ("Checking MPD status! {0} seconds have passed since last MPD was last playing.".format((counter-1)*SleepTime))

    if Client.status()['state'] == "play":
        counter = 0
        # print ("MPD is Playing, Reseting counter to {0}".format(counter))

    if counter > StandbyTime:
        # print ("MPD has not been playing for {0} seconds! Entering standby!".format((counter-1)*SleepTime))
        
        # Set GPIO pins to standby state
        GPIO.output(MainRelayPin, GPIO.LOW)
        GPIO.output(GreenLedPin, GPIO.LOW)
        GPIO.output(RedLedPin, GPIO.HIGH)
        
        # wait for MPD to return Idle signaling that subsystem 'player' has changed
        # print "Waiting for Standby exit signal......."
        while Client.status()['state']=='stop':
            Id = Client.idle('player')
        # print "Standby exit signal received. Entering ON state"
        
        # Set GPIO pins to initial ON state
        GPIO.output(MainRelayPin, GPIO.HIGH)
        GPIO.output(RedLedPin, GPIO.LOW)
        GPIO.output(GreenLedPin, GPIO.HIGH)
        counter = 0

    time.sleep(SleepTime) # Allow a sleep time of SleepTime seconds to reduce CPU usage

# Close connection to MPD (not used since the main loop never exits)
Client.close() # send the close command
Client.disconnect() # disconnect from the server
Possible developments: the while loop that waits for client.idle could be replaced with a shutdown command. Then the script would work as an auto shutdown after a certain time, although I'm not sure if MoOde can do this alreaddy.
 

Attachments

  • ampcontroller.zip
    1.2 KB · Views: 41
Here is my finished amplifier standby script for MoOde audioplayer.

This script is relevant for those who use MoOde as an AlwaysOnDevice with an external amplifier class A or AB and would like to be able to turn off the amplifier when MoOde is not playing.

...

Klaus:

Nice to see you got it running. I hadn't thought about the auto-shutdown possibility.

A caution to others: there's at least one typo in the quoted code that isn't in the zip file. Don't copy and paste from the code window.

Regards,
Kent
 
Klaus:

Nice to see you got it running. I hadn't thought about the auto-shutdown possibility.

A caution to others: there's at least one typo in the quoted code that isn't in the zip file. Don't copy and paste from the code window.

Regards,
Kent

Wierd:confused: I just pasted it, but you are right, the loop arround the idle statement should be:
Code:
while Client.status()['state']=='stop':
            Id = Client.idle('player')
        # print "Standby exit signal received. Entering ON state"
I dont seem to be able to edit my previous post, so do as Kent says: "Use the atatchment".

Best Regards
Max (not Klaus:D)
 
Hello to all !

Is it possible to add a boot delay at startup ? I would add this feature because i have a single power on/off for all my audio stuff and the pi boots faster than the device (popcorn hour) on which there's a samba sharing. The issue is the samba sharing is not seen and mounted by the pi and i have to reboot the pi if i want to play music files that are on the samba sharing.
Thanks for your help.

Guillaume