Author: roma
Update of /cvs/pkgs/rpms/fmtools/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv9100/F-12
Modified Files:
.cvsignore fmtools.spec import.log sources tkradio.py
Added Files:
fmlircrc
Log Message:
lirc and recording support
--- NEW FILE fmlircrc ---
# File: .fmlircrc
# Remote Control: Pixelview PlayTV MPEG2 PV-M4900 FM.RC
# Author: Paulo Roma on 28/12/2009
# Configuration file for fmtools-tkradio.
#
begin
prog = tkradio
button = power
config = quit
end
begin
prog = tkradio
button = ch+
config = next
end
begin
prog = tkradio
button = ch-
config = previous
end
begin
prog = tkradio
button = mute
config = off
end
begin
prog = tkradio
button = rec
config = rec
end
begin
prog = tkradio
button = stop
config = stop
end
begin
prog = tkradio
button = play
config = on
end
begin
prog = tkradio
button = vol+
config = volup
end
begin
prog = tkradio
button = vol-
config = voldown
end
begin
prog = tkradio
button = 1
config = 1
end
begin
prog = tkradio
button = 2
config = 2
end
begin
prog = tkradio
button = 3
config = 3
end
begin
prog = tkradio
button = 4
config = 4
end
begin
prog = tkradio
button = 5
config = 5
end
begin
prog = tkradio
button = 6
config = 6
end
begin
prog = tkradio
button = 7
config = 7
end
begin
prog = tkradio
button = 8
config = 8
end
begin
prog = tkradio
button = 9
config = 9
end
begin
prog = tkradio
button = 0
config = 0
end
Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/fmtools/F-12/.cvsignore,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- .cvsignore 27 Dec 2009 20:33:26 -0000 1.4
+++ .cvsignore 31 Dec 2009 14:50:40 -0000 1.5
@@ -1,2 +1,2 @@
-fmtools-2.0.tar.gz
fmcontrol.tar.gz
+fmtools-2.0.tar.gz
Index: fmtools.spec
===================================================================
RCS file: /cvs/pkgs/rpms/fmtools/F-12/fmtools.spec,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 -r1.11
--- fmtools.spec 27 Dec 2009 20:33:26 -0000 1.10
+++ fmtools.spec 31 Dec 2009 14:50:40 -0000 1.11
@@ -1,7 +1,7 @@
Summary: Simple Video for Linux radio card programs
Name: fmtools
Version: 2.0
-Release: 7%{?dist}
+Release: 8%{?dist}
License: GPLv2+
Group: Applications/Multimedia
URL:
http://www.stanford.edu/~blp/fmtools/
@@ -13,6 +13,7 @@ Source3:
http://www.stanford.edu/~blp/fm
Source4: fmtools.desktop
Source5: radio.png
Source6: tkradio.py
+Source7: fmlircrc
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
@@ -29,12 +30,13 @@ Summary: Python/Tk wrapper for fmt
Group: Applications/Multimedia
BuildRequires: desktop-file-utils
Requires: %{name} = %{version}
-Requires: python, tkinter, alsa-utils
+Requires: python, python-lirc, tkinter, alsa-utils
BuildArch: noarch
%description tkradio
-This package provides a GUI for %{name}.
-The stations are read from the same files used by fmcontrol.
+This package provides a GUI for %{name}, with lirc support.
+The stations are read from the same files used by fmcontrol,
+and the lirc configuration file is in $HOME/.fmlircrc
The script fmcontrol.py saves one from remembering frequencies
and volumes when using the "fm" program from %{name}.
@@ -66,6 +68,7 @@ desktop-file-install
%{SOURCE4}
install -Dpm 0644 %{SOURCE5} %{buildroot}%{_datadir}/pixmaps/radio.png
+install -Dpm 0644 %{SOURCE7} %{buildroot}%{_datadir}/%{name}/fmlircrc
%clean
rm -rf %{buildroot}
@@ -83,12 +86,17 @@ rm -rf %{buildroot}
%{_bindir}/fmcontrol.py
%{_datadir}/applications/fmtools.desktop
%{_datadir}/pixmaps/radio.png
+%{_datadir}/%{name}/fmlircrc
%changelog
+* Sun Dec 30 2009 Paulo Roma <roma(a)lcg.ufrj.br> 2.0-8
+- Added recording support.
+
* Sun Dec 27 2009 Paulo Roma <roma(a)lcg.ufrj.br> 2.0-7
- Replaced fmcontrol for fmcontrol.py
- Moved fmcontrol to tkradio package.
+- Added lirc support.
* Sun Dec 23 2009 Paulo Roma <roma(a)lcg.ufrj.br> 2.0-5
- Replaced BR tk for tkinter.
Index: import.log
===================================================================
RCS file: /cvs/pkgs/rpms/fmtools/F-12/import.log,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -p -r1.5 -r1.6
--- import.log 27 Dec 2009 20:33:26 -0000 1.5
+++ import.log 31 Dec 2009 14:50:40 -0000 1.6
@@ -3,3 +3,4 @@ fmtools-2_0-4_fc12:F-12:fmtools-2.0-4.fc
fmtools-2_0-5_fc12:F-12:fmtools-2.0-5.fc12.src.rpm:1261655654
fmtools-2_0-6_fc12:F-12:fmtools-2.0-6.fc12.src.rpm:1261758030
fmtools-2_0-7_fc12:F-12:fmtools-2.0-7.fc12.src.rpm:1261945933
+fmtools-2_0-8_fc12:F-12:fmtools-2.0-8.fc12.src.rpm:1262270955
Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/fmtools/F-12/sources,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- sources 27 Dec 2009 20:33:26 -0000 1.4
+++ sources 31 Dec 2009 14:50:40 -0000 1.5
@@ -1,2 +1,2 @@
-807467a8bccae32317c6bdb6c5329ab3 fmtools-2.0.tar.gz
8accad958c3f0cd0fb582aad922857aa fmcontrol.tar.gz
+807467a8bccae32317c6bdb6c5329ab3 fmtools-2.0.tar.gz
Index: tkradio.py
===================================================================
RCS file: /cvs/pkgs/rpms/fmtools/F-12/tkradio.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -p -r1.2 -r1.3
--- tkradio.py 24 Dec 2009 11:55:00 -0000 1.2
+++ tkradio.py 31 Dec 2009 14:50:40 -0000 1.3
@@ -1,49 +1,198 @@
#!/usr/bin/env python
-# Paulo Roma - simple tkinter interface for fmtools
+# Paulo Roma - simple tkinter interface for fmtools,
+# with lirc and recording support.
# Date: 23/12/2009
# The radio is turned off on exit.
from Tkinter import *
import Tkinter
-import os, sys
+import os, sys, string
+import datetime, time
+from threading import Thread
+try:
+ import pylirc
+except:
+ exit ( "pylirc not found:
http://pylirc.mccabe.nu/" )
# These are stations in the Rio de Janeiro area.
-# Customize for your own locale.
+# Customize for your own locale. They can be set
+# in file ~/.fmrc or ~/.radiostations:
+# station name, frequency and volume.
+
+stations = [["MPB", "90.3 100"],
+ ["CBN", "92.5 100"],
+ ["Band News", "94.9 100"],
+ ["Paradiso", "95.7 100"],
+ ["Tupy", "96.5 100"],
+ ["Beat98 FM", "98.0 100"],
+ ["MEC", "98.9 100"],
+ ["JB FM", "99.7 100"],
+ ["O Dia", "100.5 100"],
+ ["Transamerica", "101.3 100"],
+ ["Mix", "102.1 100"],
+ ["Oi", "102.9 100"],
+ ["Nativa", "103.7 100"]]
+
+radbut = stations[3][1] # default radio frequency
+volume = 100 # initial volume [0,100]
+state = False # keep track of mutting/unmutting
+blocking = 0 # lirc blocking control
+tid = 0 # recorder thread id
+fmrec = None # recorder thread variable
+irrec = None # lirc thread variable
+
+class IRRec(Thread):
+ """Class for interacting with lirc."""
+
+ def __init__ (self, lirc_handle):
+ """Constructor."""
+
+ Thread.__init__ (self)
+ self.lirc_handle = lirc_handle
+ self.__on = True
+
+ def stop ( self ):
+ """Kills this thread."""
+
+ self.__on = False
+
+ def run(self):
+ print "IRRrec awaits IR commands"
+
+ code = {"config" : ""}
+
+ while ( self.__on ):
+ # Delay...
+ time.sleep(1)
+
+ s = pylirc.nextcode(1)
+ while ( s ):
+ for code in s:
+ if ( code["config"] == "next" ):
+ next()
+ elif ( code["config"] == "previous" ):
+ previous()
+ elif ( code["config"] == "off" ):
+ mute()
+ elif ( code["config"] == "on" ):
+ radio ("on")
+ elif ( code["config"] == "volup" ):
+ volup ()
+ elif ( code["config"] == "voldown" ):
+ voldown()
+ elif ( code["config"] in "0123456789" ):
+ setStation ( int (code["config"]) )
+ elif ( code["config"] == "rec" ):
+ rec_on()
+ elif ( code["config"] == "stop" ):
+ rec_off()
+ elif ( code["config"] == "quit" ):
+ print "Not implemented yet, sorry..."
+ # self.stop()
+ else:
+ # Print all the configs...
+ print "Command: %s, Repeat: %d" %
(code["config"], code["repeat"])
+ if (not blocking):
+ s = pylirc.nextcode(1)
+ else:
+ s = []
+
+ # if we get here, the thread is over, so clean up lirc
+ pylirc.exit()
+
+class FMRec(Thread):
+ """Class for controlling the recording process."""
+
+ def __init__ (self):
+ """Constructor."""
+
+ Thread.__init__ (self)
+ self.__pid = 0 # arecord process id
+ self.__on = True # for implementing a thread stop,
+ # which python does not have
+ def __del__ (self):
+ """Destructor. Stops the recording, before
quitting."""
+
+ self.stop()
+
+ def stop ( self ):
+
+ """Stops the recording, by killing the recorder
process."""
+
+ global tid
+
+ tid = 0
+
+ if ( self.__pid ):
+ os.kill ( self.__pid, 9 )
+ self.__pid = 0
+ self.__on = False
+
+ def run(self):
+ """Start the thread."""
+
+ while (self.__on):
+ if ( not self.__pid ):
+ data = str(datetime.date.today())
+ hora = list(time.localtime(time.time()))
+ hora =
str(hora[3])+":"+str(hora[4])+":"+str(hora[5])
+ rec_file =
'/tmp/tkradio-'+fmstations[cur_station][0]+"-"+data+"-"+hora+'.wav'
+ lparam = ['/usr/bin/arecord', '-D', 'default',
'-d', '0', '-f', 'cd', rec_file]
+ self.__pid = os.spawnv (os.P_NOWAIT, "/usr/bin/arecord", lparam
)
+
+ time.sleep(1.0) # Suspend execution for the given number of seconds
-stations = [["MPB", "90.3"],
- ["CBN", "92.5"],
- ["Band News", "94.9"],
- ["PARADISO", "95.7"],
- ["Nativa", "96.5"],
- ["98 FM", "98.0"],
- ["MEC", "98.9"],
- ["JB FM", "99.7"],
- ["O Dia", "100.5"],
- ["Transamerica", "101.3"],
- ["Joven Pan", "102.1"],
- ["Oi", "102.9"],
- ["Antena1", "103.7"]]
-
-radbut = "95.7" # default radio frequency
-volume = 100 # initial volume [0,100]
-state = False
+ # if we get here, the thread is finished
+ self.stop ()
def radio ( cmd ):
"""Send the given command to the radio."""
os.system("fm "+cmd)
+def setCurStation ( frequency ):
+ """Update the current station."""
+
+ global cur_station
+
+ ind = 0
+ for st in fmstations:
+ if ( st[1] == frequency ):
+ cur_station = ind
+ break
+ ind += 1
+
def setstation():
- "Set the station chosen via Radio Button."""
+ """Set the station chosen via Radio Button."""
+
+ freq = station.get()
+ changeStation ( freq )
+ setCurStation ( freq )
+
+def setStation(ind):
+ """Set the station to ind."""
+
+ if ( ind >= 0 and ind < ns ):
+ freq = fmstations[ind][1]
+ changeStation ( freq )
+ setCurStation ( freq )
+
+def changeStation ( st ):
+ """Set the station to the given station."""
- radio ( station.get() )
+ radio ( st )
freq.delete(0, END)
- freq.insert(0,station.get())
+ freq.insert(0,st.split()[0])
+ station.set ( st )
def quit():
"""Quit the radio."""
radio ("off")
+ # kill all threads
+ if ( fmrec ): fmrec.stop()
+ if ( irrec ): irrec.stop()
+
sys.exit ( 0 )
def mute():
@@ -68,13 +217,31 @@ def on_move(value=0):
v = scale.get()
os.system("amixer -q -c 0 set PCM "+str(v)+"%")
+def volup ():
+ """Increases the volume."""
+
+ v = scale.get() + 5
+ if ( v > 100 ): v = 100
+ scale.set ( v )
+ os.system("amixer -q -c 0 set PCM "+str(v)+"%")
+
+def voldown():
+ """Decreases the volume."""
+
+ v = scale.get() - 5
+ if ( v < 0 ): v = 0
+ scale.set ( v )
+ os.system("amixer -q -c 0 set PCM "+str(v)+"%")
+
def enter ():
"Enter a new frequency."""
- radio (freq.get())
+ f = freq.get()+" "+ str(volume)
+ changeStation (f)
+ setCurStation (f)
def readStations ( ):
- """Read the station file."""
+ """Read the preset station file."""
path = os.environ.get("HOME")
fname = path+"/.radiostations"
@@ -87,19 +254,83 @@ def readStations ( ):
for line in textf:
l=line.split(None)
- st = [l[0].replace("_"," "),l[1]]
+ st = [l[0].replace("_"," "),l[1]+" "+l[2]]
lst.append ( st )
textf.close()
return lst
+def next ():
+ "Go to the next station."""
+
+ global cur_station
+ cur_station = (cur_station + 1) % ns
+ changeStation ( fmstations[cur_station][1] )
+
+def previous ():
+ "Go to the previous station."""
+
+ global cur_station
+ cur_station = (cur_station - 1) % ns
+ changeStation ( fmstations[cur_station][1] )
+
+def trigger ():
+ """Creates a thread for recording."""
+
+ global tid, fmrec
+
+ if ( not tid ):
+ fmrec = FMRec ()
+ fmrec.start()
+ tid = 1
+
+def rec():
+ """Record the current station."""
+
+ if ( recvar.get() == "ON" ):
+ rec_on()
+ else:
+ rec_off()
+
+def rec_on():
+ """Turn the recorder on."""
+
+ recvar.set ("ON")
+ trigger()
+
+def rec_off():
+ """Turn the recorder off."""
+
+ recvar.set ("OFF")
+ if ( fmrec ): fmrec.stop()
+
def main (argv=None):
"""Main program."""
- global scale, station, btmute, btm, freq
+ global scale # volume scale
+ global station # variable for the station radio buttons
+ global btmute # variable for the text in the mute button
+ global btm # mute button
+ global freq # variable for manually entering a frequency
+ global fmstations # preset fm stations
+ global cur_station # current station
+ global ns # number of preset fm stations
+ global recvar # variable for setting record on/off
+ global irrec # lirc thread variable
if argv is None:
argv = sys.argv
+ pyversion = string.split(sys.version)[0]
+ print "Python Version: ", pyversion
+
+ # check whether tkradio is already running
+ stat = os.popen ( "/bin/ps aux | /bin/grep \"python" + pyversion[0:3]
+ " " + argv[0] + "\"" ).readline()
+ cid = os.getpid()
+ if ( stat ):
+ pid = stat.split()[1]
+ if ( cid != int(pid) ):
+ exit ( argv[0] + " is already running: pid = " + pid )
+
mw = Tk()
# do not resize the radio
mw.resizable(False,False)
@@ -111,15 +342,18 @@ def main (argv=None):
btmute.set ( "Off" )
top = Frame(); top.pack()
+ bbt = Frame(); bbt.pack()
bot = Frame(); bot.pack()
mw.title ("tkradio")
- s = readStations ( )
- if ( not s ):
- s = stations
+ fmstations = readStations ( )
+ if ( not fmstations ):
+ fmstations = stations
+ ns = len ( fmstations )
+ cur_station = -1
# make tuner buttons
- for st in s:
+ for st in fmstations:
Radiobutton(bot,text=st[0],value=st[1],variable=station,command=setstation).pack(anchor=W)
scale = Scale(top, from_=0, to=100, orient=HORIZONTAL, command=on_move, bd=0,
@@ -128,13 +362,18 @@ def main (argv=None):
scale.set(volume)
# the current radio frequency
- Button(top,text="Enter", command = enter).pack(side="bottom")
+ Button(bbt,text="<", command =
previous).pack(side="left",anchor=E)
+ Button(bbt,text="Enter", command = enter).pack(side="left")
+ Button(bbt,text=">", command =
next).pack(side="left",anchor=W)
freq=Entry(top,font="Arial 24",width=5,justify=CENTER)
freq.insert(0,station.get())
freq.pack(side="bottom")
# create quit and mute buttons
Button(top,text="Exit", command = quit).pack(side="right")
+ recvar = StringVar() # creates a checkbutton for the alarm state
+ recvar.set ( "OFF" )
+ Checkbutton (top, text="Rec", variable=recvar, onvalue="ON",
offvalue="OFF", command=rec).pack(side="right")
btm=Button(top,text="Off", command = mute, textvariable = btmute)
btm.pack(side="left")
@@ -142,6 +381,19 @@ def main (argv=None):
setstation()
radio ("on")
+ lircid = os.popen ( '/sbin/pidof lircd' ).readline()
+ if ( lircid ): # is lirc running?
+ # handle lirc events
+ path = os.environ.get("HOME")
+ fname = path+"/.fmlircrc"
+ if ( not os.path.exists (fname) ):
+ fname = "/usr/share/fmtools/fmlircrc"
+ lirc_handle = pylirc.init("tkradio", fname, blocking)
+ if (lirc_handle):
+ print "Succesfully opened lirc, handle is " + str(lirc_handle)
+ irrec = IRRec(lirc_handle)
+ irrec.start()
+
top.mainloop()
try: