rpms/fmtools/F-12 fmlircrc, NONE, 1.1 .cvsignore, 1.4, 1.5 fmtools.spec, 1.10, 1.11 import.log, 1.5, 1.6 sources, 1.4, 1.5 tkradio.py, 1.2, 1.3

Paulo Roma Cavalcanti roma at fedoraproject.org
Thu Dec 31 14:50:40 UTC 2009


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 at lcg.ufrj.br> 2.0-8
+- Added recording support.
+
 * Sun Dec 27 2009 Paulo Roma <roma at 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 at 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:




More information about the scm-commits mailing list