INACTIVE PROJECT! Musikbeere (german for "music berry") is a script designed for playing music from a headless raspberry pi that is only controlled by four keys attached to GPIO pins.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

324 lines
7.6 KiB

#!/usr/bin/env ruby
require 'thread'
puts("SimplePlayer2 started!")
system("cd /music")
$musicFiles = Array.new(0)
$currentFileIndex = 0
$currentFileIndexSemaphore = Mutex.new()
$currentFile = ""
$configVolume = 75
$currentPlaybackPID = -1
$pidSemaphore = Mutex.new()
KEY_NEXT = 21
KEY_PREV = 4
KEY_FUNC = 17
KEY_USR1 = 22
class PlaybackConfiguration
def initialize()
@fileIntermission = 0.5
@mode = 0x03
end
end
class Configuration
def initialize()
end
end
#Config = Configuration.new()
#4 bits set the play mode:
BIT_REPEAT = 0 #sets repeat on(1)/off(0)
BIT_SHUFFLE = 1 #sets shuffle on(1)/off(0)
BIT_FILE = 2 #restrict to one file on(1)/off(0)
BIT_DIR = 3 #restrict to one directory on(1)/off(0)
#if BIT_FILE and BIT_DIR are not set, BIT_REPEAT and BIT_SHUFFLE apply to all files
#Examples:
#MSB .. LSB
#0011 = shuffle and repeat all files
#1001 = repeat one directory
#0101 = repeat one file
#1010 = shuffle one directory
def readConfig
#read configuration files
puts("Reading configuration...")
#$Config.playback = Object.new()
#hard coded:
$playbackFileIntermission = 0.5 #pause between files in seconds
$playbackMode = 0x03 #play all files infinite
$configVolume = 75 #default value
puts ("DONE!")
end
def setupHardware()
#setup keys
if(KEY_FUNC > 0)
system("echo \"#{KEY_FUNC}\" > /sys/class/gpio/export")
system("echo \"in\" > /sys/class/gpio/gpio#{KEY_FUNC}/direction")
end
if(KEY_NEXT > 0)
system("echo \"#{KEY_NEXT}\" > /sys/class/gpio/export")
system("echo \"in\" > /sys/class/gpio/gpio#{KEY_NEXT}/direction")
end
if(KEY_PREV > 0)
system("echo \"#{KEY_PREV}\" > /sys/class/gpio/export")
system("echo \"in\" > /sys/class/gpio/gpio#{KEY_PREV}/direction")
end
if(KEY_USR1 > 0)
system("echo \"#{KEY_USR1}\" > /sys/class/gpio/export")
system("echo \"in\" > /sys/class/gpio/gpio#{KEY_USR1}/direction")
end
#setiup display (TODO)
#setup sound card
system("amixer -q -c 0 set PCM,0 #{$configVolume.to_s()}%")
end
def collectPlaylist
#read files with matching file name extensions:
puts("Collecting playlist...")
$musicFiles = Dir.glob("/music/**/*.{ogg,oga,flac,spx,mka,mp3,mp2,aac,wma,wav}").sort()
puts ("DONE!")
end
def playbackControl()
puts("Starting infinite playback!")
while (true)
#for m in $musicFiles
#for i in 1..$musicFiles.length do
puts ("PLAYBACK_CONTROL: currentFileIndex = "+$currentFileIndex.to_s())
$currentFile = $musicFiles[$currentFileIndex]
#$musicFiles.each do |m|
puts("Playing "+$currentFile)
#everything supported by avplay
forked = -1
$pidSemaphore.synchronize {
$currentPlaybackPID = fork{ exec 'avplay','-v','0','-autoexit','-vn','-nodisp', $currentFile }
forked = $currentPlaybackPID
}
Process.wait(forked)
#end
$currentFileIndexSemaphore.synchronize {
if($currentFileIndex+1 == $musicFiles.length)
$currentFileIndex = 0
else
$currentFileIndex += 1
end
}
#sleep($Config.playback.fileIntermission)
sleep(0.5)
end
puts("SimplePlayer exited infinite playback loop!")
end
def settingsMenu()
puts "SETTINGS_MENU activated!"
puts "SETTINGS_MENU not yet implemented!"
puts "SETTINGS_MENU deactivated!"
end
def playbackMenu()
puts "PLAYBACK_MENU activated!"
sleep(0.2) #wait for the user to release keys
function = 0 #0 = track switch, 1 = directory switch
i = 0
while(i < 300) #go back to main menu when no key is pressed for 30 seconds
sleep(0.1)
case keysPressed()
when 2
i = 0
case function
when 0
puts "PLAYBACK_MENU: previous track"
#go to previous track
$currentFileIndexSemaphore.synchronize{
if($currentFileIndex <= 0)
#go to last file
$currentFileIndex = $musicFiles.length-2
else
$currentFileIndex -= 2
end
puts "PLAYBACK_MENU: $currentFileIndex = "+$currentFileIndex.to_s()
}
$pidSemaphore.synchronize{
if($currentPlaybackPID > 0)
Process.kill("TERM", $currentPlaybackPID)
$currentPlaybackPID = -1
end
}
when 1
puts "PLAYBACK_MENU: previous directory"
#go to previous directory
else
end
when 4
i = 0
case function
when 0
puts "PLAYBACK_MENU: next track"
#go to next track
$pidSemaphore.synchronize{
puts "PLAYBACK_MENU: killing child!"
if($currentPlaybackPID > 0)
Process.kill("TERM",$currentPlaybackPID)
$currentPlaybackPID = -1
end
}
when 1
puts "PLAYBACK_MENU: next directory"
#go to next directory
else
end
else
i += 1
end
end
puts "PLAYBACK_MENU: no key pressed for more than 30 seconds!"
puts "PLAYBACK_MENU: deactivated!"
end
def keyLock()
puts "KEY_LOCK: activated!"
puts "KEY_LOCK: hold F+U1 keys for 0.5 seconds to disable key lock!"
sleep(0.5)
i = 0
while(keysPressed() != 9) #F + U1
sleep(0.1)
end
while(keysPressed() == 9)
sleep(0.1)
i += 1
if (i > 5)
puts "KEY_LOCK: F+U1 keys were pressed for longer than 0.5 seconds, disabling KEY_LOCK!"
sleep(0.5)
return true
end
end
end
def keyPressed(key)
return (`cat /sys/class/gpio/gpio#{key}/value`.to_i() == 1 ) #true when key pressed, otherwise false
end
def keysPressed()
keyValue = 0
if(KEY_FUNC > 0)
keyValue += (`cat /sys/class/gpio/gpio#{KEY_FUNC}/value`.to_i()) #1 or 0
end
if(KEY_PREV > 0)
keyValue += (`cat /sys/class/gpio/gpio#{KEY_PREV}/value`.to_i()*2) #2 or 0
end
if(KEY_NEXT > 0)
keyValue += (`cat /sys/class/gpio/gpio#{KEY_NEXT}/value`.to_i()*4) #4 or 0
end
if(KEY_USR1 > 0)
keyValue += (`cat /sys/class/gpio/gpio#{KEY_USR1}/value`.to_i()*8) #8 or 0
end
#puts("KEYSPRESSED = ["+keyValue.to_s()+"]")
return keyValue
end
def watchKeys()
#simulate key combination "next file" every 10 seconds:
while(true)
while(keysPressed() == 0)
sleep(0.1)
end
#sleep(0.1) #to give the user some time to press another button -> delay sucks!
case keysPressed()
when 1
#enter playback menu
playbackMenu()
when 2
#previous/minus
#default action: volume -
if($configVolume > 0)
$configVolume -= 1
end
system("amixer -q -c 0 set PCM,0 #{$configVolume.to_s()}%")
when 4
if($configVolume < 100)
$configVolume += 1
end
system("amixer -q -c 0 set PCM,0 #{$configVolume.to_s()}%")
#next/plus
#default action: volume +
# while(keyPressed(KEY_NEXT))
# sleep(0.1)
# end
# #sleep( + $playbackFileIntermission)
#
# #next file event
# puts("REAL next file event!")
# $pidSemaphore.synchronize {
# if($currentPlaybackPID >= 0)
# Process.kill("TERM", $currentPlaybackPID)
# $currentPlaybackPID = -1
# end
# }
# puts("REAL next file event END!")
when 8
#user action
#power button:
puts "MAIN: Hold F2 for 2 seconds to shutdown!"
i=0
while(keyPressed(KEY_USR1))
sleep(0.1)
i += 1
end
if(i > 20) #if F2 key was pressed more than 2 seconds
puts "MAIN: F2 held for "+i.to_s()+"/10 Seconds!"
puts("MAIN: Shutting down!")
system("halt") #shutdown the system
else
settingsMenu()
end
when 9
#F + U1 key: enable key lock mode!
keyLock()
else
#nothing
end
end
end
readConfig()
setupHardware()
collectPlaylist()
playThread = Thread.new { playbackControl() }
watchKeys()
#playThread.start()
#watchThread.start()