pax_global_header00006660000000000000000000000064145436272270014526gustar00rootroot0000000000000052 comment=4a5bc99abc5e38545d0a658a2ed104271d6e302c autoradio-autoradio-3.6-4/000077500000000000000000000000001454362722700155135ustar00rootroot00000000000000autoradio-autoradio-3.6-4/.gitignore000066400000000000000000000003571454362722700175100ustar00rootroot00000000000000__pycache__ *.pyc *\# django.mo autoradio.sqlite3 autoplayer.xspf *~ build dist autoradio.egg-info man MANIFEST *.swf *.jar autoradio/programs/static/programs/playogg/js/*.js autoradio/programs/static/programs/playogg/swfobject/*.js media autoradio-autoradio-3.6-4/COPYING000066400000000000000000000431101454362722700165450ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. autoradio-autoradio-3.6-4/MANIFEST.in000066400000000000000000000006441454362722700172550ustar00rootroot00000000000000include COPYING include NEWS include README include TODO include *.txt include autoradio.wsgi global-include *.txt *.py *.sh *.in *.cfg *.json *.conf recursive-include doc * recursive-include locale *.po recursive-include templates * recursive-include global_static * recursive-include centos * recursive-include fedora * prune static prune amarok prune media prune debian prune autoradio.egg-info global-exclude *~ autoradio-autoradio-3.6-4/NEWS000066400000000000000000000070271454362722700162200ustar00rootroot00000000000000NEWS ---- * Wed Jan 15 2020 Paolo Patruno 3.3 - added shebang for python3 ; release 3.3 (p.patruno@iperbole.bologna.it) - release 3.2 for Debian (p.patruno@iperbole.bologna.it) - migrate to django 2.2 and python3 bugs (p.patruno@iperbole.bologna.it) - bug on debian install (default locale) and python3 refinements (root@localhost.localdomain) - ready for release 3.0 (p.patruno@iperbole.bologna.it) - ported player to python 3 (p.patruno@iperbole.bologna.it) - new migration for python3 (p.patruno@iperbole.bologna.it) - porting to python3 with futurize (p.patruno@iperbole.bologna.it) - sure you specify the proper version support in your setup.py file (p.patruno@iperbole.bologna.it) - new stable release for Debian (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno 2.8.9-1 - * Wed Feb 01 2017 Paolo Patruno 2.8.8-1 - standard spec file (ppatruno@arpa.emr.it) - bug in spec (ppatruno@arpa.emr.it) - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) version 2.8.2 ------------- * ported to django 1.6 version 2.8.1 ------------- * ported to django 1.5, gstreamer1, haxe 3.0 version 2.7.0 ------------- * now autoradio have an internal player based on python, dbus and gstreamer * autoradioweb now use dbus for the integrated player and autoradiod do not start thread for cherrypy web server version 2.6.1 ------------- * (bug corrected) firefox chrome etc. when upload files say different mime type * logo.gif file path was wrong in template version 2.6 ----------- * lot of bugs corrected * new config parameter to check presence of tags in file uploaded * now mysql with innodb (transaction) works well version 2.5 ----------- working version version 2.4 ----------- * file uplodated now are validated: new config parameter permit_no_playable_files (default = False): enclosure can be ogg 44100Hz only for best web player functionality; in all other cases files can be audio file mp3/ogg/flac version 2.3 ----------- * autoradiod now take in account audacious and audacious2 executables * changed SITE_MEDIA_PREFIX to MEDIA_SITE_PREFIX in config files * close bug on wrong path for static media * avoid to save enclosure without title, naming enclosure with auto part number version 2.2 ----------- * close bug on web player ( multiple windows on multiple enclosure) * close bug on web player ( do not play for media path error ) * close bug that don not show multiple enclosure for rss and atom feed * better site configuration * revisited look and feel of web ogg player (THANKS to Francesco Siviero !) version 2.1 ----------- * close bug autoradiod crash on playlist management - ID: 3388949 * a lot of new documentation * userguide in italian * player in podcast now is open in new windows using jquery version 2.0 ----------- The section program redesigned for podcasting: * a program now can have different part * programs now are available for podcasting * web interface for podcasting A palimpsest in pdf format available in italian law standard format Integrated ogg web player that is compatible with a great number of user's browser You can use audaucious2 for player The communication with player now use Dbus Compatible with cherrypython3 and Django 1.3 Tested and packaged for Fedora 15, Ubuntu 11.04, ubuntu server 11.04, debian 6.0.2 and testing. On line web documentation autoradio-autoradio-3.6-4/README000066400000000000000000000324221454362722700163760ustar00rootroot00000000000000= AutoRadio version 3.3 = https://github.com/pat1/autoradio OVERVIEW -------- Radio automation software. Simple to use, starting from digital audio files, manage on-air broadcasting over a radio-station or web-radio. The main components are: * Player (integrated or external Xmms/Audacious): plays all your media files and send digital sound to an audio device or audio server * Scheduler: real time manager for emission of special audio files like jingles, spots, playlist and programs; interact with player like supervisor User * interface: WEB interface to monitor the player and scheduler and admin the schedules for the complete control over your station format. The web interface allows you to easily publish podcasts that conform to the RSS 2.0 and iTunes RSS podcast specifications The web interface provide a "full compatible" ogg player. Developed with Python, Django, Dbus it works in an production enviroment FEATURES -------- * manage ogg, mp3, and other media file format managed by gstreamer * it's designed as client - server * manage playlists, inserting on it jingles, spots and programs * programmable rules for schedule and period schedule * do not overlap schedules: anticipate, postone or delete * player is monitored by web interface * spots are grouped and ordered by your preference * programs are available for podcasting in a very complete rss feed web interface * integrated web player for ogg vorbis that is very compatible with most user's systems * can produce a palimpsest and a printable version is available following the the italian law standard * integrated daemon system with logging * provide enhanced version of dir2ogg.py and mkplaylist.py to manage files with music (convert to ogg and make playlist) * do not use DataBases to manage music; you can use your preferred application to produce playlists * on line web documentation REQUIRES -------- autoradio requires: python >= 3.7 mutagen muatgen version >= 1.17 http://code.google.com/p/mutagen/ django http://www.djangoproject.com/ Suggested Django >= 2.2 configobj Summary : Config file reading, writing, and validation URL : http://www.voidspace.org.uk/python/configobj.html gstreamer Autoradio can use gstreamer 0.10 but is better to use gstreamer 1.0; the installed plugins establish the usable audio formats. OLD DISTRIBUTIONS ----------------- Autoradio try to work on very old distribution like fedora 8 with xmms and cherrypy2 On not so old distribution try to use audacious version >= 1.5 and cherypy3 python >= 2.5 cherrypy Summary : A pythonic, object-oriented web development framework URL : http://www.cherrypy.org/ Thera are incompatibility from cherrypy version 2 and 3 but autoradio works well with any version :) Player (xmms or audacious in alternative): for xmms player pyxmms http://people.via.ecp.fr/~flo/index.en.xhtml xmms http://www.xmms.org/ for audacious player version >= 1.5 dbus-python D-Bus Python Bindings http://www.freedesktop.org/software/dbus/ audacious http://audacious-media-player.org/ the player web server respond on port 8888 HOW TO INSTALL -------------- >>>>> Easy way: You can run autoradio daemon and web server from your root software distributed directory: python setup.py build change your preferred language and other preference in autoradio.cfg ./autoradioctrl --syncdb You have to answer to some question to setup database. ./autoradioweb run This start autoradio webserver on localhost port 8080 control+c to stop it if all works well you can detach it with ./autoradioweb restart ./autoplayerd run This start the player daemon and you can listen it if you have a sound card and loaded audio files control+c to stop it if all works well you can detach it with ./autoplayerd restart ./autoradiod run This start daemon autoradiod (that in old distribution can launch xmms/audacious ) control+c to stop it if all works well you can detach it with ./autoradiod restart ./autoplayergui This start the player GUI; with it you can load audio file/playlists and manage audio player You have to use a browser (on the same machine) pointing to http://localhost:8080 >>>>> Installed way: you need access to root administrator user and after: python setup.py install choose a normal user to run the daemons and create it and login, make and go in your preferred user working writable directory modify /etc/autoradio/autoradio-site.cfg or from the normal user copy it in your working directory with name autoradio.cfg and modify it specify your personal settings for installed files if you want you can set user's global settings coping configuration file in ~/.autoradio.cfg after from root: autoradioctrl --syncdb --changeuser autoradioweb restart You can run autoradiod and autoplayerd in one host and autoradioweb in other if you use server Data Base like mysql and specify it and where autoradiod is running in the autoradio configuration (.cfg) files. The /usr/share/autoradio of the machine where run autoradioweb will be accessible read (and write) from machine where run autoradiod. In addition to do this you have to have a tcp enabled version of dbus running autoradiodbusd somewhere. On machine where you want run autoradiod (the player side), after autoradio installation, from root user create a new user and set password and activate interactive login like this: useradd autoradio passwd autoradio usermod -s /bin/bash autoradio login in autoradio user in a X (graphics) session and: autoradiod run or autoradiod restart For a pubblic web server do not use django internal web server: autoradioweb stop but use apache instead: https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/ you can find an example configuration file in doc directory: doc/apache_modwsgi_example.conf set SERVE_STATIC=False in /etc/autoradio-site.cfg >>>> Pachaged way: for Fedora Centos and Debian/Ubuntu you have the possibility to install from pachages in a easy way. For Debian/Ubuntu you can find autoradio in standard distribution. For Fedora use copr repo at https://copr.fedorainfracloud.org/coprs/pat1/autoradio/ The pachage create the autoradio user for you and set everything in a standard way for an easy use. To start everythings from root user (prepend sudo command for Ubuntu): autoradioctrl --syncdb --changeuser autoradioweb restart You can run autoradiod and autoplayerd in one host and autoradioweb in other if you use server Data Base like mysql and specify it and where autoradiod is running in the autoradio configuration (.cfg) files. The /usr/share/autoradio of the machine where run autoradioweb will be accessible read (and write) from machine where run autoradiod. On machine where you want run autoplayerd (the player side), after autoradio installation, from root user create a new user and if you want activate interactive login like this: useradd autoradio passwd autoradio usermod -s /bin/bash autoradio login in autoradio user in a X (graphics) session and: autoradiod run or autoradiod restart If you want you can activate monit daemon to control autoradio daemons; an example conf file to add to monit is in: doc/monit_autoradio_example.conf For a pubblic web server do not use django internal web server: autoradioweb stop and use apache instead: http://docs.djangoproject.com/en/dev/howto/deployment/modpython/#howto-deployment-modpython you can find an example configuration file in doc directory: doc/apache_mod_python_example.conf set SERVE_STATIC=False in /etc/autoradio-site.cfg HOW IT WORKS ------------ In player's playlist you need a queue of media for a minumun of some hours and for this you have to program some playlist. Player cannot stay stopped or paused (if stopped it will be started, if paused it stay paused) for a corret work. When time will be right jingle, programs and spots will be placed in playlist the first position after the last file inserted before by autoradiod HOT TO USE IT ------------- autoradioctrl provide some administration commands like --sincdb to inizialite the data base. autoradioweb or other web serber like apache provide a web interface to program every thinks you cannot find in configuration files; you have to run it like a permanent daemon; use a browser pointing it at the machine and port of the web server (http://localhost:8080 is the default for autoradioweb). Run autoplayerd to start to play music. You need an audio card. You can run autoradiod to start the automation of the player; autoradiod manage the player with the programmed schedules. You can run autoplayerd/autoradiod from the same machine where run auroradioweb; it use sqlite local file. If you use a database client/server like mysql you can access the DB from an other machine but you have to read the media files from all machines involved (with nfs services). Where you have an X server you can run autoplayergui to interact with graphical interface with the player. Read doc/user_guide.txt or the documentation in the web admin interface for the features enabled in the autoradio suite. CONTRIBUTED SOFTWARE -------------------- module daemon come from http://www.livinglogic.de/Python/index.html ## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany. ## Copyright 2007-2009 by Walter Drwald ## OSI Approved :: MIT License module mkplaylist come from http://bj.spline.de/mkplaylist-man.html # Author: Marc 'BlackJack' Rintsch # Copyright: (c) 2004-2009 # Licence: GPL module dir2ogg come from http://jak-linux.org/projects/dir2ogg/ # Copyright (C) 2007-2009 Julian Andres Klode # Copyright (C) 2003-2006 Darren Kirby # Licence: GPL django-podcast http://code.google.com/p/django-podcast/ https://github.com/jefftriplett/django-podcast # Copyright (c) 2008, django-podcast Project Members # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the django-podcast Project nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. SWFObject v2.2 is released under the MIT License jQuery JavaScript Library v1.4.1 http://jquery.com/ Copyright 2010, John Resig Dual licensed under the MIT or GPL Version 2 licenses. http://jquery.org/license Includes Sizzle.js http://sizzlejs.com/ Copyright 2010, The Dojo Foundation Released under the MIT, BSD, and GPL Licenses. jquery Open Window plugin http://plugins.jquery.com/project/open GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Cortado - a video player java applet Copyright (C) 2004 Fluendo S.L. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. anoggplayer http://code.google.com/p/anoggplayer/ GNU LESSER GENERAL PUBLIC LICENSE fogg http://bazaar.launchpad.net/~arkadini/fogg/trunk GNU LESSER GENERAL PUBLIC LICENSE ---------------------------------------------------------------------------- Italiano: Autoradio una suite di programmi che partendo da file audio digitali permette la gestione automatica dell'emissione di una stazione radiofonica. queste sono le componenti: * Player: partendo da una playlist in grado di gestire differenti formati di audio digitali per poi inviare il suono o a una scheda audio o a un server audio * Scheduler: gestisce in tempo reale l'emissione di particolari file o audio quali i jingles, pubblicit, playlist e programmi; interagisce col player controllandolo e impartendo comandi * L'intefaccia utente: utilizzando una interfaccia WEB pemette il monitoraggio dello scheduler e del player e permette la programmazione del palinsesto. L'interfaccia web permette anche di pubblicare facilmente podcasts conforme alle specifiche RSS 2.0 e iTunes RSS. autoradio-autoradio-3.6-4/README.release000066400000000000000000000007101454362722700200100ustar00rootroot00000000000000to change release: emacs autoradio/__init__.py change _version as: _version_="3.3" use tito to change spec file and do a new release for RPM: tito tag --use-release=4 --use-version=3.3 push to github and start build on COPR: git push --follow-tags origin to release for debian: python3 setup.py distclean python3 setup.py sdist create a release on github as 3.x. 3.x.x for example 3.3 upload dist/autoradio-3.3.tar.gz tag as 3.3-1 will be ignored autoradio-autoradio-3.6-4/TODO000066400000000000000000000402311454362722700162030ustar00rootroot00000000000000== TODO == 17/02/2013 * utilizzare mp3splt sper spezzare i programmi e inserirli nei podcast * alternare meglio i jingle tenendo in considerazione la priorita * link in home page to spot playlist is wrong * on programbook programtype 5 need subtype 5a * code dump in player when trackremoved activated: Core was generated by `python ./autoplayerd run'. Program terminated with signal 6, Aborted. #0 0x0000003971236285 in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); Missing separate debuginfos, use: debuginfo-install gstreamer-python-0.10.19-2.fc15.x86_64 libid3tag-0.15.1b-11.fc15.x86_64 libmad-0.15.1b-13.fc12.x86_64 orc-0.4.16-5.fc16.x86_64 (gdb) where #0 0x0000003971236285 in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #1 0x0000003971237b9b in __GI_abort () at abort.c:91 #2 0x00000036bce2fff5 in _dbus_abort () at dbus-sysdeps.c:94 #3 0x00000036bce26fc1 in _dbus_warn_check_failed (format= 0x36bce362b0 "arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\nThis is normally a bug in some application using the D-Bus library.\n") at dbus-internals.c:289 #4 0x00000036bce19cbb in dbus_message_iter_append_basic (iter=0x7fffb9abca10, type=, value=0x7fffb9abc938) at dbus-message.c:2514 #5 0x00007fb5bcea2e22 in _message_iter_append_string (appender=0x7fffb9abca10, sig_type=111, obj=, allow_object_path_attr=) at message-append.c:628 #6 0x00007fb5bcea4292 in _message_iter_append_pyobject (appender=0x7fffb9abca10, sig_iter=0x7fffb9abca60, obj=u'638', more=0x7fffb9abca8c) at message-append.c:1174 #7 0x00007fb5bcea4b51 in dbus_py_Message_append (self=0x2699d68, args=(u'638',), kwargs=) at message-append.c:1301 #8 0x0000003c6e0dfb7d in ext_do_call (nk=1, na=, flags=, pp_stack=0x7fffb9abcba8, func= ) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4408 #9 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2779 #10 0x0000003c6e0e19a5 in PyEval_EvalCodeEx (co=, globals=, locals=, args=, argcount= 2, kws=0x2473ee8, kwcount=0, defs=0x0, defcount=0, closure= (, , , , , )) at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330 #11 0x0000003c6e0dff03 in fast_function (nk=, na=2, n=, pp_stack=0x7fffb9abcd98, func=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4194 #12 call_function (oparg=, pp_stack=0x7fffb9abcd98) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4119 #13 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740 #14 0x0000003c6e0e19a5 in PyEval_EvalCodeEx (co=, globals=, locals=, args=, argcount= 2, kws=0x7fb5c6952068, kwcount=0, defs=0x0, defcount=0, closure=0x0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330 #15 0x0000003c6e06e093 in function_call (func=, arg= (, _Connection__call_on_disconnection=[], _dbus_Connection_initialized=1, _bus_names=, data={'org.mpris.MediaPlayer2.AutoPlayer': }) at remote 0x2d8c5a8>, _signal_sender_matches={}, _signal_recipients_by_object_path={'/org/freedesktop/DBus': {None: {'NameOwnerChanged': []}}}) at remote 0x2a247d0>, _bus_name=) at remote 0x2b1d510>, _locations=[(<...>, '/org/mpris/MediaPlayer2', False)], _uname=':1.231', _bus=<...>, player= to continue, or q to quit--- #16 0x0000003c6e049383 in PyObject_Call (func=, arg=, kw=) at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2529 #17 0x0000003c6e0dc76f in ext_do_call (nk=0, na=, flags=, pp_stack=0x7fffb9abd058, func= ) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4411 #18 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2779 #19 0x0000003c6e0e19a5 in PyEval_EvalCodeEx (co=, globals=, locals=, args=, argcount= 3, kws=0x2bdd990, kwcount=0, defs=0x0, defcount=0, closure=0x0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330 #20 0x0000003c6e06df9c in function_call (func=, arg= (, _Connection__call_on_disconnection=[], _dbus_Connection_initialized=1, _bus_names=, data={'org.mpris.MediaPlayer2.AutoPlayer': }) at remote 0x2d8c5a8>, _signal_sender_matches={}, _signal_recipients_by_object_path={'/org/freedesktop/DBus': {None: {'NameOwnerChanged': []}}}) at remote 0x2a247d0>, _bus_name=) at remote 0x2b1d510>, _locations=[(<...>, '/org/mpris/MediaPlayer2', False)], _uname=':1.231', _bus=<...>, player=, arg=, kw=) at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2529 #22 0x0000003c6e05801f in instancemethod_call (func=, arg= (, _Connection__call_on_disconnection=[], _dbus_Connection_initialized=1, _bus_names=, data={'org.mpris.MediaPlayer2.AutoPlayer': }) at remote 0x2d8c5a8>, _signal_sender_matches={}, _signal_recipients_by_object_path={'/org/freedesktop/DBus': {None: {'NameOwnerChanged': []}}}) at remote 0x2a247d0>, _bus_name=) at remote 0x2b1d510>, _locations=[(<...>, '/org/mpris/MediaPlayer2', False)], _uname=':1.231', _bus=<...>, player=, arg=, kw=) at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2529 #24 0x0000003c6e049ba0 in PyObject_CallFunctionObjArgs (callable=) at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2760 #25 0x00007fb5bce9ec0b in DBusPyConnection_HandleMessage (conn=, msg=, callable=) at conn.c:79 #26 0x00007fb5bce9f8ce in _object_path_message (conn=, message=, user_data=) at conn-methods.c:119 #27 0x00000036bce1db31 in _dbus_object_tree_dispatch_and_unlock (tree=0x29cf9c0, message=0x2e54920) at dbus-object-tree.c:858 ---Type to continue, or q to quit--- #28 0x00000036bce0faa0 in dbus_connection_dispatch (connection=0x2bc6d60) at dbus-connection.c:4685 #29 0x00000036bd60abf5 in message_queue_dispatch (source=, callback=, user_data=) at dbus-gmain.c:90 #30 0x0000003973644f3d in g_main_dispatch (context=0x2a543c0) at gmain.c:2441 #31 g_main_context_dispatch (context=0x2a543c0) at gmain.c:3011 #32 0x0000003973645738 in g_main_context_iterate (context=0x2a543c0, block=, dispatch=1, self=) at gmain.c:3089 #33 0x0000003973645c85 in g_main_loop_run (loop=0x2a04f80) at gmain.c:3297 #34 0x00007fb5bf281ed1 in _wrap_g_main_loop_run (self=0x7fb5c69138d0) at pygmainloop.c:331 #35 0x0000003c6e0dff3b in call_function (oparg=, pp_stack=0x7fffb9abd9d8) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4082 #36 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740 #37 0x0000003c6e0e19a5 in PyEval_EvalCodeEx (co=, globals=, locals=, args=, argcount= 2, kws=0x29e8338, kwcount=0, defs=0x29a02f0, defcount=2, closure=0x0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330 #38 0x0000003c6e0dff03 in fast_function (nk=, na=2, n=, pp_stack=0x7fffb9abdbc8, func=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4194 #39 call_function (oparg=, pp_stack=0x7fffb9abdbc8) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4119 #40 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740 #41 0x0000003c6e0e075e in fast_function (nk=, na=1, n=, pp_stack=0x7fffb9abdd08, func=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4184 #42 call_function (oparg=, pp_stack=0x7fffb9abdd08) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4119 #43 PyEval_EvalFrameEx (f=, throwflag=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740 #44 0x0000003c6e0e19a5 in PyEval_EvalCodeEx (co=, globals=, locals=, args=, argcount= 0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330 #45 0x0000003c6e0e1ad2 in PyEval_EvalCode (co=, globals=, locals=) at /usr/src/debug/Python-2.7.3/Python/ceval.c:689 #46 0x0000003c6e0fbd5c in run_mod (mod=, filename=, globals= {'GstMad': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e54eb0>, 'GstURIDecodeBin': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2470a80>, 'GstBaseAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e58150>, 'player': , 'GstAutoAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2c09800>, 'GstPlaySink': , __doc__=, __module__='autoradio.autoplayer.playe...(truncated), locals= {'GstMad': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e54eb0>, 'GstURIDecodeBin': , __doc__= to continue, or q to quit--- Object.__doc__ at remote 0x7fb5c69150b0>, __module__='autoradio.autoplayer.player') at remote 0x2470a80>, 'GstBaseAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e58150>, 'player': , 'GstAutoAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2c09800>, 'GstPlaySink': , __doc__=, __module__='autoradio.autoplayer.playe...(truncated), flags=, arena=) at /usr/src/debug/Python-2.7.3/Python/pythonrun.c:1361 #47 0x0000003c6e0fcb60 in PyRun_FileExFlags (fp=0x21f8810, filename=0x7fffb9abf304 "./autoplayerd", start=, globals= {'GstMad': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e54eb0>, 'GstURIDecodeBin': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2470a80>, 'GstBaseAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e58150>, 'player': , 'GstAutoAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2c09800>, 'GstPlaySink': , __doc__=, __module__='autoradio.autoplayer.playe...(truncated), locals= {'GstMad': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e54eb0>, 'GstURIDecodeBin': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2470a80>, 'GstBaseAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2e58150>, 'player': , 'GstAutoAudioSink': , __doc__=, __module__='autoradio.autoplayer.player') at remote 0x2c09800>, 'GstPlaySink': , __doc__=, __module__='autoradio.autoplayer.playe...(truncated), closeit=1, flags=0x7fffb9abe030) at /usr/src/debug/Python-2.7.3/Python/pythonrun.c:1347 #48 0x0000003c6e0fd5df in PyRun_SimpleFileExFlags (fp=0x21f8810, filename=0x7fffb9abf304 "./autoplayerd", closeit=1, flags=0x7fffb9abe030) at /usr/src/debug/Python-2.7.3/Python/pythonrun.c:951 #49 0x0000003c6e10ef15 in Py_Main (argc=, argv=) at /usr/src/debug/Python-2.7.3/Modules/main.c:639 #50 0x000000397122169d in __libc_start_main (main=0x400620
, argc=3, ubp_av=0x7fffb9abe158, init=, fini=, rtld_fini=, stack_end=0x7fffb9abe148) at libc-start.c:226 #51 0x0000000000400651 in _start () autoradio-autoradio-3.6-4/amarok/000077500000000000000000000000001454362722700167655ustar00rootroot00000000000000autoradio-autoradio-3.6-4/amarok/autoradio.amarokscript.tar.gz000066400000000000000000000065221454362722700246060ustar00rootroot00000000000000Hks62+z2RVM^'M\zIOnF"X)I)1%ž]ZHrN;NA{|͎= p0E brY_hfL&OrM>`"Y22"J;<O2ьSvQ.ߤ,ư4$ -E$ & 74WdI&GHyOիt7yj< gW\'++>(Yz&bAE)ѭ>B#ASAdH|FH z\ZyjȩBpq+ 2r("I,D^dUx|!\hl:qqeŒ&9E &Tp5mϘ6ԽW?N޿/}sBXRdц^dl:T葊i4uKow4Ch3k|AB& Ȁibh)=CdҌm ,4T Q >a¸F fޖ1Ze">:Z1:L Pd ɚ+՚@K l\f &9Am&&HJV,B$v?_]/4#%lwkc0 {"0Tqwlp5٦cۺRjwE6~̶YLyTm9-SlYO&xV;# fM"Ǹr~C’8&kx5^4uZa3T=_8hP*SW NjLvЂ^݂ȬuF}Zb03j5#/]R%M_{uWmM4t#W .@`:J٩I&'J_DW3m,0KL(g -DteJ:%zzɅL~p?KF5Jzv]VK8N4IB`ABj>߸vAcFMLp?ʸQk[7mt+-MШ? z]o @*oҫ/ }B$RxKxQ)mԭ6Y=d+VgS(8A Euh#$=8jc>7,PQڕY?W9O_'5҆/ʹ&R"}dbw( $"VVZb'0`*ӳׯޟ֓.B% `_D"[Pf+50pB $[M㠦`hґpak0omm&$Sak#g M/ĔMO7Iv &w^\{n(k![?7e^dex&M߃dRhT|3U\W-B6+vzNS|TX}V ʹ+K>}ҁw?nhm5!/Lz9luڦ12LG"v6dȳJ}疊Ω=wj=eW}e!/H m<]RF1FK۪r حFnRmW4ۨn>Eʼm&n ~{Sn_  W ި`wbG8yFմ]zu֪76:oԨW.w6벧,=j6h ~2n q{to;Gzu" yi\TeeNwp&4+ )ُYkS|,'ZTT:[If#[I/{2[". tS)6>H#>KK* 9iI#ʼ:[l^bL.!łi]kͰeeӵˋFm؂.&z+s K Q6!  < Bv/5-Bm~۱ yFmW_&ADZ_wr51=[΁ۘԖ,yhPLBxPwHkn,iCWU&XHNͥ;{0k_mBpK9!bwMJJl}T^u5jۭ^Cedư\<뚸~Q}>wl'"/Im!ma3|j&*gNq#b35epmj**sJmlvqu{&Es#uhAdo~[:]pC&hzZ?Eҭ>vU_Nr"W %b'Ti s_#cU|fd.(F>5,K b78W^ ژ+& m}-CI؜JSgֻa#n߻ҚE6 e5Us_mDji%AL:q^eA@TUuȘ$h`}o'n1 =M.s(*Jr|n# S (һ}poaڿk&&VKU7B0/T]?E}W/.eN m_["1lKrm^s~I5d<+2k'9F|2o"'C{8pWRUTFSnІ6 mhCІ6 mhCІ6 mhCІ6 ^Pautoradio-autoradio-3.6-4/amarok/autoradioweb.amarokscript.tar.gz000066400000000000000000000003471454362722700253030ustar00rootroot00000000000000H1O0F8N` :tatդve'@=E*! Uz>7ܝëkA4,k:SM&Y91D)3ss{CNnzNcF*!"pڝD(autoradio-autoradio-3.6-4/anoggplayer/000077500000000000000000000000001454362722700200235ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/README.md000066400000000000000000000011201454362722700212740ustar00rootroot00000000000000# anoggplayer Automatically exported from code.google.com/p/anoggplayer Based on Arek Korbik's FOGG reference implementation, http://bazaar.launchpad.net/~arkadini/fogg/trunk/files. Player is capable of natively playing Ogg Vorbis files and webcasts, up to 128 kbps, at 44100 Hz, using Flash v.10 plugin. Update: higher bandwidth ogg files are now supported, limited to 44100 Hz Adaptation of other formats is planned as well. All user interface is pure javascript, to control the player completely from the hosting web-page. The player is written in haXe (http://haxe.org) for flash. autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/000077500000000000000000000000001454362722700223335ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/AnOggPlayer.hx000066400000000000000000000556511454362722700250600ustar00rootroot00000000000000import org.xiph.system.Bytes; import flash.Vector; import flash.external.ExternalInterface; import flash.events.Event; import flash.events.ProgressEvent; import org.xiph.fogg.SyncState; import org.xiph.fogg.StreamState; import org.xiph.fogg.Page; import org.xiph.fogg.Packet; import org.xiph.fvorbis.Info; import org.xiph.fvorbis.Comment; import org.xiph.fvorbis.DspState; import org.xiph.fvorbis.Block; import org.xiph.foggy.Demuxer; //import org.xiph.foggy.DemuxerStatus; import org.xiph.system.AudioSink; class PAudioSink extends AudioSink { /** A very quick&dirty wrapper around the AudioSink to somewhat make up for the lack of a proper demand-driven ogg demuxer a.t.m. */ var cb_threshold : Int; var cb_pending : Bool; var cb : PAudioSink -> Void; public function new(chunk_size : Int, fill = true, trigger = 0) { super(chunk_size, fill, trigger); cb_threshold = 0; cb = null; cb_pending = false; } public function set_cb(threshold : Int, cb : PAudioSink -> Void) : Void { cb_threshold = threshold; this.cb = cb; } override function _data_cb(event : flash.events.SampleDataEvent) :Void { super._data_cb(event); if (cb_threshold > 0) { if (available < cb_threshold && !cb_pending) { cb_pending = true; haxe.Timer.delay(_delayed_cb, 1); } } } function _delayed_cb() : Void { this.cb_pending = false; this.cb(this); } override public function write(pcm : Array>, index : Vector, samples : Int) : Void { super.write(pcm, index, samples); if (cb_threshold > 0) { if (available < cb_threshold && !cb_pending) { cb_pending = true; haxe.Timer.delay(_delayed_cb, 1); } } } } class AnMp3Player { var mp3Sound:flash.media.Sound; var mp3Request:flash.net.URLRequest; var bIsPlaying: Bool; var nItfPlayMode: Int; //0=stop, 1=play, 2=pause var onProgress:flash.events.ProgressEvent -> Void; var onID3:flash.events.Event -> Void; var statusCB : String -> Void; var bufferCB : Int -> Void; var newSongCB: String -> Void; var onError: flash.events.IOErrorEvent -> Void; var volume: Int; var sch:flash.media.SoundChannel; var onSoundComplete:Event -> Void; var onProgressCB: Int -> Int -> Void; var bytesLoaded: Int; var bytesTotal: Int; var bytesPlayed: Int; var pausePos : Float; var playTimer: haxe.Timer; function DoProgress(event:ProgressEvent):Void { bytesLoaded = cast(event.bytesLoaded,Int); bytesTotal = cast(event.bytesTotal,Int); doOnProgress(Math.ceil(bytesLoaded*100/bytesTotal),bytesPlayed); if(mp3Sound.isBuffering)doBuffer(50) else { if(!bIsPlaying){ if(nItfPlayMode==1) { doBuffer(100); bIsPlaying=true; doStatus("playing"); } } } } function doBuffer(value: Int) :Void { if(bufferCB != null) bufferCB(value); } function doOnProgress(loaded: Int, played: Int): Void { if(onProgressCB != null) onProgressCB(loaded,played); } function doStatus(state: String) :Void { trace("mp3:"+state); if(statusCB != null) statusCB(state); } function DoSoundComplete(e:Event):Void { bIsPlaying=false; trace("mp3 sound complete"); doStatus("stopped"); nItfPlayMode=0; } function DoID3(event:Event):Void { var statstring: String; statstring = "Artist"+ "=\""+StringTools.replace(mp3Sound.id3.artist,"\"","\"\"")+"\";"; statstring+="Title"+"=\""+StringTools.replace(mp3Sound.id3.songName,"\"","\"\"")+"\";"; statstring+="Album"+"=\""+StringTools.replace(mp3Sound.id3.album,"\"","\"\"")+"\";"; statstring+="Genre"+"=\""+StringTools.replace(mp3Sound.id3.genre,"\"","\"\"")+"\";"; if(newSongCB != null) newSongCB(statstring); } function DoError(event:flash.events.IOErrorEvent):Void { doStatus("error=ioerror"); bIsPlaying=false; nItfPlayMode=0; } function DoPlayTimer(): Void{ if(bIsPlaying) { if (sch !=null)bytesPlayed=Math.ceil(sch.position*100/ mp3Sound.length+1); doOnProgress(Math.ceil(bytesLoaded*100/bytesTotal),bytesPlayed); } } public function setNewSongCB(newCB : String -> Void): Void { newSongCB = newCB; } //----------------- public function setBufferCB(newCB : Int -> Void): Void { bufferCB = newCB; } public function setProgressCB(newCB: Int -> Int -> Void): Void{ onProgressCB = newCB; } public function setStatusCB(newCB : String -> Void): Void { statusCB = newCB; } public function new() { onProgress=DoProgress; onID3=DoID3; onError=DoError; onSoundComplete=DoSoundComplete; sch = null; bytesPlayed=0; playTimer = new haxe.Timer(500); playTimer.run = DoPlayTimer; nItfPlayMode = 0; pausePos=0; } public function setVolume(vol:Int):Void { var strans:flash.media.SoundTransform; volume=vol; if(sch != null) { strans = sch.soundTransform; strans.volume = (volume+0.0001)/100; sch.soundTransform = strans; } } public function playMP3 ( murl:String):Void { trace("playMP3: "+murl); nItfPlayMode = 1;//play! bIsPlaying = false; mp3Request = new flash.net.URLRequest(murl); mp3Sound = new flash.media.Sound(); mp3Sound.load(mp3Request); mp3Sound.addEventListener(flash.events.ProgressEvent.PROGRESS, onProgress); mp3Sound.addEventListener(Event.ID3, onID3); mp3Sound.addEventListener(flash.events.IOErrorEvent.IO_ERROR, onError); sch = mp3Sound.play(0,0); sch.addEventListener(Event.SOUND_COMPLETE,onSoundComplete); doStatus("buffering"); setVolume(volume); pausePos=0; } public function stopMP3() :Void { //trace(".mp3 stopping"); //doStatus("stopped"); bIsPlaying=false; nItfPlayMode = 0; if(sch!= null)sch.stop(); pausePos=0; try { mp3Sound.close(); }catch (e:flash.errors.IOError){ } trace(" mp3 stopped"); } public function pauseMP3():Void{ if(pausePos==0){//do pause if(sch!=null) { pausePos=sch.position; sch.stop(); nItfPlayMode=2; } }else{ sch=mp3Sound.play(pausePos); setVolume(volume); pausePos=0; nItfPlayMode=1; sch.addEventListener(Event.SOUND_COMPLETE,onSoundComplete); } } public function seekMp3(seekPos:Float):Int{ var target_pos:Int =Math.ceil(mp3Sound.length*seekPos); target_pos=Math.ceil(Math.max(target_pos,1000));//from 1 sec var needResume:Bool =(pausePos==0); if(pausePos==0)pauseMP3(); pausePos=target_pos; if(needResume)pauseMP3(); return 1; } public function isPlaying(): Bool { return bIsPlaying; } public function getPlayMode():Int { return(nItfPlayMode); } } /* ANOnymous-delivered Ogg Player for ANOma.fm :3 */ class AnOggPlayer { var ul : flash.net.URLStream; var asink : PAudioSink; var url : String; var volume : Int; var mp3player:AnMp3Player; var bytesTotal : Int; var bytesLoaded : Int; var bytesPlayed: Int; var playBuffer:flash.utils.ByteArray; var whatPlayer:Int;//0 for ogg, 1 for mp3; var isPaused:Bool; // FIXME: find a better way to initialize those static bits? static function init_statics() : Void { org.xiph.fogg.Buffer._s_init(); org.xiph.fvorbis.FuncFloor._s_init(); org.xiph.fvorbis.FuncMapping._s_init(); org.xiph.fvorbis.FuncTime._s_init(); org.xiph.fvorbis.FuncResidue._s_init(); } var _packets : Int; var vi : Info; var vc : Comment; var vd : DspState; var vb : Block; var dmx : Demuxer; var _pcm : Array>>; var _index : Vector; var read_pending : Bool; var read_started : Bool; var read_buff_pending: Bool; var buff_write_pos:Int; var play_buffered:Bool;//use buffer, don't set to true for streaming? var streamDetected:Bool;//do NOT use buffer. function _proc_packet_head(p : Packet, sn : Int) : DemuxerStatus { vi.init(); vc.init(); if (vi.synthesis_headerin(vc, p) < 0) { // not vorbis - clean up and ignore vc.clear(); vi.clear(); } else { // vorbis - detach this cb and attach the main decoding cb // to the specific serialno //dmx.remove_packet_cb(-1); dmx.set_packet_cb(sn, _proc_packet); } _packets = 0; _packets++; return dmx_ok; } function _proc_packet(p : Packet, sn : Int) : DemuxerStatus { var samples : Int; switch(_packets) { case 0: /* vi.init(); vc.init(); if (vi.synthesis_headerin(vc, p) < 0) { return dmx_ok; } else { dmx.set_packet_cb(sn, _proc_packet); dmx.remove_packet_cb(-1); } */ case 1: vi.synthesis_headerin(vc, p); case 2: vi.synthesis_headerin(vc, p); { var ptr : Array = vc.user_comments; var j : Int = 0; var comments : String; var comment: Array; //trace(""); comments=""; while (j < ptr.length) { if (ptr[j] == null) { break; }; comment = System.fromBytes(ptr[j], 0, ptr[j].length - 1).split("="); comments = comments+comment[0]; comments = comments +"=\""+StringTools.htmlEscape(StringTools.replace(comment[1],"\"","\"\""))+"\";"; trace(System.fromBytes(ptr[j], 0, ptr[j].length - 1)); j++; }; _doNewSong(comments); trace("Bitstream is " + vi.channels + " channel, " + vi.rate + "Hz"); trace(("Encoded by: " + System.fromBytes(vc.vendor, 0, vc.vendor.length - 1)) + "\n"); } vd.synthesis_init(vi); vb.init(vd); _pcm = [null]; _index = new Vector(vi.channels, true); default: if (vb.synthesis(p) == 0) { vd.synthesis_blockin(vb); } while ((samples = vd.synthesis_pcmout(_pcm, _index)) > 0) { asink.write(_pcm[0], _index, samples); vd.synthesis_read(samples); } } _packets++; return dmx_ok; } function _read_data() : Void { var to_read : Int = ul.bytesAvailable; //var chunk : Int = 8192; var chunk : Int = 16384;//test? //trace("read_data: " + ul.bytesAvailable+" to read: "+to_read); read_pending = false; if (to_read == 0) return; if (to_read < chunk && !read_pending) { read_pending = true; haxe.Timer.delay(_read_data, 50); return; } to_read = ul.bytesAvailable; if (to_read > chunk) { to_read = chunk; } /*this was here, now we read to buffer, not to demuxer dmx.read(ul, to_read); bytesPlayed+=to_read; _doProgress(Math.ceil(bytesLoaded*100/(bytesTotal+2)),Math.ceil(bytesPlayed*100/(bytesTotal+2))); */ to_read=ul.bytesAvailable; ul.readBytes(playBuffer,buff_write_pos,/*chunk*/to_read); buff_write_pos+=to_read; // bytesPlayed+=to_read; } function _read_buffer():Void{ var to_read : Int = playBuffer.bytesAvailable; //var chunk : Int = 8192; var chunk : Int = 16384;//test? var did_read:Int=0; //trace("read_data: " + ul.bytesAvailable+" to read: "+to_read); read_buff_pending = false; if (to_read == 0) return; if (to_read < chunk && !read_buff_pending) { read_buff_pending = true; haxe.Timer.delay(_read_buffer, 50); return; } /*else if(to_read chunk) { to_read = chunk; } did_read=dmx.read(playBuffer, to_read); if(did_read==to_read) { bytesPlayed+=to_read; if((!play_buffered)||(streamDetected)) {//kill off buffer /* buff_write_pos=playBuffer.bytesAvailable; System.bytescopy(playBuffer,playBuffer.position,playBuffer, 0, playBuffer.bytesAvailable); playBuffer.position=0;*/ var tmp:flash.utils.ByteArray = new flash.utils.ByteArray(); playBuffer.readBytes(tmp); playBuffer=tmp; buff_write_pos=playBuffer.length; } _doProgress(Math.ceil(bytesLoaded*100/(bytesTotal+2)),Math.ceil(bytesPlayed*100/(bytesTotal+2))); } } function _seek_ogg(seek_pos:Float):Int { var target_pos,target_step:Int; target_pos=Math.ceil(bytesTotal*seek_pos); target_step=Math.ceil(Math.max(Math.ceil(target_pos/16384),3)); target_pos=target_step*16384; if(playBuffer.length > cast(target_pos,UInt)){ bytesPlayed=target_pos; playBuffer.position=target_pos; return 1; } else { return 0; } } function try_ogg() : Void { dmx = new Demuxer(); vi = new Info(); vc = new Comment(); vd = new DspState(); vb = new Block(vd); _packets = 0; dmx.set_packet_cb(-1, _proc_packet_head); //asink = new PAudioSink(8192, true, 132300); asink = new PAudioSink(8192, true, 132300);//params: data chunk for Sound.onSampleData, doFill with zeroes, trigger play after... asink.setBufferCB(_doBuffer); asink.setStatusCB(_doState); asink.setVolume(volume); asink.set_cb(88200, _on_data_needed); } //---------------------------------------------------------------- function _playURL ( murl:String ): Void { trace("playURL: "+murl); playBuffer=new flash.utils.ByteArray(); streamDetected=false; oldBytesTotal=0;//nothing loaded buff_write_pos=0; url=murl; bytesPlayed =0; isPaused=false; if(StringTools.endsWith(url,"ogg")||StringTools.endsWith(url,"OGG")||StringTools.endsWith(url,"Ogg")) { _doState("buffering"); ul.load(new flash.net.URLRequest(url)); whatPlayer=0;//ogg } else if(StringTools.endsWith(url,"mp3")||StringTools.endsWith(url,"MP3")||StringTools.endsWith(url,"Mp3")) { _playMP3(murl); } else { _doState("error=unsupported_format"); } } function _playMP3 (murl:String):Void { trace("playing mp3"); whatPlayer=1;//mp3 mp3player = new AnMp3Player(); mp3player.setNewSongCB(_doNewSong); mp3player.setStatusCB(_doState); mp3player.setBufferCB(_doBuffer); mp3player.setProgressCB(_doProgress); mp3player.playMP3(murl); } //--------------------------------------------------- function _stopPlay() : Void { trace("stopPlay!"); isPaused=false; try { if(mp3player!=null){ trace("stopping mp3"); mp3player.stopMP3(); } if(asink!=null) { asink.stop(); ul.close(); playBuffer=null; } } catch( msg : String ) { trace("Error occurred: " + msg); } whatPlayer=-1; _doState("stopped"); } //---------------------------------------------------- function _pausePlay() : Void { trace(whatPlayer); if(whatPlayer==0) { //ogg pause routine if(!isPaused){ asink.stop(); isPaused=true; _doState("paused"); } else{ asink.play(); isPaused=false; _doState("playing"); } } else if(whatPlayer==1) { //mp3 pause routine if(mp3player.getPlayMode()==2) {//unpause mp3player.pauseMP3(); _doState("playing"); } else {//pause mp3player.pauseMP3(); _doState("paused"); } } } //---------------------------------------------------- function _seekPlay(pos:Float): Void { if(whatPlayer==0) { asink.stop(); if(_seek_ogg(pos)>0){ asink.resetBuffer(); _read_buffer(); _read_buffer(); _read_buffer(); } asink.play(); } else { mp3player.seekMp3(pos); } } //---------------------------------------------------- function _setVolume(vol: Int) : Void { volume = vol; if(asink!=null) asink.setVolume(vol); if(mp3player!=null)mp3player.setVolume(vol); } function _doState(state: String) : Void { if(state=="stopped")whatPlayer = -1; flash.external.ExternalInterface.call("onOggState",state); } function _doBuffer(fill : Int) : Void { flash.external.ExternalInterface.call("onOggBuffer",fill); } function _doNewSong(headers:String) : Void { flash.external.ExternalInterface.call("onOggSongBegin",headers); } function _doProgress(loaded:Int,played:Int):Void { if(streamDetected) { loaded=100; if((whatPlayer==0)&&(asink!=null)) { played=Math.ceil(asink.available*100/(132300*3)); } } flash.external.ExternalInterface.call("onOggProgress",loaded,played); } function start_request() : Void { trace("Starting downloading: " + url); ul = new flash.net.URLStream(); ul.addEventListener(flash.events.Event.OPEN, _on_open ); ul.addEventListener(flash.events.ProgressEvent.PROGRESS, _on_progress); ul.addEventListener(flash.events.Event.COMPLETE, _on_complete); ul.addEventListener(flash.events.IOErrorEvent.IO_ERROR, _on_error); ul.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR, _on_security); _doState("loaded"); //ul.load(new flash.net.URLRequest(url)); } function _on_open(e : flash.events.Event) : Void { read_pending = false; read_started = false; try_ogg(); } var oldBytesTotal:Int; var adjustCount:Int; var _bootstrap_pending:Bool; function _on_progress(e : flash.events.ProgressEvent) : Void { //trace("on_progress: " + ul.bytesAvailable); bytesLoaded = cast(e.bytesLoaded,Int); if(oldBytesTotal==0){ _bootstrap_pending=false; read_started=false; oldBytesTotal=bytesTotal; if(adjustCount>3)adjustCount=0; if(!streamDetected)trace("adjust "+adjustCount+": size "+bytesTotal); } bytesTotal = cast(e.bytesTotal,Int); if((bytesTotal==0)&&(!streamDetected)) { adjustCount++; if(adjustCount>3) { trace("Microsoft idea of streaming detected :3"); streamDetected=true; } } if(oldBytesTotal!=bytesTotal) { oldBytesTotal=bytesTotal; if(!streamDetected) { adjustCount++; trace("adjust "+adjustCount+": size "+bytesTotal); if(adjustCount>10) { trace("streaming Ogg detected"); streamDetected=true; adjustCount=0; } } } _doProgress(Math.ceil(bytesLoaded*100/(bytesTotal+2)),Math.ceil(bytesPlayed*100/(bytesTotal+2))); if (ul.bytesAvailable > 16284){ _read_data(); if (!read_started ) { //to fix immediate preload on ogg on IE 6 if(!_bootstrap_pending)_bootstrap_read(); } } } //this functions hand-feeds audiosink new data until it starts playing on it's own function _bootstrap_read():Void { _bootstrap_pending=false; _read_buffer();//this function feeds the actual data if((!asink.triggered)&&(!_bootstrap_pending)) { _bootstrap_pending=true; haxe.Timer.delay(_bootstrap_read, 50); return; } } function _on_complete(e : flash.events.Event) : Void { //trace("Found ? pages with " + _packets + " packets."); trace("\n\n===== Loading '" + url + "'done. Enjoy! =====\n"); } function _on_error(e : flash.events.IOErrorEvent) : Void { trace("error occured: " + e); _doState("error=ioerror"); } function _on_security(e : flash.events.SecurityErrorEvent) : Void { trace("security error: " + e); _doState("error=securerror"); } function _on_data_needed(s : PAudioSink) : Void { //trace("on_data: " + ul.bytesAvailable); read_started = true; //_read_data(); _read_buffer(); } static function check_version() : Bool { if (flash.Lib.current.loaderInfo.parameters.noversioncheck != null) return true; var vs : String = flash.system.Capabilities.version; var vns : String = vs.split(" ")[1]; var vn : Array = vns.split(","); if (vn.length < 1 || Std.parseInt(vn[0]) < 10) return false; if (vn.length < 2 || Std.parseInt(vn[1]) > 0) return true; if (vn.length < 3 || Std.parseInt(vn[2]) > 0) return true; if (vn.length < 4 || Std.parseInt(vn[3]) >= 525) return true; return false; } private function new(url : String) { this.url = url; whatPlayer=-1; play_buffered=true; } public static function main() : Void { if (check_version()) { init_statics(); var fvs : Dynamic = flash.Lib.current.loaderInfo.parameters; var url = fvs.playUrl == null ? "http://comodino.org:8001/null.ogg" : fvs.playUrl; var foe = new AnOggPlayer(url); foe.volume=100; flash.system.Security.allowDomain("*"); flash.external.ExternalInterface.addCallback("playURL",foe._playURL); flash.external.ExternalInterface.addCallback("stopPlaying",foe._stopPlay); flash.external.ExternalInterface.addCallback("setVolume",foe._setVolume); flash.external.ExternalInterface.addCallback("pausePlay",foe._pausePlay); flash.external.ExternalInterface.addCallback("Seek",foe._seekPlay); //foe._playURL("called from self"); foe.start_request(); } else { trace("You need a newer Flash Player."); trace("Your version: " + flash.system.Capabilities.version); trace("The minimum required version: 10.0.0.525"); flash.external.ExternalInterface.call("onOggState","error=need_flash_10.0.0.525_or_better"); } } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/ArrayTools.hx000066400000000000000000000055251454362722700250020ustar00rootroot00000000000000import org.xiph.system.Bytes; import flash.Vector; class ArrayTools { public static function alloc(size : Int, ?fill = true, ?value = null) : Array { return _alloc(size, fill, value); } public static inline function _alloc(size : Int, fill : Bool, value : T) : Array { var b : Array = new Array(); if (fill) { var i : Int = 0; while (i < size) { b[i] = value; i++; } } else { b[size - 1] = value; } return b; } public static inline function arraycopy(src : Array, src_pos : Int, dst : Array, dst_pos : Int, length : Int) : Void { var srci : Int; var n : Int; var dsti : Int; if (src == dst && dst_pos > src_pos) { srci = src_pos + length; n = src_pos; dsti = dst_pos + length; while (srci > n) { dst[--dsti] = src[--srci]; } } else { srci = src_pos; n = src_pos + length; dsti = dst_pos; while (srci < n) { dst[dsti++] = src[srci++]; } } } public static inline function copy(src : Array, src_pos : Int, dst : Array, dst_pos : Int, length : Int) : Array { var b : Array; var src_end : Int = src_pos + length; if (dst_pos > 0) { b = dst.slice(0, dst_pos).concat(src.slice(src_pos, src_end)); } else { b = src.slice(src_pos, src_end); } if (dst_pos + length < dst.length) { b = b.concat(dst.slice(dst_pos + length)); } return b; } /* I'm not sure why would anybody need the methods below... */ public static function allocI(size : Int, ?fill = true, ?value = 0) : Array { return _allocI(size, fill, value); } public static inline function _allocI(size : Int, fill : Bool, value : Int) : Array { var b : Array = new Array(); if (fill) { var i : Int = 0; while (i < size) { b[i] = value; i++; } } else { b[size - 1] = value; } return b; } public static function allocF(size : Int, ?fill = true, ?value = 0.0) : Array { return _allocF(size, fill, value); } public static inline function _allocF(size : Int, fill : Bool, value : Float) : Array { var b : Array = new Array(); if (fill) { var i : Int = 0; while (i < size) { b[i] = value; i++; } } else { b[size - 1] = value; } return b; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/COPYING000066400000000000000000000635001454362722700233720ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/Makefile000066400000000000000000000025071454362722700237770ustar00rootroot00000000000000HAXE = haxe HX_FILES = \ org/xiph/fogg/Buffer.hx \ org/xiph/fogg/SyncState.hx \ org/xiph/fogg/Packet.hx \ org/xiph/fogg/StreamState.hx \ org/xiph/fogg/Page.hx \ org/xiph/foggy/Demuxer.hx \ org/xiph/system/Bytes.hx \ org/xiph/system/AudioSink.hx \ org/xiph/fvorbis/Block.hx \ org/xiph/fvorbis/CodeBook.hx \ org/xiph/fvorbis/Comment.hx \ org/xiph/fvorbis/Drft.hx \ org/xiph/fvorbis/DspState.hx \ org/xiph/fvorbis/EncodeAuxNearestMatch.hx \ org/xiph/fvorbis/EncodeAuxThreshMatch.hx \ org/xiph/fvorbis/Floor0.hx \ org/xiph/fvorbis/Floor1.hx \ org/xiph/fvorbis/FuncFloor.hx \ org/xiph/fvorbis/FuncMapping.hx \ org/xiph/fvorbis/FuncResidue.hx \ org/xiph/fvorbis/FuncTime.hx \ org/xiph/fvorbis/Info.hx \ org/xiph/fvorbis/InfoMode.hx \ org/xiph/fvorbis/Lookup.hx \ org/xiph/fvorbis/Lpc.hx \ org/xiph/fvorbis/Lsp.hx \ org/xiph/fvorbis/Mapping0.hx \ org/xiph/fvorbis/Mdct.hx \ org/xiph/fvorbis/PsyInfo.hx \ org/xiph/fvorbis/Residue0.hx \ org/xiph/fvorbis/Residue1.hx \ org/xiph/fvorbis/Residue2.hx \ org/xiph/fvorbis/StaticCodeBook.hx \ org/xiph/fvorbis/Time0.hx \ System.hx \ ArrayTools.hx \ VectorTools.hx AnOgg.swf: build.hxml AnOggPlayer.hx $(HX_FILES) $(HAXE) -cp . -swf-version 10 -swf-header 200:200:30:000000 build.hxml clean: rm -f ../../autoradio/programs/static/programs/playogg/flash/AnOgg.swf autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/System.hx000066400000000000000000000045621454362722700241670ustar00rootroot00000000000000import org.xiph.system.Bytes; import flash.Vector; class System { /* * Note: modifies .position of both src and dst! */ public static inline function bytescopy(src : Bytes, src_pos : Int, dst : Bytes, dst_pos : Int, length : Int) : Void { src.position = src_pos; if (src == dst && dst_pos > src_pos) { var tmp : Bytes = new Bytes(); tmp.length = length; src.readBytes(tmp, 0, length); tmp.position = 0; tmp.readBytes(dst, dst_pos, length); } else { src.readBytes(dst, dst_pos, length); } } /* * That one, though a tiny bit faster, doesn't handle overlapping if: * - src and dst are the same object, and * - dst_pos > src_pos */ public static inline function unsafe_bytescopy(src : Bytes, src_pos : Int, dst : Bytes, dst_pos : Int, length : Int) : Void { src.position = src_pos; src.readBytes(dst, dst_pos, length); } public static inline function fromString(str : String) : Bytes { var b = new Bytes(); b.writeUTFBytes(str); b.position = 0; return b; } public static inline function fromBytes(b : Bytes, start : Int, length : Int) : String { b.position = start; return b.readUTFBytes(length); } public static function alloc(size : Int) : Bytes { var b = new Bytes(); b.length = size; b[size - 1] = 0; b.position = 0; return b; } public static inline function resize(b : Bytes, new_size : Int) : Void { b.length = new_size; // do we need to do: "b[new_size - 1] = 0" (even if only when growing)? } public static inline function abs(n : Int) : Int { return n < 0 ? -n : n; } public static inline function max(a : Int, b : Int) : Int { return a > b ? a : b; } public static function floatToIntBits(value : Float) : Int { var b : Bytes = new Bytes(); b.writeFloat(value); b.position = 0; var i : Int = b.readInt(); return i; } public static function intBitsToFloat(value : Int) : Float { var b : Bytes = new Bytes(); b.writeInt(value); b.position = 0; var f : Float = b.readFloat(); return f; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/TODO000066400000000000000000000001601454362722700230200ustar00rootroot00000000000000TODO ---- * ogg's granulepos type is a 64 bit integer - don't use 32 int type to store granulepos in fogg! autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/VectorTools.hx000066400000000000000000000063251454362722700251650ustar00rootroot00000000000000import flash.Vector; // copy & paste sucks class VectorTools { public static inline function vectorcopy(src : Vector, src_pos : Int, dst : Vector, dst_pos : Int, length : Int) : Void { var srci : Int; var n : Int; var dsti : Int; if (src == dst && dst_pos > src_pos) { srci = src_pos + length; n = src_pos; dsti = dst_pos + length; while (srci > n) { dst[--dsti] = src[--srci]; } } else { srci = src_pos; n = src_pos + length; dsti = dst_pos; while (srci < n) { dst[dsti++] = src[srci++]; } } } public static inline function vectorcopyI(src : Vector, src_pos : Int, dst : Vector, dst_pos : Int, length : Int) : Void { var srci : Int; var n : Int; var dsti : Int; if (src == dst && dst_pos > src_pos) { srci = src_pos + length; n = src_pos; dsti = dst_pos + length; while (srci > n) { dst[--dsti] = src[--srci]; } } else { srci = src_pos; n = src_pos + length; dsti = dst_pos; while (srci < n) { dst[dsti++] = src[srci++]; } } } public static inline function vectorcopyF(src : Vector, src_pos : Int, dst : Vector, dst_pos : Int, length : Int) : Void { var srci : Int; var n : Int; var dsti : Int; if (src == dst && dst_pos > src_pos) { srci = src_pos + length; n = src_pos; dsti = dst_pos + length; while (srci > n) { dst[--dsti] = src[--srci]; } } else { srci = src_pos; n = src_pos + length; dsti = dst_pos; while (srci < n) { dst[dsti++] = src[srci++]; } } } public static inline function copyI(src : Vector, src_pos : Int, dst : Vector, dst_pos : Int, length : Int) : Vector { var b : Vector; var src_end : Int = src_pos + length; if (dst_pos > 0) { b = dst.slice(0, dst_pos).concat(src.slice(src_pos, src_end)); } else { b = src.slice(src_pos, src_end); } if (cast(dst_pos + length,Int) < dst.length) { b = b.concat(dst.slice(dst_pos + length)); } b.fixed = dst.fixed; return b; } public static inline function copyF(src : Vector, src_pos : Int, dst : Vector, dst_pos : Int, length : Int) : Vector { var b : Vector; var src_end : Int = src_pos + length; if (dst_pos > 0) { b = dst.slice(0, dst_pos).concat(src.slice(src_pos, src_end)); } else { b = src.slice(src_pos, src_end); } if (cast(dst_pos + length,Int) < dst.length) { b = b.concat(dst.slice(dst_pos + length)); } b.fixed = dst.fixed; return b; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/build.hxml000066400000000000000000000001171454362722700243230ustar00rootroot00000000000000-main AnOggPlayer -swf-version 10 -swf-header 400:800:12:ffffff -swf AnOgg.swf autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/000077500000000000000000000000001454362722700231225ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/000077500000000000000000000000001454362722700240725ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/000077500000000000000000000000001454362722700250145ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/Buffer.hx000066400000000000000000000237441454362722700266000ustar00rootroot00000000000000package org.xiph.fogg; import org.xiph.system.Bytes; import flash.Vector; class Buffer { /* * generated source for Buffer */ inline static private var BUFFER_INCREMENT : Int = 256; inline static private function _mask(): Array{ return [0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff]; } static private var _vmask : Vector = null; private var mask : Vector; // discarded initializer: '0'; var ptr : Int; // discarded initializer: 'null'; public var buffer : Bytes; // discarded initializer: '0'; var endbit : Int; // discarded initializer: '0'; var endbyte : Int; // discarded initializer: '0'; var storage : Int; // modifiers: public public function writeinit() : Void { buffer = System.alloc(Buffer.BUFFER_INCREMENT); ptr = 0; buffer[0] = 0; storage = Buffer.BUFFER_INCREMENT; } // modifiers: public public function writeBytes(s : Bytes) : Void { // for-while; var i : UInt = 0; while (i < s.length) { if (s[i] == 0) { break; }; write(s[i], 8); i++; }; } // modifiers: public public function readBytes(s : Bytes, bytes : Int) : Void { var i : Int = 0; while (bytes-- != 0) { s[i++] = read(8); }; } // modifiers: function reset() : Void { ptr = 0; buffer[0] = 0; endbit = endbyte = 0; } // modifiers: public public function writeclear() : Void { buffer = null; } /* // modifiers: public public function __readinit_0(buf : Bytes, bytes : Int) : Void { __readinit_1(buf, 0, bytes); } */ // modifiers: public public function readinit(buf : Bytes, start : Int = 0, bytes : Int) : Void { ptr = start; buffer = buf; endbit = endbyte = 0; storage = bytes; } // modifiers: public public function write(value : Int, bits : Int) : Void { if ((endbyte + 4) >= storage) { // var foo : Bytes = System.alloc(storage + Buffer.BUFFER_INCREMENT); // System.arraycopy(buffer, 0, foo, 0, storage); // buffer = foo; storage += Buffer.BUFFER_INCREMENT; buffer.length = storage; }; value &= mask[bits]; bits += endbit; buffer[ptr] |= value << endbit; if (bits >= 8) { buffer[ptr + 1] = value >>> (8 - endbit); if (bits >= 16) { buffer[ptr + 2] = value >>> (16 - endbit); if (bits >= 24) { buffer[ptr + 3] = value >>> (24 - endbit); if (bits >= 32) { if (endbit > 0) { buffer[ptr + 4] = value >>> (32 - endbit); } else { buffer[ptr + 4] = 0; }; }; }; }; }; endbyte += Std.int(bits / 8); ptr += Std.int(bits / 8); endbit = bits & 7; } // modifiers: public public function look(bits : Int) : Int { var ret : Int; var m : Int = mask[bits]; bits += endbit; if ((endbyte + 4) >= storage) { if ((endbyte + ((bits - 1) / 8)) >= storage) { return -1; }; }; ret = ((buffer[ptr] & 0xff) >>> endbit); if (bits > 8) { ret |= ((buffer[ptr + 1] & 0xff) << (8 - endbit)); if (bits > 16) { ret |= ((buffer[ptr + 2] & 0xff) << (16 - endbit)); if (bits > 24) { ret |= ((buffer[ptr + 3] & 0xff) << (24 - endbit)); if ((bits > 32) && (endbit != 0)) { ret |= ((buffer[ptr + 4] & 0xff) << (32 - endbit)); }; }; }; }; return m & ret; } // modifiers: public public function look1() : Int { if (endbyte >= storage) { return -1; }; return (buffer[ptr] >> endbit) & 1; } // modifiers: public public function adv(bits : Int) : Void { bits += endbit; ptr += Std.int(bits / 8); endbyte += Std.int(bits / 8); endbit = bits & 7; } // modifiers: public public function adv1() : Void { ++endbit; if (endbit > 7) { endbit = 0; ptr++; endbyte++; }; } // modifiers: public public function read(bits : Int) : Int { var ret : Int; var m : Int = mask[bits]; bits += endbit; if ((endbyte + 4) >= storage) { ret = -1; if ((endbyte + ((bits - 1) / 8)) >= storage) { ptr += Std.int(bits / 8); endbyte += Std.int(bits / 8); endbit = (bits & 7); return ret; }; }; ret = ((buffer[ptr] & 0xff) >>> endbit); if (bits > 8) { ret |= ((buffer[ptr + 1] & 0xff) << (8 - endbit)); if (bits > 16) { ret |= ((buffer[ptr + 2] & 0xff) << (16 - endbit)); if (bits > 24) { ret |= ((buffer[ptr + 3] & 0xff) << (24 - endbit)); if ((bits > 32) && (endbit != 0)) { ret |= ((buffer[ptr + 4] & 0xff) << (32 - endbit)); }; }; }; }; ret &= m; ptr += Std.int(bits / 8); endbyte += Std.int(bits / 8); endbit = bits & 7; return ret; } // modifiers: public public function readB(bits : Int) : Int { var ret : Int; var m : Int = 32 - bits; bits += endbit; if ((endbyte + 4) >= storage) { ret = -1; if (((endbyte * 8) + bits) > (storage * 8)) { ptr += Std.int(bits / 8); endbyte += Std.int(bits / 8); endbit = (bits & 7); return ret; }; }; ret = ((buffer[ptr] & 0xff) << (24 + endbit)); if (bits > 8) { ret |= ((buffer[ptr + 1] & 0xff) << (16 + endbit)); if (bits > 16) { ret |= ((buffer[ptr + 2] & 0xff) << (8 + endbit)); if (bits > 24) { ret |= ((buffer[ptr + 3] & 0xff) << endbit); if ((bits > 32) && (endbit != 0)) { ret |= ((buffer[ptr + 4] & 0xff) >> (8 - endbit)); }; }; }; }; ret = ((ret >>> (m >> 1)) >>> ((m + 1) >> 1)); ptr += Std.int(bits / 8); endbyte += Std.int(bits / 8); endbit = (bits & 7); return ret; } // modifiers: public public function read1() : Int { var ret : Int; if (endbyte >= storage) { ret = -1; endbit++; if (endbit > 7) { endbit = 0; ptr++; endbyte++; }; return ret; }; ret = ((buffer[ptr] >> endbit) & 1); endbit++; if (endbit > 7) { endbit = 0; ptr++; endbyte++; }; return ret; } // modifiers: public public function bytes() : Int { return endbyte + Std.int((endbit + 7) / 8); } // modifiers: public public function bits() : Int { return (endbyte * 8) + endbit; } // modifiers: public public function buffer_() : Bytes { // FIXME: shadows variable 'buffer'; return buffer; } // modifiers: static,public static public function ilog(v : Int) : Int { var ret : Int = 0; while (v > 0) { ret++; v >>>= 1; }; return ret; } // modifiers: static,public static public function report(in_ : String) : Void { //System.err.println(in_); trace(in_); //System.exit(1); } /* // modifiers: inline,public inline public function read() : Void { // FIXME: implement disambiguation handler; // __read_0(s : Bytes, bytes : Int) : Void; // __read_1(bits : Int) : Int; throw "NotImplementedError"; } */ /* // modifiers: inline,public inline public function readinit() : Void { // FIXME: implement disambiguation handler; // __readinit_0(buf : Bytes, bytes : Int) : Void; // __readinit_1(buf : Bytes, start : Int, bytes : Int) : Void; throw "NotImplementedError"; } */ /* // modifiers: inline,public inline public function write() : Void { // FIXME: implement disambiguation handler; // __write_0(s : Bytes) : Void; // __write_1(value : Int, bits : Int) : Void; throw "NotImplementedError"; } */ public function new() { mask = Buffer._vmask; ptr = 0; buffer = null; endbit = 0; endbyte = 0; storage = 0; } private static function __static_init__() : Void { var i : Int = 0; var n : Int = Buffer._mask().length; Buffer._vmask = new Vector(n, true); while (i < n) { Buffer._vmask[i] = Buffer._mask()[i]; i++; } } public static function _s_init() : Void { if (Buffer._vmask == null) { __static_init__(); } } /* private static function __init__() : Void { //__static_init__(); } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/Packet.hx000066400000000000000000000005561454362722700265720ustar00rootroot00000000000000package org.xiph.fogg; import org.xiph.system.Bytes; class Packet { /* * generated source for Packet */ public var packet_base : Bytes; public var packet : Int; public var bytes : Int; public var b_o_s : Int; public var e_o_s : Int; public var granulepos : Int; public var packetno : Int; public function new() {} } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/Page.hx000066400000000000000000000070421454362722700262340ustar00rootroot00000000000000package org.xiph.fogg; import org.xiph.system.Bytes; import flash.Vector; class Page { /* * generated source for Page */ static private var crc_lookup : Vector; // modifiers: static static function __static_init__() { // for-while; var i : Int = 0; crc_lookup = new Vector(256, true); while (i < 256) { crc_lookup[i] = crc_entry(i); i++; }; } // modifiers: static,private static private function crc_entry(index : Int) : Int { var r : Int = index << 24; // for-while; var i : Int = 0; while (i < 8) { if ((r & 0x80000000) != 0) { r = ((r << 1) ^ 0x04c11db7); } else { r <<= 1; }; i++; }; return r & 0xffffffff; } public var header_base : Bytes; public var header : Int; public var header_len : Int; public var body_base : Bytes; public var body : Int; public var body_len : Int; // modifiers: public function version() : Int { return header_base[header + 4] & 0xff; } // modifiers: public function continued() : Int { return header_base[header + 5] & 0x01; } // modifiers: public public function bos() : Int { return header_base[header + 5] & 0x02; } // modifiers: public public function eos() : Int { return header_base[header + 5] & 0x04; } // modifiers: public public function granulepos() : Int { var foo : Int = header_base[header + 13] & 0xff; foo = ((foo << 8) | (header_base[header + 12] & 0xff)); foo = ((foo << 8) | (header_base[header + 11] & 0xff)); foo = ((foo << 8) | (header_base[header + 10] & 0xff)); foo = ((foo << 8) | (header_base[header + 9] & 0xff)); foo = ((foo << 8) | (header_base[header + 8] & 0xff)); foo = ((foo << 8) | (header_base[header + 7] & 0xff)); foo = ((foo << 8) | (header_base[header + 6] & 0xff)); return foo; } // modifiers: public public function serialno() : Int { return (((header_base[header + 14] & 0xff) | ((header_base[header + 15] & 0xff) << 8)) | ((header_base[header + 16] & 0xff) << 16)) | ((header_base[header + 17] & 0xff) << 24); } // modifiers: public function pageno() : Int { return (((header_base[header + 18] & 0xff) | ((header_base[header + 19] & 0xff) << 8)) | ((header_base[header + 20] & 0xff) << 16)) | ((header_base[header + 21] & 0xff) << 24); } // modifiers: public function checksum() : Void { var crc_reg : Int = 0; // for-while; var i : Int = 0; while (i < header_len) { crc_reg = ((crc_reg << 8) ^ Page.crc_lookup[((crc_reg >>> 24) & 0xff) ^ (header_base[header + i] & 0xff)]); i++; }; // for-while; var i : Int = 0; while (i < body_len) { crc_reg = ((crc_reg << 8) ^ Page.crc_lookup[((crc_reg >>> 24) & 0xff) ^ (body_base[body + i] & 0xff)]); i++; }; header_base[header + 22] = crc_reg; header_base[header + 23] = crc_reg >>> 8; header_base[header + 24] = crc_reg >>> 16; header_base[header + 25] = crc_reg >>> 24; } public function new() { header_base = null; header = 0; header_len = 0; body_base = null; body = 0; body_len = 0; } private static function __init__() : Void untyped { __static_init__(); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/StreamState.hx000066400000000000000000000330771454362722700276230ustar00rootroot00000000000000package org.xiph.fogg; import org.xiph.system.Bytes; import flash.Vector; class StreamState { /* * generated source for StreamState */ var body_data : Bytes; var body_storage : Int; var body_fill : Int; private var body_returned : Int; var lacing_vals : Vector; var granule_vals : Vector; var lacing_storage : Int; var lacing_fill : Int; var lacing_packet : Int; var lacing_returned : Int; // discarded initializer: 'Bytes.alloc(282)'; var header : Bytes; var header_fill : Int; public var e_o_s : Int; var b_o_s : Int; var serialno : Int; var pageno : Int; var packetno : Int; var granulepos : Int; // modifiers: public public function __new_0() { init(); } // modifiers: function __new_1(serialno : Int) { this.__new_0(); __init_1(serialno); } // modifiers: function __init_0() : Void { header = System.alloc(282); body_storage = (16 * 1024); body_data = System.alloc(body_storage); lacing_storage = 1024; lacing_vals = new Vector(lacing_storage); //int[lacing_storage]; granule_vals = new Vector(lacing_storage); //long[lacing_storage]; } // modifiers: public public function __init_1(serialno : Int) : Void { if (body_data == null) { __init_0(); } else { // for-while; var i : UInt = 0; while (i < body_data.length) { body_data[i] = 0; i++; }; // for-while; var i : Int = 0; while (i < lacing_vals.length) { lacing_vals[i] = 0; i++; }; // for-while; var i : Int = 0; while (i < granule_vals.length) { granule_vals[i] = 0; i++; }; }; this.serialno = serialno; } // modifiers: public public function clear() : Void { body_data = null; lacing_vals = null; granule_vals = null; } // modifiers: function destroy() : Void { clear(); } // modifiers: function body_expand(needed : Int) : Void { if (body_storage <= (body_fill + needed)) { body_storage += (needed + 1024); // var foo : Bytes = System.alloc(body_storage); // System.arraycopy(body_data, 0, foo, 0, body_data.length); // body_data = foo; System.resize(body_data, body_storage); }; } // modifiers: function lacing_expand(needed : Int) : Void { if (lacing_storage <= (lacing_fill + needed)) { lacing_storage += (needed + 32); //var foo : Array = new Array(); //int[lacing_storage]; //System.arraycopy(lacing_vals, 0, foo, 0, lacing_vals.length); //lacing_vals[lacing_storage-1] = 0; lacing_vals.length = lacing_storage; //var bar : Array = new Array(); //long[lacing_storage]; //System.arraycopy(granule_vals, 0, bar, 0, granule_vals.length); //granule_vals[lacing_storage-1] = 0; granule_vals.length = lacing_storage; }; } // modifiers: public public function packetin(op : Packet) : Int { var lacing_val : Int = Std.int(op.bytes / 255) + 1; if (body_returned != 0) { body_fill -= body_returned; if (body_fill != 0) { System.bytescopy(body_data, body_returned, body_data, 0, body_fill); }; body_returned = 0; }; body_expand(op.bytes); lacing_expand(lacing_val); System.bytescopy(op.packet_base, op.packet, body_data, body_fill, op.bytes); body_fill += op.bytes; var j : Int; // for-while; j = 0; while (j < (lacing_val - 1)) { lacing_vals[lacing_fill + j] = 255; granule_vals[lacing_fill + j] = granulepos; j++; }; lacing_vals[lacing_fill + j] = (op.bytes % 255); granulepos = (granule_vals[lacing_fill + j] = op.granulepos); lacing_vals[lacing_fill] |= 0x100; lacing_fill += lacing_val; packetno++; if (op.e_o_s != 0) { e_o_s = 1; }; return 0; } // modifiers: public public function packetout(op : Packet) : Int { var ptr : Int = lacing_returned; if (lacing_packet <= ptr) { return 0; }; if ((lacing_vals[ptr] & 0x400) != 0) { lacing_returned++; packetno++; return -1; }; var size : Int = lacing_vals[ptr] & 0xff; var bytes : Int = 0; op.packet_base = body_data; op.packet = body_returned; op.e_o_s = (lacing_vals[ptr] & 0x200); op.b_o_s = (lacing_vals[ptr] & 0x100); bytes += size; while (size == 255) { var val : Int = lacing_vals[++ptr]; size = (val & 0xff); if ((val & 0x200) != 0) { op.e_o_s = 0x200; }; bytes += size; }; op.packetno = packetno; op.granulepos = granule_vals[ptr]; op.bytes = bytes; body_returned += bytes; lacing_returned = (ptr + 1); packetno++; return 1; } // modifiers: public public function pagein(og : Page) : Int { var header_base : Bytes = og.header_base; var header : Int = og.header; var body_base : Bytes = og.body_base; var body : Int = og.body; var bodysize : Int = og.body_len; var segptr : Int = 0; var version : Int = og.version(); var continued : Int = og.continued(); var bos : Int = og.bos(); var eos : Int = og.eos(); var granulepos : Int = og.granulepos(); var _serialno : Int = og.serialno(); var _pageno : Int = og.pageno(); var segments : Int = header_base[header + 26] & 0xff; var lr : Int = lacing_returned; var br : Int = body_returned; if (br != 0) { body_fill -= br; if (body_fill != 0) { System.bytescopy(body_data, br, body_data, 0, body_fill); }; body_returned = 0; }; if (lr != 0) { if ((lacing_fill - lr) != 0) { //System.arraycopyV(lacing_vals, lr, lacing_vals, 0, // lacing_fill - lr); lacing_vals = VectorTools.copyI(lacing_vals, lr, lacing_vals, 0, lacing_fill - lr); //System.arraycopyV(granule_vals, lr, granule_vals, 0, // lacing_fill - lr); granule_vals = VectorTools.copyI(granule_vals, lr, granule_vals, 0, lacing_fill - lr); }; lacing_fill -= lr; lacing_packet -= lr; lacing_returned = 0; }; if (_serialno != serialno) { return -1; }; if (version > 0) { return -1; }; lacing_expand(segments + 1); if (_pageno != pageno) { var i : Int; // for-while; i = lacing_packet; while (i < lacing_fill) { body_fill -= (lacing_vals[i] & 0xff); i++; }; lacing_fill = lacing_packet; if (pageno != -1) { lacing_vals[lacing_fill++] = 0x400; lacing_packet++; }; if (continued != 0) { bos = 0; // for-while; while (segptr < segments) { var val : Int = header_base[(header + 27) + segptr] & 0xff; body += val; bodysize -= val; if (val < 255) { segptr++; break; }; segptr++; }; }; }; if (bodysize != 0) { body_expand(bodysize); System.bytescopy(body_base, body, body_data, body_fill, bodysize); body_fill += bodysize; }; var saved : Int = -1; while (segptr < segments) { var val : Int = header_base[(header + 27) + segptr] & 0xff; lacing_vals[lacing_fill] = val; granule_vals[lacing_fill] = -1; if (bos != 0) { lacing_vals[lacing_fill] |= 0x100; bos = 0; }; if (val < 255) { saved = lacing_fill; }; lacing_fill++; segptr++; if (val < 255) { lacing_packet = lacing_fill; }; }; if (saved != -1) { granule_vals[saved] = granulepos; }; if (eos != 0) { e_o_s = 1; if (lacing_fill > 0) { lacing_vals[lacing_fill - 1] |= 0x200; }; }; pageno = (_pageno + 1); return 0; } // modifiers: public public function flush(og : Page) : Int { var i : Int; var vals : Int = 0; var maxvals : Int = (lacing_fill > 255 ? 255 : lacing_fill); var bytes : Int = 0; var acc : Int = 0; var granule_pos : Int = granule_vals[0]; if (maxvals == 0) { return 0; }; if (b_o_s == 0) { granule_pos = 0; // for-while; vals = 0; while (vals < maxvals) { if ((lacing_vals[vals] & 0x0ff) < 255) { vals++; break; }; vals++; }; } else { // for-while; vals = 0; while (vals < maxvals) { if (acc > 4096) { break; }; acc += (lacing_vals[vals] & 0x0ff); granule_pos = granule_vals[vals]; vals++; }; }; System.bytescopy(haxe.io.Bytes.ofString("OggS").getData(), 0, header, 0, 4); header[4] = 0x00; header[5] = 0x00; if ((lacing_vals[0] & 0x100) == 0) { header[5] |= 0x01; }; if (b_o_s == 0) { header[5] |= 0x02; }; if ((e_o_s != 0) && (lacing_fill == vals)) { header[5] |= 0x04; }; b_o_s = 1; // for-while; i = 6; while (i < 14) { header[i] = granule_pos; granule_pos >>>= 8; i++; }; var _serialno : Int = serialno; // for-while; i = 14; while (i < 18) { header[i] = _serialno; _serialno >>>= 8; i++; }; if (pageno == -1) { pageno = 0; }; var _pageno : Int = pageno++; // for-while; i = 18; while (i < 22) { header[i] = _pageno; _pageno >>>= 8; i++; }; header[22] = 0; header[23] = 0; header[24] = 0; header[25] = 0; header[26] = vals; // for-while; i = 0; while (i < vals) { header[i + 27] = lacing_vals[i]; bytes += (header[i + 27] & 0xff); i++; }; og.header_base = header; og.header = 0; og.header_len = (header_fill = (vals + 27)); og.body_base = body_data; og.body = body_returned; og.body_len = bytes; lacing_fill -= vals; //System.arraycopyV(lacing_vals, vals, lacing_vals, 0, lacing_fill * 4); lacing_vals = VectorTools.copyI(lacing_vals, vals, lacing_vals, 0, lacing_fill * 4); //System.arraycopyV(granule_vals, vals, granule_vals, 0, lacing_fill * 8); granule_vals = VectorTools.copyI(granule_vals, vals, granule_vals, 0, lacing_fill * 8); body_returned += bytes; og.checksum(); return 1; } // modifiers: public public function pageout(og : Page) : Int { if (((((e_o_s != 0) && (lacing_fill != 0)) || ((body_fill - body_returned) > 4096)) || (lacing_fill >= 255)) || ((lacing_fill != 0) && (b_o_s == 0))) { return flush(og); }; return 0; } // modifiers: public public function eof() : Int { return e_o_s; } // modifiers: public public function reset() : Int { body_fill = 0; body_returned = 0; lacing_fill = 0; lacing_packet = 0; lacing_returned = 0; header_fill = 0; e_o_s = 0; b_o_s = 0; pageno = -1; packetno = 0; granulepos = 0; return 0; } // modifiers: inline public function init(?serialno : Int) : Void { // FIXME: implement disambiguation handler; // __init_0() : Void; // __init_1(serialno : Int) : Void; //throw "NotImplementedError"; if (serialno == null) __init_0(); else __init_1(serialno); } // modifiers: inline,public public function new(?serialno : Int) { // FIXME: implement disambiguation handler; // __new_0() : None; // __new_1(serialno : Int) : None; //throw "NotImplementedError"; if (serialno == null) __new_0(); else __new_1(serialno); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fogg/SyncState.hx000066400000000000000000000131621454362722700272750ustar00rootroot00000000000000package org.xiph.fogg; import org.xiph.system.Bytes; class SyncState { /* * generated source for SyncState */ public var data : Bytes; var storage : Int; var fill : Int; var returned : Int; var unsynced : Int; var headerbytes : Int; var bodybytes : Int; // modifiers: public public function clear() : Int { data = null; return 0; } // modifiers: public public function buffer(size : Int) : Int { if (returned != 0) { fill -= returned; if (fill > 0) { System.bytescopy(data, returned, data, 0, fill); }; returned = 0; }; if (size > (storage - fill)) { var newsize : Int = (size + fill) + 4096; if (data != null) { // var foo : Bytes = System.alloc(newsize); // System.arraycopy(data, 0, foo, 0, data.length); // data = foo; System.resize(data, newsize); } else{ data = System.alloc(newsize); }; storage = newsize; }; return fill; } // modifiers: public public function wrote(bytes : Int) : Int { if ((fill + bytes) > storage) { return -1; }; fill += bytes; return 0; } // discarded initializer: 'Page()'; private var _pageseek : Page; // discarded initializer: 'Bytes.alloc(4)'; private var chksum : Bytes; // modifiers: public public function pageseek(og : Page) : Int { // FIXME: shadows variable 'pageseek'; var page : Int = returned; var next : Int; var bytes : Int = fill - returned; if (headerbytes == 0) { var _headerbytes : Int; var i : Int; if (bytes < 27) { return 0; }; if ((((data[page] != 'O'.charCodeAt(0)) || (data[page + 1] != 'g'.charCodeAt(0))) || (data[page + 2] != 'g'.charCodeAt(0))) || (data[page + 3] != 'S'.charCodeAt(0))) { headerbytes = 0; bodybytes = 0; next = 0; // for-while; var ii : Int = 0; while (ii < (bytes - 1)) { if (data[(page + 1) + ii] == 'O'.charCodeAt(0)) { next = ((page + 1) + ii); break; }; ii++; }; if (next == 0) { next = fill; }; returned = next; return -(next - page); }; _headerbytes = ((data[page + 26] & 0xff) + 27); if (bytes < _headerbytes) { return 0; }; i = 0; while (i < (data[page + 26] & 0xff)) { bodybytes += (data[(page + 27) + i] & 0xff); i++; }; headerbytes = _headerbytes; }; if ((bodybytes + headerbytes) > bytes) { return 0; }; // synchronized (chksum) ...; { System.bytescopy(data, page + 22, chksum, 0, 4); data[page + 22] = 0; data[page + 23] = 0; data[page + 24] = 0; data[page + 25] = 0; var log : Page = _pageseek; log.header_base = data; log.header = page; log.header_len = headerbytes; log.body_base = data; log.body = (page + headerbytes); log.body_len = bodybytes; log.checksum(); if ((((chksum[0] != data[page + 22]) || (chksum[1] != data[page + 23])) || (chksum[2] != data[page + 24])) || (chksum[3] != data[page + 25])) { System.bytescopy(chksum, 0, data, page + 22, 4); headerbytes = 0; bodybytes = 0; next = 0; // for-while; var ii : Int = 0; while (ii < (bytes - 1)) { if (data[(page + 1) + ii] == 'O'.charCodeAt(0)) { next = ((page + 1) + ii); break; }; ii++; }; if (next == 0) { next = fill; }; returned = next; return -(next - page); }; }; page = returned; if (og != null) { og.header_base = data; og.header = page; og.header_len = headerbytes; og.body_base = data; og.body = (page + headerbytes); og.body_len = bodybytes; }; unsynced = 0; returned += (bytes = (headerbytes + bodybytes)); headerbytes = 0; bodybytes = 0; return bytes; } // modifiers: public public function pageout(og : Page) : Int { while (true) { var ret : Int = pageseek(og); if (ret > 0) { return 1; }; if (ret == 0) { return 0; }; if (unsynced == 0) { unsynced = 1; return -1; }; }; return -1; // ??!... } // modifiers: public public function reset() : Int { fill = 0; returned = 0; unsynced = 0; headerbytes = 0; bodybytes = 0; return 0; } // modifiers: public public function init() : Void { reset(); storage = 0; } public function new() { _pageseek = new Page(); chksum = System.alloc(4); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/foggy/000077500000000000000000000000001454362722700252055ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/foggy/Demuxer.hx000066400000000000000000000113341454362722700271610ustar00rootroot00000000000000package org.xiph.foggy; import org.xiph.system.Bytes; import org.xiph.fogg.SyncState; import org.xiph.fogg.StreamState; import org.xiph.fogg.Page; import org.xiph.fogg.Packet; import flash.utils.IDataInput; enum DemuxerStatus { dmx_ok; dmx_stop; } class Demuxer { public static inline var ENOTOGG = -1; var oy : SyncState; //var os : StreamState; var og : Page; var op : Packet; var streams : Map; var bos_done : Bool; var page_cbs : Map Int -> DemuxerStatus>; var packet_cbs : Map Int -> DemuxerStatus>; public function new() { page_cbs = new Map Int -> DemuxerStatus>(); packet_cbs = new Map Int -> DemuxerStatus>(); streams = new Map(); bos_done = false; oy = new SyncState(); //os = new StreamState(); og = new Page(); op = new Packet(); oy.init(); } public function set_page_cb(serialno : Int, cb : Page -> Int -> DemuxerStatus) : Void { if (serialno != -1 && !streams.exists(serialno)) { // TODO: throw and exception? } else { page_cbs.set(serialno, cb); } } public function remove_page_cb(serialno : Int) : Void { page_cbs.remove(serialno); } public function set_packet_cb(serialno : Int, cb : Packet -> Int -> DemuxerStatus) : Void { if (serialno != -1 && !streams.exists(serialno)) { // TODO: throw and exception? trace("*** HERE ***"); trace("streams: " + streams.toString()); } else { packet_cbs.set(serialno, cb); } } public function remove_packet_cb(serialno : Int) : Void { packet_cbs.remove(serialno); } //public function read(data : Bytes, len : Int, pos : Int = -1) : Int { public function read(data : IDataInput, len : Int, pos : Int = -1) : Int { // TODO: handle len as end_of_data? var buffer : Bytes; var ret : Int; var index : Int = oy.buffer(len); buffer = oy.data; if (pos != -1) { //data.position = pos; } data.readBytes(buffer, index, len); oy.wrote(len); while (true) { if ((ret = oy.pageout(og)) != 1) { if (buffer.length < 16384 || ret == 0) return len; else { return ENOTOGG; } } _process_page(og); // TODO: check for returns from _process_page() } return len; } private function _process_page(p : Page) : Int { var sn = p.serialno(); var cbret : DemuxerStatus; var ret : Int; var cb : Page -> Int -> DemuxerStatus; cb = page_cbs.get(sn); if (cb == null) { //trace("cb==0"); cb = page_cbs.get(-1); } if (cb != null) { cbret = cb(p, sn); trace("cb!=null; "+cbret); // TODO handle stop request } var os : StreamState = streams.get(sn); if (os == null) { /*if (bos_done) { // unexpected new stream trace("unexpected end of stream"); return -1; }*/ bos_done = false; os = new StreamState(); os.init(sn); streams.set(sn, os); } else { // end of bos pages? handle!... // trace("end of bos"); if (!bos_done) { bos_done = true; } } if (os.pagein(p) < 0) { // can happen on an unsupported version trace("unsupported ver"); return -1; } while (true) { if ((ret = os.packetout(op)) != 1) { if (ret == 0) break; } else { _process_packet(op, sn); } } if (p.eos() != 0) { //trace("eos detected"); os.clear(); streams.remove(sn); if (!streams.iterator().hasNext()) { bos_done = false; // we're ready for new chained streams } } return 0; } private function _process_packet(p : Packet, sn : Int) : Int { var ret : Int; var cbret : DemuxerStatus; var cb : Packet -> Int -> DemuxerStatus; cb = packet_cbs.get(sn); if (cb == null) { cb = packet_cbs.get(-1); } if (cb != null) { cbret = cb(p, sn); // TODO handle stop request } return 0; } }autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/ftremor/000077500000000000000000000000001454362722700255505ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/ftremor/Mdct.hx000066400000000000000000001560311454362722700270060ustar00rootroot00000000000000package org.xiph.ftremor; class Mdct { /* At the moment we're using the low accuracy mode, because the lack of ready/builtin 64-bit int operations... */ // #if lowacc inline static var cPI3_8 : Int = 0x0062; inline static var cPI2_8 : Int = 0x00b5; inline static var cPI1_8 : Int = 0x00ed; inline function MULT32(x : Int, y : Int) : Int { return (x >> 9) * y; // preshifted y >>23 } inline function MULT31(x : Int, y : Int) : Int { return (x >> 8) * y; // preshifted y >>23 } inline function MULT31_SHIFT15(x : Int, y : Int) : Int { return (x >> 6) * y; // preshifted y >>9 } // #end inline function XPROD32(a : Int, b : Int, t : Int, v : Int, x : Array, ix : Int, y : Array, iy : Int) { x[ix] = MULT32(a, t) + MULT32(b, v); y[iy] = MULT32(b, t) - MULT32(a, v); } inline function XPROD31(a : Int, b : Int, t : Int, v : Int, x : Array, ix : Int, y : Array, iy : Int) { x[ix] = MULT31(a, t) + MULT31(b, v); y[iy] = MULT31(b, t) - MULT31(a, v); } inline function XNPROD31(a : Int, b : Int, t : Int, v : Int, x : Array, ix : Int, y : Array, iy : Int) { x[ix] = MULT31(a, t) - MULT31(b, v); y[iy] = MULT31(b, t) + MULT31(a, v); } inline function butterfly_8(x : Array, i : Int) : Void { var r0 : Int = x[i + 4] + x[i + 0]; var r1 : Int = x[i + 4] - x[i + 0]; var r2 : Int = x[i + 5] + x[i + 1]; var r3 : Int = x[i + 5] - x[i + 1]; var r4 : Int = x[i + 6] + x[i + 2]; var r5 : Int = x[i + 6] - x[i + 2]; var r6 : Int = x[i + 7] + x[i + 3]; var r7 : Int = x[i + 7] - x[i + 3]; x[i + 0] = r5 + r3; x[i + 1] = r7 - r1; x[i + 2] = r5 - r3; x[i + 3] = r7 + r1; x[i + 4] = r4 - r0; x[i + 5] = r6 - r2; x[i + 6] = r4 + r0; x[i + 7] = r6 + r2; } inline function butterfly_16(x : Array, i : Int) : Void { var r0 : Int; var r1 : Int; r0 = x[i + 0] - x[i + 8]; x[i + 8] += x[i + 0]; r1 = x[i + 1] - x[i + 9]; x[i + 9] += x[i + 1]; x[i + 0] = MULT31((r0 + r1), cPI2_8); x[i + 1] = MULT31((r1 - r0), cPI2_8); r0 = x[i + 10] - x[i + 2]; x[i + 10] += x[i + 2]; r1 = x[i + 3] - x[i + 11]; x[i + 11] += x[i + 3]; x[i + 2] = r1; x[i + 3] = r0; r0 = x[i + 12] - x[i + 4]; x[i + 12] += x[i + 4]; r1 = x[i + 13] - x[i + 5]; x[i + 13] += x[i + 5]; x[i + 4] = MULT31((r0 - r1), cPI2_8); x[i + 5] = MULT31((r0 + r1), cPI2_8); r0 = x[i + 14] - x[i + 6]; x[i + 14] += x[i + 6]; r1 = x[i + 15] - x[i + 7]; x[i + 15] += x[i + 7]; x[i + 6] = r0; x[i + 7] = r1; butterfly_8(x, i); butterfly_8(x, i + 8); } inline function butterfly_32(x : Array, i : Int) : Void { var r0 : Int; var r1 : Int; r0 = x[i + 30] - x[i + 14]; x[i + 30] += x[i + 14]; r1 = x[i + 31] - x[i + 15]; x[i + 31] += x[i + 15]; x[i + 14] = r0; x[i + 15] = r1; r0 = x[i + 28] - x[i + 12]; x[i + 28] += x[i + 12]; r1 = x[i + 29] - x[i + 13]; x[i + 29] += x[i + 13]; XNPROD31(r0, r1, cPI1_8, cPI3_8, x, i + 12, x, i + 13); r0 = x[i + 26] - x[i + 10]; x[i + 26] += x[i + 10]; r1 = x[i + 27] - x[i + 11]; x[i + 27] += x[i + 11]; x[i + 10] = MULT31((r0 - r1) , cPI2_8); x[i + 11] = MULT31((r0 + r1) , cPI2_8); r0 = x[i + 24] - x[i + 8]; x[i + 24] += x[i + 8]; r1 = x[i + 25] - x[i + 9]; x[i + 25] += x[i + 9]; XNPROD31(r0, r1, cPI3_8, cPI1_8, x, i + 8, x, i + 9); r0 = x[i + 22] - x[i + 6]; x[i + 22] += x[i + 6]; r1 = x[i + 7] - x[i + 23]; x[i + 23] += x[i + 7]; x[i + 6] = r1; x[i + 7] = r0; r0 = x[i + 4] - x[i + 20]; x[i + 20] += x[i + 4]; r1 = x[i + 5] - x[i + 21]; x[i + 21] += x[i + 5]; XPROD31(r0, r1, cPI3_8, cPI1_8, x, i + 4, x, i + 5); r0 = x[i + 2] - x[i + 18]; x[i + 18] += x[i + 2]; r1 = x[i + 3] - x[i + 19]; x[i + 19] += x[i + 3]; x[i + 2] = MULT31((r1 + r0) , cPI2_8); x[i + 3] = MULT31((r1 - r0) , cPI2_8); r0 = x[i + 0] - x[i + 16]; x[i + 16] += x[i + 0]; r1 = x[i + 1] - x[i + 17]; x[i + 17] += x[i + 1]; XPROD31(r0, r1, cPI1_8, cPI3_8, x, i /*+ 0*/, x, i + 1); butterfly_16(x, i); butterfly_16(x, i + 16); } /* N/stage point generic N stage butterfly (in place, 2 register) */ /* inline */ function butterfly_generic(x : Array, i : Int, points : Int, step : Int) : Void { var T : Array = sincos_lookup0; var iT0 : Int = 0; var iT1 : Int = 1; var i1 : Int = i + (points - 8); var i2 : Int = i + ((points >> 1) - 8); var r0 : Int; var r1 : Int; do { r0 = x[i1 + 6] - x[i2 + 6]; x[i1 + 6] += x[i2 + 6]; r1 = x[i2 + 7] - x[i1 + 7]; x[i1 + 7] += x[i2 + 7]; XPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 6, x, i2 + 7); iT0 += step; iT1 += step; r0 = x[i1 + 4] - x[i2 + 4]; x[i1 + 4] += x[i2 + 4]; r1 = x[i2 + 5] - x[i1 + 5]; x[i1 + 5] += x[i2 + 5]; XPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 4, x, i2 + 5); iT0 += step; iT1 += step; r0 = x[i1 + 2] - x[i2 + 2]; x[i1 + 2] += x[i2 + 2]; r1 = x[i2 + 3] - x[i1 + 3]; x[i1 + 3] += x[i2 + 3]; XPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 2, x, i2 + 3); iT0 += step; iT1 += step; r0 = x[i1 + 0] - x[i2 + 0]; x[i1 + 0] += x[i2 + 0]; r1 = x[i2 + 1] - x[i1 + 1]; x[i1 + 1] += x[i2 + 1]; XPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 0, x, i2 + 1); iT0 += step; iT1 += step; i1 -= 8; i2 -= 8; } while (iT0 < 1024); do { r0 = x[i1 + 6] - x[i2 + 6]; x[i1 + 6] += x[i2 + 6]; r1 = x[i1 + 7] - x[i2 + 7]; x[i1 + 7] += x[i2 + 7]; XNPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 6, x, i2 + 7); iT0 -= step; iT1 -= step; r0 = x[i1 + 4] - x[i2 + 4]; x[i1 + 4] += x[i2 + 4]; r1 = x[i1 + 5] - x[i2 + 5]; x[i1 + 5] += x[i2 + 5]; XNPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 4, x, i2 + 5); iT0 -= step; iT1 -= step; r0 = x[i1 + 2] - x[i2 + 2]; x[i1 + 2] += x[i2 + 2]; r1 = x[i1 + 3] - x[i2 + 3]; x[i1 + 3] += x[i2 + 3]; XNPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 2, x, i2 + 3); iT0 -= step; iT1 -= step; r0 = x[i1 + 0] - x[i2 + 0]; x[i1 + 0] += x[i2 + 0]; r1 = x[i1 + 1] - x[i2 + 1]; x[i1 + 1] += x[i2 + 1]; XNPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 0, x, i2 + 1); iT0 -= step; iT1 -= step; i1 -= 8; i2 -= 8; } while (iT0 > 0); do { r0 = x[i2 + 6] - x[i1 + 6]; x[i1 + 6] += x[i2 + 6]; r1 = x[i2 + 7] - x[i1 + 7]; x[i1 + 7] += x[i2 + 7]; XPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 6, x, i2 + 7); iT0 += step; iT1 += step; r0 = x[i2 + 4] - x[i1 + 4]; x[i1 + 4] += x[i2 + 4]; r1 = x[i2 + 5] - x[i1 + 5]; x[i1 + 5] += x[i2 + 5]; XPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 4, x, i2 + 5); iT0 += step; iT1 += step; r0 = x[i2 + 2] - x[i1 + 2]; x[i1 + 2] += x[i2 + 2]; r1 = x[i2 + 3] - x[i1 + 3]; x[i1 + 3] += x[i2 + 3]; XPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 2, x, i2 + 3); iT0 += step; iT1 += step; r0 = x[i2 + 0] - x[i1 + 0]; x[i1 + 0] += x[i2 + 0]; r1 = x[i2 + 1] - x[i1 + 1]; x[i1 + 1] += x[i2 + 1]; XPROD31(r0, r1, T[iT0], T[iT1], x, i2 + 0, x, i2 + 1); iT0 += step; iT1 += step; i1 -= 8; i2 -= 8; } while (iT0 < 1024); do{ r0 = x[i1 + 6] - x[i2 + 6]; x[i1 + 6] += x[i2 + 6]; r1 = x[i2 + 7] - x[i1 + 7]; x[i1 + 7] += x[i2 + 7]; XNPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 6, x, i2 + 7); iT0 -= step; iT1 -= step; r0 = x[i1 + 4] - x[i2 + 4]; x[i1 + 4] += x[i2 + 4]; r1 = x[i2 + 5] - x[i1 + 5]; x[i1 + 5] += x[i2 + 5]; XNPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 4, x, i2 + 5); iT0 -= step; iT1 -= step; r0 = x[i1 + 2] - x[i2 + 2]; x[i1 + 2] += x[i2 + 2]; r1 = x[i2 + 3] - x[i1 + 3]; x[i1 + 3] += x[i2 + 3]; XNPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 2, x, i2 + 3); iT0 -= step; iT1 -= step; r0 = x[i1 + 0] - x[i2 + 0]; x[i1 + 0] += x[i2 + 0]; r1 = x[i2 + 1] - x[i1 + 1]; x[i1 + 1] += x[i2 + 1]; XNPROD31(r1, r0, T[iT0], T[iT1], x, i2 + 0, x, i2 + 1); iT0 -= step; iT1 -= step; i1 -= 8; i2 -= 8; } while (iT0 > 0); } inline function butterflies(x : Array, i : Int, points : Int, shift : Int) : Void { var stages : Int = 8 - shift; var j : Int, k : Int; j = 0; while (--stages > 0) { k = 0; while (k < (1<> j) * k, points >> j, 4 << (j + shift)); k++; } j++; } j = 0; while (j < points) { butterfly_32(x, i + j); j += 32; } } static inline var bitrev : Array = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]; inline function bitrev12(x : Int) : Int { return bitrev[x>>8] | (bitrev[(x & 0x0f0) >> 4] << 4) | (bitrev[x & 0x00f] << 8); } /* inline */ function bitreverse(x : Array, i : Int, n : Int, step : Int, shift : Int) : Void { var bit : Int = 0; var w0 : Int = i; var w1 : Int = i = w0 + (n >> 1); var T : Array; var iT0 : Int, iT1 : Int, iTtop : Int; var r2 : Array = [0]; if (step >= 4) { T = sincos_lookup0; iT0 = step >> 1; } else { T = sincos_lookup1; iT0 = 0; } iT1 = iT0 + 1; iTtop = iT0 + 1024; do { var r3 : Array = [bitrev12(bit++)]; var i0 : Int = i + ((r3[0] ^ 0xfff) >> shift) - 1; var i1 : Int = i + (r3[0] >> shift); var r0 : Int = x[i0 /* + 0*/] + x[i1 /* + 0*/]; var r1 : Int = x[i1 + 1] - x[i0 + 1]; XPROD32(r0, r1, T[iT1], T[iT0], r2, 0, r3, 0); iT0 += step; iT1 += step; w1 -= 4; r0 = (x[i0 + 1] + x[i1 + 1]) >> 1; r1 = (x[i0] - x[i1]) >> 1; x[w0 + 0] = r0 + r2[0]; x[w0 + 1] = r1 + r3[0]; x[w1 + 2] = r0 - r2[0]; x[w1 + 3] = r3[0] - r1; r3[0] = bitrev12(bit++); i0 = i + ((r3[0] ^ 0xfff) >> shift) - 1; i1 = i + (r3[0] >> shift); r0 = x[i0] + x[i1]; r1 = x[i1 + 1] - x[i0 + 1]; XPROD32(r0, r1, T[iT1], T[iT0], r2, 0, r3, 0); iT0 += step; iT1 += step; r0 = (x[i0 + 1] + x[i1 + 1]) >> 1; r1 = (x[i0] - x[i1]) >> 1; x[w0 + 2] = r0 + r2[0]; x[w0 + 3] = r1 + r3[0]; x[w1 + 0] = r0 - r2[0]; x[w1 + 1] = r3[0] - r1; w0 += 4; } while (iT0 < iTtop); do { var r3 : Array = [bitrev12(bit++)]; var i0 : Int = i + ((r3[0] ^ 0xfff) >> shift) - 1; var i1 : Int = i + (r3[0] >> shift); var r0 : Int = x[i0] + x[i1]; var r1 : Int = x[i1 + 1] - x[i0 + 1]; iT0 -= step; iT1 -= step; XPROD32(r0, r1, T[iT0], T[iT1], r2, 0, r3, 0); w1 -= 4; r0 = (x[i0 + 1] + x[i1 + 1]) >> 1; r1 = (x[i0] - x[i1]) >> 1; x[w0 + 0] = r0 + r2[0]; x[w0 + 1] = r1 + r3[0]; x[w1 + 2] = r0 - r2[0]; x[w1 + 3] = r3[0] - r1; r3[0] = bitrev12(bit++); i0 = i + ((r3[0] ^ 0xfff) >> shift) - 1; i1 = i + (r3[0] >> shift); r0 = x[i0] + x[i1]; r1 = x[i1 + 1] - x[i0 + 1]; iT0 -= step; iT1 -= step; XPROD32(r0, r1, T[iT0], T[iT1], r2, 0, r3, 0); r0 = (x[i0 + 1] + x[i1 + 1]) >> 1; r1 = (x[i0] - x[i1]) >> 1; x[w0 + 2] = r0 + r2[0]; x[w0 + 3] = r1 + r3[0]; x[w1 + 0] = r0 - r2[0]; x[w1 + 1] = r3[0] - r1; w0 += 4; } while (w0 < w1); } public function backward(n : Int, in_ : Array, out : Array) : Void { var i : Int = 0; var o : Int = 0; var n2 : Int = n >> 1; var n4 : Int = n >> 2; var iX : Int; var oX : Int; var T : Array; var V : Array; var shift : Int; var step : Int; var iT0 : Int = 0; var iT1 : Int = 1; shift = 6; while ((n & (1 << shift)) == 0) { shift++; } shift = 13 - shift; step = 2 << shift; /* rotate */ iX = i + n2 - 7; oX = o + n2 + n4; T = sincos_lookup0; do { oX -= 4; XPROD31(in_[iX + 4], in_[iX + 6], T[iT0], T[iT1], out, oX + 2, out, oX + 3); iT0 += step; iT1 += step; XPROD31(in_[iX + 0], in_[iX + 2], T[iT0], T[iT1], out, oX + 0, out, oX + 1); iT0 += step; iT1 += step; iX -= 8; } while (iX >= i + n4); do { oX -= 4; XPROD31(in_[iX + 4], in_[iX + 6], T[iT1], T[iT0], out, oX + 2, out, oX + 3); iT0 -= step; iT1 -= step; XPROD31(in_[iX + 0], in_[iX + 2], T[iT1], T[iT0], out, oX + 0, out, oX + 1); iT0 -= step; iT1 -= step; iX -= 8; } while (iX >= i); iX = i + n2 - 8; oX = o + n2 + n4; T = sincos_lookup0; iT0 = 0; iT1 = 1; do { iT0 += step; iT1 += step; XPROD31(in_[iX + 6], in_[iX + 4], T[iT0], T[iT1], out, oX + 0, out, oX + 1); iT0 += step; iT1 += step; XPROD31(in_[iX + 2], in_[iX + 0], T[iT0], T[iT1], out, oX + 2, out, oX + 3); iX -= 8; oX += 4; } while (iX >= i + n4); do { iT0 -= step; iT1 -= step; XPROD31(in_[iX + 6], in_[iX + 4], T[iT1], T[iT0], out, oX + 0, out, oX + 1); iT0 -= step; iT1 -= step; XPROD31(in_[iX + 2], in_[iX + 0], T[iT1], T[iT0], out, oX + 2, out, oX + 3); iX -= 8; oX += 4; } while (iX >= i); butterflies(out, o + n2, n2, shift); bitreverse(out, o, n, step, shift); /* rotate + window */ step >>= 2; { var oX1 : Int = o + n2 + n4; var oX2 : Int = o + n2 + n4; var iX : Int = o; switch(step) { default: { if (step >= 4) { T = sincos_lookup0; iT0 = step >> 1; } else { T = sincos_lookup1; iT0 = 0; } iT1 = iT0 + 1; do { oX1 -= 4; XPROD31(out[iX + 0], - out[iX + 1], T[iT0], T[iT1], out, oX1 + 3, out, oX2 + 0); iT0 += step; iT1 += step; XPROD31(out[iX + 2], - out[iX + 3], T[iT0], T[iT1], out, oX1 + 2, out, oX2 + 1); iT0 += step; iT1 += step; XPROD31(out[iX + 4], - out[iX + 5], T[iT0], T[iT1], out, oX1 + 1, out, oX2 + 2); iT0 += step; iT1 += step; XPROD31(out[iX + 6], - out[iX + 7], T[iT0], T[iT1], out, oX1 + 0, out, oX2 + 3); iT0 += step; iT1 += step; oX2 += 4; iX += 8; } while (iX < oX1); } case 1: { /* linear interpolation between table values: offset=0.5, step=1 */ var t0 : Int, t1 : Int, v0 : Int, v1 : Int; T = sincos_lookup0; V = sincos_lookup1; var iT : Int = 0; var iV : Int = 0; t0 = T[iT++] >> 1; t1 = T[iT++] >> 1; do { oX1 -= 4; t0 += (v0 = (V[iV++]) >> 1); t1 += (v1 = (V[iV++]) >> 1); XPROD31(out[iX + 0], - out[iX + 1], t0, t1, out, oX1 + 3, out, oX2 + 0); v0 += (t0 = (T[iT++]) >> 1); v1 += (t1 = (T[iT++]) >> 1); XPROD31(out[iX + 2], - out[iX + 3], v0, v1, out, oX1 + 2, out, oX2 + 1); t0 += (v0 = (V[iV++]) >> 1); t1 += (v1 = (V[iV++]) >> 1); XPROD31(out[iX + 4], - out[iX + 5], t0, t1, out, oX1 + 1, out, oX2 + 2); v0 += (t0 = (T[iT++]) >> 1); v1 += (t1 = (T[iT++]) >> 1); XPROD31(out[iX + 6], - out[iX + 7], v0, v1, out, oX1 + 0, out, oX2 + 3); oX2 += 4; iX += 8; } while (iX < oX1); } case 0: { /* linear interpolation between table values: offset=0.25, step=0.5 */ var t0 : Int, t1 : Int, v0 : Int, v1 : Int, q0 : Int, q1 : Int; T = sincos_lookup0; V = sincos_lookup1; var iT : Int = 0; var iV : Int = 0; t0 = T[iT++]; t1 = T[iT++]; do { oX1 -= 4; v0 = V[iV++]; v1 = V[iV++]; t0 += (q0 = (v0 - t0) >> 2); t1 += (q1 = (v1 - t1) >> 2); XPROD31(out[iX + 0], - out[iX + 1], t0, t1, out, oX1 + 3, out, oX2 + 0); t0 = v0 - q0; t1 = v1 - q1; XPROD31(out[iX + 2], - out[iX + 3], t0, t1, out, oX1 + 2, out, oX2 + 1); t0 = T[iT++]; t1 = T[iT++]; v0 += (q0 = (t0 - v0) >> 2); v1 += (q1 = (t1 - v1) >> 2); XPROD31(out[iX + 4], - out[iX + 5], v0, v1, out, oX1 + 1, out, oX2 + 2); v0 = t0 - q0; v1 = t1 - q1; XPROD31(out[iX + 6], - out[iX + 7], v0, v1, out, oX1 + 0, out, oX2 + 3); oX2 += 4; iX += 8; } while (iX < oX1); } } iX = o + n2 + n4; oX1 = o + n4; oX2 = oX1; do { oX1 -= 4; iX -= 4; out[oX2 + 0] = -(out[oX1 + 3] = out[iX + 3]); out[oX2 + 1] = -(out[oX1 + 2] = out[iX + 2]); out[oX2 + 2] = -(out[oX1 + 1] = out[iX + 1]); out[oX2 + 3] = -(out[oX1 + 0] = out[iX + 0]); oX2 += 4; } while (oX2 < iX); iX = o + n2 + n4; oX1 = o + n2 + n4; oX2 = o + n2; do { oX1 -= 4; out[oX1 + 0]= out[iX + 3]; out[oX1 + 1]= out[iX + 2]; out[oX1 + 2]= out[iX + 1]; out[oX1 + 3]= out[iX + 0]; iX += 4; } while (oX1 > oX2); } } public function new() { } // #if lowacc static inline function X(n : Int) : Int { return (((n >> 22) + 1) >> 1) - (((n >> 22) + 1) >> 9); } // #end public function init_lookup() : Void { sincos_lookup0 = _sincos_lookup0; sincos_lookup1 = _sincos_lookup1; } var sincos_lookup0 : Array; var sincos_lookup1 : Array; /* {sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */ static var _sincos_lookup0 : Array = [ X(0x00000000), X(0x7fffffff), X(0x003243f5), X(0x7ffff621), X(0x006487e3), X(0x7fffd886), X(0x0096cbc1), X(0x7fffa72c), X(0x00c90f88), X(0x7fff6216), X(0x00fb5330), X(0x7fff0943), X(0x012d96b1), X(0x7ffe9cb2), X(0x015fda03), X(0x7ffe1c65), X(0x01921d20), X(0x7ffd885a), X(0x01c45ffe), X(0x7ffce093), X(0x01f6a297), X(0x7ffc250f), X(0x0228e4e2), X(0x7ffb55ce), X(0x025b26d7), X(0x7ffa72d1), X(0x028d6870), X(0x7ff97c18), X(0x02bfa9a4), X(0x7ff871a2), X(0x02f1ea6c), X(0x7ff75370), X(0x03242abf), X(0x7ff62182), X(0x03566a96), X(0x7ff4dbd9), X(0x0388a9ea), X(0x7ff38274), X(0x03bae8b2), X(0x7ff21553), X(0x03ed26e6), X(0x7ff09478), X(0x041f6480), X(0x7feeffe1), X(0x0451a177), X(0x7fed5791), X(0x0483ddc3), X(0x7feb9b85), X(0x04b6195d), X(0x7fe9cbc0), X(0x04e8543e), X(0x7fe7e841), X(0x051a8e5c), X(0x7fe5f108), X(0x054cc7b1), X(0x7fe3e616), X(0x057f0035), X(0x7fe1c76b), X(0x05b137df), X(0x7fdf9508), X(0x05e36ea9), X(0x7fdd4eec), X(0x0615a48b), X(0x7fdaf519), X(0x0647d97c), X(0x7fd8878e), X(0x067a0d76), X(0x7fd6064c), X(0x06ac406f), X(0x7fd37153), X(0x06de7262), X(0x7fd0c8a3), X(0x0710a345), X(0x7fce0c3e), X(0x0742d311), X(0x7fcb3c23), X(0x077501be), X(0x7fc85854), X(0x07a72f45), X(0x7fc560cf), X(0x07d95b9e), X(0x7fc25596), X(0x080b86c2), X(0x7fbf36aa), X(0x083db0a7), X(0x7fbc040a), X(0x086fd947), X(0x7fb8bdb8), X(0x08a2009a), X(0x7fb563b3), X(0x08d42699), X(0x7fb1f5fc), X(0x09064b3a), X(0x7fae7495), X(0x09386e78), X(0x7faadf7c), X(0x096a9049), X(0x7fa736b4), X(0x099cb0a7), X(0x7fa37a3c), X(0x09cecf89), X(0x7f9faa15), X(0x0a00ece8), X(0x7f9bc640), X(0x0a3308bd), X(0x7f97cebd), X(0x0a6522fe), X(0x7f93c38c), X(0x0a973ba5), X(0x7f8fa4b0), X(0x0ac952aa), X(0x7f8b7227), X(0x0afb6805), X(0x7f872bf3), X(0x0b2d7baf), X(0x7f82d214), X(0x0b5f8d9f), X(0x7f7e648c), X(0x0b919dcf), X(0x7f79e35a), X(0x0bc3ac35), X(0x7f754e80), X(0x0bf5b8cb), X(0x7f70a5fe), X(0x0c27c389), X(0x7f6be9d4), X(0x0c59cc68), X(0x7f671a05), X(0x0c8bd35e), X(0x7f62368f), X(0x0cbdd865), X(0x7f5d3f75), X(0x0cefdb76), X(0x7f5834b7), X(0x0d21dc87), X(0x7f531655), X(0x0d53db92), X(0x7f4de451), X(0x0d85d88f), X(0x7f489eaa), X(0x0db7d376), X(0x7f434563), X(0x0de9cc40), X(0x7f3dd87c), X(0x0e1bc2e4), X(0x7f3857f6), X(0x0e4db75b), X(0x7f32c3d1), X(0x0e7fa99e), X(0x7f2d1c0e), X(0x0eb199a4), X(0x7f2760af), X(0x0ee38766), X(0x7f2191b4), X(0x0f1572dc), X(0x7f1baf1e), X(0x0f475bff), X(0x7f15b8ee), X(0x0f7942c7), X(0x7f0faf25), X(0x0fab272b), X(0x7f0991c4), X(0x0fdd0926), X(0x7f0360cb), X(0x100ee8ad), X(0x7efd1c3c), X(0x1040c5bb), X(0x7ef6c418), X(0x1072a048), X(0x7ef05860), X(0x10a4784b), X(0x7ee9d914), X(0x10d64dbd), X(0x7ee34636), X(0x11082096), X(0x7edc9fc6), X(0x1139f0cf), X(0x7ed5e5c6), X(0x116bbe60), X(0x7ecf1837), X(0x119d8941), X(0x7ec8371a), X(0x11cf516a), X(0x7ec14270), X(0x120116d5), X(0x7eba3a39), X(0x1232d979), X(0x7eb31e78), X(0x1264994e), X(0x7eabef2c), X(0x1296564d), X(0x7ea4ac58), X(0x12c8106f), X(0x7e9d55fc), X(0x12f9c7aa), X(0x7e95ec1a), X(0x132b7bf9), X(0x7e8e6eb2), X(0x135d2d53), X(0x7e86ddc6), X(0x138edbb1), X(0x7e7f3957), X(0x13c0870a), X(0x7e778166), X(0x13f22f58), X(0x7e6fb5f4), X(0x1423d492), X(0x7e67d703), X(0x145576b1), X(0x7e5fe493), X(0x148715ae), X(0x7e57dea7), X(0x14b8b17f), X(0x7e4fc53e), X(0x14ea4a1f), X(0x7e47985b), X(0x151bdf86), X(0x7e3f57ff), X(0x154d71aa), X(0x7e37042a), X(0x157f0086), X(0x7e2e9cdf), X(0x15b08c12), X(0x7e26221f), X(0x15e21445), X(0x7e1d93ea), X(0x16139918), X(0x7e14f242), X(0x16451a83), X(0x7e0c3d29), X(0x1676987f), X(0x7e0374a0), X(0x16a81305), X(0x7dfa98a8), X(0x16d98a0c), X(0x7df1a942), X(0x170afd8d), X(0x7de8a670), X(0x173c6d80), X(0x7ddf9034), X(0x176dd9de), X(0x7dd6668f), X(0x179f429f), X(0x7dcd2981), X(0x17d0a7bc), X(0x7dc3d90d), X(0x1802092c), X(0x7dba7534), X(0x183366e9), X(0x7db0fdf8), X(0x1864c0ea), X(0x7da77359), X(0x18961728), X(0x7d9dd55a), X(0x18c7699b), X(0x7d9423fc), X(0x18f8b83c), X(0x7d8a5f40), X(0x192a0304), X(0x7d808728), X(0x195b49ea), X(0x7d769bb5), X(0x198c8ce7), X(0x7d6c9ce9), X(0x19bdcbf3), X(0x7d628ac6), X(0x19ef0707), X(0x7d58654d), X(0x1a203e1b), X(0x7d4e2c7f), X(0x1a517128), X(0x7d43e05e), X(0x1a82a026), X(0x7d3980ec), X(0x1ab3cb0d), X(0x7d2f0e2b), X(0x1ae4f1d6), X(0x7d24881b), X(0x1b161479), X(0x7d19eebf), X(0x1b4732ef), X(0x7d0f4218), X(0x1b784d30), X(0x7d048228), X(0x1ba96335), X(0x7cf9aef0), X(0x1bda74f6), X(0x7ceec873), X(0x1c0b826a), X(0x7ce3ceb2), X(0x1c3c8b8c), X(0x7cd8c1ae), X(0x1c6d9053), X(0x7ccda169), X(0x1c9e90b8), X(0x7cc26de5), X(0x1ccf8cb3), X(0x7cb72724), X(0x1d00843d), X(0x7cabcd28), X(0x1d31774d), X(0x7ca05ff1), X(0x1d6265dd), X(0x7c94df83), X(0x1d934fe5), X(0x7c894bde), X(0x1dc4355e), X(0x7c7da505), X(0x1df5163f), X(0x7c71eaf9), X(0x1e25f282), X(0x7c661dbc), X(0x1e56ca1e), X(0x7c5a3d50), X(0x1e879d0d), X(0x7c4e49b7), X(0x1eb86b46), X(0x7c4242f2), X(0x1ee934c3), X(0x7c362904), X(0x1f19f97b), X(0x7c29fbee), X(0x1f4ab968), X(0x7c1dbbb3), X(0x1f7b7481), X(0x7c116853), X(0x1fac2abf), X(0x7c0501d2), X(0x1fdcdc1b), X(0x7bf88830), X(0x200d888d), X(0x7bebfb70), X(0x203e300d), X(0x7bdf5b94), X(0x206ed295), X(0x7bd2a89e), X(0x209f701c), X(0x7bc5e290), X(0x20d0089c), X(0x7bb9096b), X(0x21009c0c), X(0x7bac1d31), X(0x21312a65), X(0x7b9f1de6), X(0x2161b3a0), X(0x7b920b89), X(0x219237b5), X(0x7b84e61f), X(0x21c2b69c), X(0x7b77ada8), X(0x21f3304f), X(0x7b6a6227), X(0x2223a4c5), X(0x7b5d039e), X(0x225413f8), X(0x7b4f920e), X(0x22847de0), X(0x7b420d7a), X(0x22b4e274), X(0x7b3475e5), X(0x22e541af), X(0x7b26cb4f), X(0x23159b88), X(0x7b190dbc), X(0x2345eff8), X(0x7b0b3d2c), X(0x23763ef7), X(0x7afd59a4), X(0x23a6887f), X(0x7aef6323), X(0x23d6cc87), X(0x7ae159ae), X(0x24070b08), X(0x7ad33d45), X(0x243743fa), X(0x7ac50dec), X(0x24677758), X(0x7ab6cba4), X(0x2497a517), X(0x7aa8766f), X(0x24c7cd33), X(0x7a9a0e50), X(0x24f7efa2), X(0x7a8b9348), X(0x25280c5e), X(0x7a7d055b), X(0x2558235f), X(0x7a6e648a), X(0x2588349d), X(0x7a5fb0d8), X(0x25b84012), X(0x7a50ea47), X(0x25e845b6), X(0x7a4210d8), X(0x26184581), X(0x7a332490), X(0x26483f6c), X(0x7a24256f), X(0x26783370), X(0x7a151378), X(0x26a82186), X(0x7a05eead), X(0x26d809a5), X(0x79f6b711), X(0x2707ebc7), X(0x79e76ca7), X(0x2737c7e3), X(0x79d80f6f), X(0x27679df4), X(0x79c89f6e), X(0x27976df1), X(0x79b91ca4), X(0x27c737d3), X(0x79a98715), X(0x27f6fb92), X(0x7999dec4), X(0x2826b928), X(0x798a23b1), X(0x2856708d), X(0x797a55e0), X(0x288621b9), X(0x796a7554), X(0x28b5cca5), X(0x795a820e), X(0x28e5714b), X(0x794a7c12), X(0x29150fa1), X(0x793a6361), X(0x2944a7a2), X(0x792a37fe), X(0x29743946), X(0x7919f9ec), X(0x29a3c485), X(0x7909a92d), X(0x29d34958), X(0x78f945c3), X(0x2a02c7b8), X(0x78e8cfb2), X(0x2a323f9e), X(0x78d846fb), X(0x2a61b101), X(0x78c7aba2), X(0x2a911bdc), X(0x78b6fda8), X(0x2ac08026), X(0x78a63d11), X(0x2aefddd8), X(0x789569df), X(0x2b1f34eb), X(0x78848414), X(0x2b4e8558), X(0x78738bb3), X(0x2b7dcf17), X(0x786280bf), X(0x2bad1221), X(0x7851633b), X(0x2bdc4e6f), X(0x78403329), X(0x2c0b83fa), X(0x782ef08b), X(0x2c3ab2b9), X(0x781d9b65), X(0x2c69daa6), X(0x780c33b8), X(0x2c98fbba), X(0x77fab989), X(0x2cc815ee), X(0x77e92cd9), X(0x2cf72939), X(0x77d78daa), X(0x2d263596), X(0x77c5dc01), X(0x2d553afc), X(0x77b417df), X(0x2d843964), X(0x77a24148), X(0x2db330c7), X(0x7790583e), X(0x2de2211e), X(0x777e5cc3), X(0x2e110a62), X(0x776c4edb), X(0x2e3fec8b), X(0x775a2e89), X(0x2e6ec792), X(0x7747fbce), X(0x2e9d9b70), X(0x7735b6af), X(0x2ecc681e), X(0x77235f2d), X(0x2efb2d95), X(0x7710f54c), X(0x2f29ebcc), X(0x76fe790e), X(0x2f58a2be), X(0x76ebea77), X(0x2f875262), X(0x76d94989), X(0x2fb5fab2), X(0x76c69647), X(0x2fe49ba7), X(0x76b3d0b4), X(0x30133539), X(0x76a0f8d2), X(0x3041c761), X(0x768e0ea6), X(0x30705217), X(0x767b1231), X(0x309ed556), X(0x76680376), X(0x30cd5115), X(0x7654e279), X(0x30fbc54d), X(0x7641af3d), X(0x312a31f8), X(0x762e69c4), X(0x3158970e), X(0x761b1211), X(0x3186f487), X(0x7607a828), X(0x31b54a5e), X(0x75f42c0b), X(0x31e39889), X(0x75e09dbd), X(0x3211df04), X(0x75ccfd42), X(0x32401dc6), X(0x75b94a9c), X(0x326e54c7), X(0x75a585cf), X(0x329c8402), X(0x7591aedd), X(0x32caab6f), X(0x757dc5ca), X(0x32f8cb07), X(0x7569ca99), X(0x3326e2c3), X(0x7555bd4c), X(0x3354f29b), X(0x75419de7), X(0x3382fa88), X(0x752d6c6c), X(0x33b0fa84), X(0x751928e0), X(0x33def287), X(0x7504d345), X(0x340ce28b), X(0x74f06b9e), X(0x343aca87), X(0x74dbf1ef), X(0x3468aa76), X(0x74c7663a), X(0x34968250), X(0x74b2c884), X(0x34c4520d), X(0x749e18cd), X(0x34f219a8), X(0x7489571c), X(0x351fd918), X(0x74748371), X(0x354d9057), X(0x745f9dd1), X(0x357b3f5d), X(0x744aa63f), X(0x35a8e625), X(0x74359cbd), X(0x35d684a6), X(0x74208150), X(0x36041ad9), X(0x740b53fb), X(0x3631a8b8), X(0x73f614c0), X(0x365f2e3b), X(0x73e0c3a3), X(0x368cab5c), X(0x73cb60a8), X(0x36ba2014), X(0x73b5ebd1), X(0x36e78c5b), X(0x73a06522), X(0x3714f02a), X(0x738acc9e), X(0x37424b7b), X(0x73752249), X(0x376f9e46), X(0x735f6626), X(0x379ce885), X(0x73499838), X(0x37ca2a30), X(0x7333b883), X(0x37f76341), X(0x731dc70a), X(0x382493b0), X(0x7307c3d0), X(0x3851bb77), X(0x72f1aed9), X(0x387eda8e), X(0x72db8828), X(0x38abf0ef), X(0x72c54fc1), X(0x38d8fe93), X(0x72af05a7), X(0x39060373), X(0x7298a9dd), X(0x3932ff87), X(0x72823c67), X(0x395ff2c9), X(0x726bbd48), X(0x398cdd32), X(0x72552c85), X(0x39b9bebc), X(0x723e8a20), X(0x39e6975e), X(0x7227d61c), X(0x3a136712), X(0x7211107e), X(0x3a402dd2), X(0x71fa3949), X(0x3a6ceb96), X(0x71e35080), X(0x3a99a057), X(0x71cc5626), X(0x3ac64c0f), X(0x71b54a41), X(0x3af2eeb7), X(0x719e2cd2), X(0x3b1f8848), X(0x7186fdde), X(0x3b4c18ba), X(0x716fbd68), X(0x3b78a007), X(0x71586b74), X(0x3ba51e29), X(0x71410805), X(0x3bd19318), X(0x7129931f), X(0x3bfdfecd), X(0x71120cc5), X(0x3c2a6142), X(0x70fa74fc), X(0x3c56ba70), X(0x70e2cbc6), X(0x3c830a50), X(0x70cb1128), X(0x3caf50da), X(0x70b34525), X(0x3cdb8e09), X(0x709b67c0), X(0x3d07c1d6), X(0x708378ff), X(0x3d33ec39), X(0x706b78e3), X(0x3d600d2c), X(0x70536771), X(0x3d8c24a8), X(0x703b44ad), X(0x3db832a6), X(0x7023109a), X(0x3de4371f), X(0x700acb3c), X(0x3e10320d), X(0x6ff27497), X(0x3e3c2369), X(0x6fda0cae), X(0x3e680b2c), X(0x6fc19385), X(0x3e93e950), X(0x6fa90921), X(0x3ebfbdcd), X(0x6f906d84), X(0x3eeb889c), X(0x6f77c0b3), X(0x3f1749b8), X(0x6f5f02b2), X(0x3f430119), X(0x6f463383), X(0x3f6eaeb8), X(0x6f2d532c), X(0x3f9a5290), X(0x6f1461b0), X(0x3fc5ec98), X(0x6efb5f12), X(0x3ff17cca), X(0x6ee24b57), X(0x401d0321), X(0x6ec92683), X(0x40487f94), X(0x6eaff099), X(0x4073f21d), X(0x6e96a99d), X(0x409f5ab6), X(0x6e7d5193), X(0x40cab958), X(0x6e63e87f), X(0x40f60dfb), X(0x6e4a6e66), X(0x4121589b), X(0x6e30e34a), X(0x414c992f), X(0x6e174730), X(0x4177cfb1), X(0x6dfd9a1c), X(0x41a2fc1a), X(0x6de3dc11), X(0x41ce1e65), X(0x6dca0d14), X(0x41f93689), X(0x6db02d29), X(0x42244481), X(0x6d963c54), X(0x424f4845), X(0x6d7c3a98), X(0x427a41d0), X(0x6d6227fa), X(0x42a5311b), X(0x6d48047e), X(0x42d0161e), X(0x6d2dd027), X(0x42faf0d4), X(0x6d138afb), X(0x4325c135), X(0x6cf934fc), X(0x4350873c), X(0x6cdece2f), X(0x437b42e1), X(0x6cc45698), X(0x43a5f41e), X(0x6ca9ce3b), X(0x43d09aed), X(0x6c8f351c), X(0x43fb3746), X(0x6c748b3f), X(0x4425c923), X(0x6c59d0a9), X(0x4450507e), X(0x6c3f055d), X(0x447acd50), X(0x6c242960), X(0x44a53f93), X(0x6c093cb6), X(0x44cfa740), X(0x6bee3f62), X(0x44fa0450), X(0x6bd3316a), X(0x452456bd), X(0x6bb812d1), X(0x454e9e80), X(0x6b9ce39b), X(0x4578db93), X(0x6b81a3cd), X(0x45a30df0), X(0x6b66536b), X(0x45cd358f), X(0x6b4af279), X(0x45f7526b), X(0x6b2f80fb), X(0x4621647d), X(0x6b13fef5), X(0x464b6bbe), X(0x6af86c6c), X(0x46756828), X(0x6adcc964), X(0x469f59b4), X(0x6ac115e2), X(0x46c9405c), X(0x6aa551e9), X(0x46f31c1a), X(0x6a897d7d), X(0x471cece7), X(0x6a6d98a4), X(0x4746b2bc), X(0x6a51a361), X(0x47706d93), X(0x6a359db9), X(0x479a1d67), X(0x6a1987b0), X(0x47c3c22f), X(0x69fd614a), X(0x47ed5be6), X(0x69e12a8c), X(0x4816ea86), X(0x69c4e37a), X(0x48406e08), X(0x69a88c19), X(0x4869e665), X(0x698c246c), X(0x48935397), X(0x696fac78), X(0x48bcb599), X(0x69532442), X(0x48e60c62), X(0x69368bce), X(0x490f57ee), X(0x6919e320), X(0x49389836), X(0x68fd2a3d), X(0x4961cd33), X(0x68e06129), X(0x498af6df), X(0x68c387e9), X(0x49b41533), X(0x68a69e81), X(0x49dd282a), X(0x6889a4f6), X(0x4a062fbd), X(0x686c9b4b), X(0x4a2f2be6), X(0x684f8186), X(0x4a581c9e), X(0x683257ab), X(0x4a8101de), X(0x68151dbe), X(0x4aa9dba2), X(0x67f7d3c5), X(0x4ad2a9e2), X(0x67da79c3), X(0x4afb6c98), X(0x67bd0fbd), X(0x4b2423be), X(0x679f95b7), X(0x4b4ccf4d), X(0x67820bb7), X(0x4b756f40), X(0x676471c0), X(0x4b9e0390), X(0x6746c7d8), X(0x4bc68c36), X(0x67290e02), X(0x4bef092d), X(0x670b4444), X(0x4c177a6e), X(0x66ed6aa1), X(0x4c3fdff4), X(0x66cf8120), X(0x4c6839b7), X(0x66b187c3), X(0x4c9087b1), X(0x66937e91), X(0x4cb8c9dd), X(0x6675658c), X(0x4ce10034), X(0x66573cbb), X(0x4d092ab0), X(0x66390422), X(0x4d31494b), X(0x661abbc5), X(0x4d595bfe), X(0x65fc63a9), X(0x4d8162c4), X(0x65ddfbd3), X(0x4da95d96), X(0x65bf8447), X(0x4dd14c6e), X(0x65a0fd0b), X(0x4df92f46), X(0x65826622), X(0x4e210617), X(0x6563bf92), X(0x4e48d0dd), X(0x6545095f), X(0x4e708f8f), X(0x6526438f), X(0x4e984229), X(0x65076e25), X(0x4ebfe8a5), X(0x64e88926), X(0x4ee782fb), X(0x64c99498), X(0x4f0f1126), X(0x64aa907f), X(0x4f369320), X(0x648b7ce0), X(0x4f5e08e3), X(0x646c59bf), X(0x4f857269), X(0x644d2722), X(0x4faccfab), X(0x642de50d), X(0x4fd420a4), X(0x640e9386), X(0x4ffb654d), X(0x63ef3290), X(0x50229da1), X(0x63cfc231), X(0x5049c999), X(0x63b0426d), X(0x5070e92f), X(0x6390b34a), X(0x5097fc5e), X(0x637114cc), X(0x50bf031f), X(0x635166f9), X(0x50e5fd6d), X(0x6331a9d4), X(0x510ceb40), X(0x6311dd64), X(0x5133cc94), X(0x62f201ac), X(0x515aa162), X(0x62d216b3), X(0x518169a5), X(0x62b21c7b), X(0x51a82555), X(0x6292130c), X(0x51ced46e), X(0x6271fa69), X(0x51f576ea), X(0x6251d298), X(0x521c0cc2), X(0x62319b9d), X(0x524295f0), X(0x6211557e), X(0x5269126e), X(0x61f1003f), X(0x528f8238), X(0x61d09be5), X(0x52b5e546), X(0x61b02876), X(0x52dc3b92), X(0x618fa5f7), X(0x53028518), X(0x616f146c), X(0x5328c1d0), X(0x614e73da), X(0x534ef1b5), X(0x612dc447), X(0x537514c2), X(0x610d05b7), X(0x539b2af0), X(0x60ec3830), X(0x53c13439), X(0x60cb5bb7), X(0x53e73097), X(0x60aa7050), X(0x540d2005), X(0x60897601), X(0x5433027d), X(0x60686ccf), X(0x5458d7f9), X(0x604754bf), X(0x547ea073), X(0x60262dd6), X(0x54a45be6), X(0x6004f819), X(0x54ca0a4b), X(0x5fe3b38d), X(0x54efab9c), X(0x5fc26038), X(0x55153fd4), X(0x5fa0fe1f), X(0x553ac6ee), X(0x5f7f8d46), X(0x556040e2), X(0x5f5e0db3), X(0x5585adad), X(0x5f3c7f6b), X(0x55ab0d46), X(0x5f1ae274), X(0x55d05faa), X(0x5ef936d1), X(0x55f5a4d2), X(0x5ed77c8a), X(0x561adcb9), X(0x5eb5b3a2), X(0x56400758), X(0x5e93dc1f), X(0x566524aa), X(0x5e71f606), X(0x568a34a9), X(0x5e50015d), X(0x56af3750), X(0x5e2dfe29), X(0x56d42c99), X(0x5e0bec6e), X(0x56f9147e), X(0x5de9cc33), X(0x571deefa), X(0x5dc79d7c), X(0x5742bc06), X(0x5da5604f), X(0x57677b9d), X(0x5d8314b1), X(0x578c2dba), X(0x5d60baa7), X(0x57b0d256), X(0x5d3e5237), X(0x57d5696d), X(0x5d1bdb65), X(0x57f9f2f8), X(0x5cf95638), X(0x581e6ef1), X(0x5cd6c2b5), X(0x5842dd54), X(0x5cb420e0), X(0x58673e1b), X(0x5c9170bf), X(0x588b9140), X(0x5c6eb258), X(0x58afd6bd), X(0x5c4be5b0), X(0x58d40e8c), X(0x5c290acc), X(0x58f838a9), X(0x5c0621b2), X(0x591c550e), X(0x5be32a67), X(0x594063b5), X(0x5bc024f0), X(0x59646498), X(0x5b9d1154), X(0x598857b2), X(0x5b79ef96), X(0x59ac3cfd), X(0x5b56bfbd), X(0x59d01475), X(0x5b3381ce), X(0x59f3de12), X(0x5b1035cf), X(0x5a1799d1), X(0x5aecdbc5), X(0x5a3b47ab), X(0x5ac973b5), X(0x5a5ee79a), X(0x5aa5fda5), X(0x5a82799a), X(0x5a82799a) ]; /* {sin((2*i+1)*PI/4096), cos((2*i+1)*PI/4096)}, with i = 0 to 511 */ static var _sincos_lookup1 : Array = [ X(0x001921fb), X(0x7ffffd88), X(0x004b65ee), X(0x7fffe9cb), X(0x007da9d4), X(0x7fffc251), X(0x00afeda8), X(0x7fff8719), X(0x00e23160), X(0x7fff3824), X(0x011474f6), X(0x7ffed572), X(0x0146b860), X(0x7ffe5f03), X(0x0178fb99), X(0x7ffdd4d7), X(0x01ab3e97), X(0x7ffd36ee), X(0x01dd8154), X(0x7ffc8549), X(0x020fc3c6), X(0x7ffbbfe6), X(0x024205e8), X(0x7ffae6c7), X(0x027447b0), X(0x7ff9f9ec), X(0x02a68917), X(0x7ff8f954), X(0x02d8ca16), X(0x7ff7e500), X(0x030b0aa4), X(0x7ff6bcf0), X(0x033d4abb), X(0x7ff58125), X(0x036f8a51), X(0x7ff4319d), X(0x03a1c960), X(0x7ff2ce5b), X(0x03d407df), X(0x7ff1575d), X(0x040645c7), X(0x7fefcca4), X(0x04388310), X(0x7fee2e30), X(0x046abfb3), X(0x7fec7c02), X(0x049cfba7), X(0x7feab61a), X(0x04cf36e5), X(0x7fe8dc78), X(0x05017165), X(0x7fe6ef1c), X(0x0533ab20), X(0x7fe4ee06), X(0x0565e40d), X(0x7fe2d938), X(0x05981c26), X(0x7fe0b0b1), X(0x05ca5361), X(0x7fde7471), X(0x05fc89b8), X(0x7fdc247a), X(0x062ebf22), X(0x7fd9c0ca), X(0x0660f398), X(0x7fd74964), X(0x06932713), X(0x7fd4be46), X(0x06c5598a), X(0x7fd21f72), X(0x06f78af6), X(0x7fcf6ce8), X(0x0729bb4e), X(0x7fcca6a7), X(0x075bea8c), X(0x7fc9ccb2), X(0x078e18a7), X(0x7fc6df08), X(0x07c04598), X(0x7fc3dda9), X(0x07f27157), X(0x7fc0c896), X(0x08249bdd), X(0x7fbd9fd0), X(0x0856c520), X(0x7fba6357), X(0x0888ed1b), X(0x7fb7132b), X(0x08bb13c5), X(0x7fb3af4e), X(0x08ed3916), X(0x7fb037bf), X(0x091f5d06), X(0x7facac7f), X(0x09517f8f), X(0x7fa90d8e), X(0x0983a0a7), X(0x7fa55aee), X(0x09b5c048), X(0x7fa1949e), X(0x09e7de6a), X(0x7f9dbaa0), X(0x0a19fb04), X(0x7f99ccf4), X(0x0a4c1610), X(0x7f95cb9a), X(0x0a7e2f85), X(0x7f91b694), X(0x0ab0475c), X(0x7f8d8de1), X(0x0ae25d8d), X(0x7f895182), X(0x0b147211), X(0x7f850179), X(0x0b4684df), X(0x7f809dc5), X(0x0b7895f0), X(0x7f7c2668), X(0x0baaa53b), X(0x7f779b62), X(0x0bdcb2bb), X(0x7f72fcb4), X(0x0c0ebe66), X(0x7f6e4a5e), X(0x0c40c835), X(0x7f698461), X(0x0c72d020), X(0x7f64aabf), X(0x0ca4d620), X(0x7f5fbd77), X(0x0cd6da2d), X(0x7f5abc8a), X(0x0d08dc3f), X(0x7f55a7fa), X(0x0d3adc4e), X(0x7f507fc7), X(0x0d6cda53), X(0x7f4b43f2), X(0x0d9ed646), X(0x7f45f47b), X(0x0dd0d01f), X(0x7f409164), X(0x0e02c7d7), X(0x7f3b1aad), X(0x0e34bd66), X(0x7f359057), X(0x0e66b0c3), X(0x7f2ff263), X(0x0e98a1e9), X(0x7f2a40d2), X(0x0eca90ce), X(0x7f247ba5), X(0x0efc7d6b), X(0x7f1ea2dc), X(0x0f2e67b8), X(0x7f18b679), X(0x0f604faf), X(0x7f12b67c), X(0x0f923546), X(0x7f0ca2e7), X(0x0fc41876), X(0x7f067bba), X(0x0ff5f938), X(0x7f0040f6), X(0x1027d784), X(0x7ef9f29d), X(0x1059b352), X(0x7ef390ae), X(0x108b8c9b), X(0x7eed1b2c), X(0x10bd6356), X(0x7ee69217), X(0x10ef377d), X(0x7edff570), X(0x11210907), X(0x7ed94538), X(0x1152d7ed), X(0x7ed28171), X(0x1184a427), X(0x7ecbaa1a), X(0x11b66dad), X(0x7ec4bf36), X(0x11e83478), X(0x7ebdc0c6), X(0x1219f880), X(0x7eb6aeca), X(0x124bb9be), X(0x7eaf8943), X(0x127d7829), X(0x7ea85033), X(0x12af33ba), X(0x7ea1039b), X(0x12e0ec6a), X(0x7e99a37c), X(0x1312a230), X(0x7e922fd6), X(0x13445505), X(0x7e8aa8ac), X(0x137604e2), X(0x7e830dff), X(0x13a7b1bf), X(0x7e7b5fce), X(0x13d95b93), X(0x7e739e1d), X(0x140b0258), X(0x7e6bc8eb), X(0x143ca605), X(0x7e63e03b), X(0x146e4694), X(0x7e5be40c), X(0x149fe3fc), X(0x7e53d462), X(0x14d17e36), X(0x7e4bb13c), X(0x1503153a), X(0x7e437a9c), X(0x1534a901), X(0x7e3b3083), X(0x15663982), X(0x7e32d2f4), X(0x1597c6b7), X(0x7e2a61ed), X(0x15c95097), X(0x7e21dd73), X(0x15fad71b), X(0x7e194584), X(0x162c5a3b), X(0x7e109a24), X(0x165dd9f0), X(0x7e07db52), X(0x168f5632), X(0x7dff0911), X(0x16c0cef9), X(0x7df62362), X(0x16f2443e), X(0x7ded2a47), X(0x1723b5f9), X(0x7de41dc0), X(0x17552422), X(0x7ddafdce), X(0x17868eb3), X(0x7dd1ca75), X(0x17b7f5a3), X(0x7dc883b4), X(0x17e958ea), X(0x7dbf298d), X(0x181ab881), X(0x7db5bc02), X(0x184c1461), X(0x7dac3b15), X(0x187d6c82), X(0x7da2a6c6), X(0x18aec0db), X(0x7d98ff17), X(0x18e01167), X(0x7d8f4409), X(0x19115e1c), X(0x7d85759f), X(0x1942a6f3), X(0x7d7b93da), X(0x1973ebe6), X(0x7d719eba), X(0x19a52ceb), X(0x7d679642), X(0x19d669fc), X(0x7d5d7a74), X(0x1a07a311), X(0x7d534b50), X(0x1a38d823), X(0x7d4908d9), X(0x1a6a0929), X(0x7d3eb30f), X(0x1a9b361d), X(0x7d3449f5), X(0x1acc5ef6), X(0x7d29cd8c), X(0x1afd83ad), X(0x7d1f3dd6), X(0x1b2ea43a), X(0x7d149ad5), X(0x1b5fc097), X(0x7d09e489), X(0x1b90d8bb), X(0x7cff1af5), X(0x1bc1ec9e), X(0x7cf43e1a), X(0x1bf2fc3a), X(0x7ce94dfb), X(0x1c240786), X(0x7cde4a98), X(0x1c550e7c), X(0x7cd333f3), X(0x1c861113), X(0x7cc80a0f), X(0x1cb70f43), X(0x7cbcccec), X(0x1ce80906), X(0x7cb17c8d), X(0x1d18fe54), X(0x7ca618f3), X(0x1d49ef26), X(0x7c9aa221), X(0x1d7adb73), X(0x7c8f1817), X(0x1dabc334), X(0x7c837ad8), X(0x1ddca662), X(0x7c77ca65), X(0x1e0d84f5), X(0x7c6c06c0), X(0x1e3e5ee5), X(0x7c602fec), X(0x1e6f342c), X(0x7c5445e9), X(0x1ea004c1), X(0x7c4848ba), X(0x1ed0d09d), X(0x7c3c3860), X(0x1f0197b8), X(0x7c3014de), X(0x1f325a0b), X(0x7c23de35), X(0x1f63178f), X(0x7c179467), X(0x1f93d03c), X(0x7c0b3777), X(0x1fc4840a), X(0x7bfec765), X(0x1ff532f2), X(0x7bf24434), X(0x2025dcec), X(0x7be5ade6), X(0x205681f1), X(0x7bd9047c), X(0x208721f9), X(0x7bcc47fa), X(0x20b7bcfe), X(0x7bbf7860), X(0x20e852f6), X(0x7bb295b0), X(0x2118e3dc), X(0x7ba59fee), X(0x21496fa7), X(0x7b989719), X(0x2179f64f), X(0x7b8b7b36), X(0x21aa77cf), X(0x7b7e4c45), X(0x21daf41d), X(0x7b710a49), X(0x220b6b32), X(0x7b63b543), X(0x223bdd08), X(0x7b564d36), X(0x226c4996), X(0x7b48d225), X(0x229cb0d5), X(0x7b3b4410), X(0x22cd12bd), X(0x7b2da2fa), X(0x22fd6f48), X(0x7b1feee5), X(0x232dc66d), X(0x7b1227d3), X(0x235e1826), X(0x7b044dc7), X(0x238e646a), X(0x7af660c2), X(0x23beab33), X(0x7ae860c7), X(0x23eeec78), X(0x7ada4dd8), X(0x241f2833), X(0x7acc27f7), X(0x244f5e5c), X(0x7abdef25), X(0x247f8eec), X(0x7aafa367), X(0x24afb9da), X(0x7aa144bc), X(0x24dfdf20), X(0x7a92d329), X(0x250ffeb7), X(0x7a844eae), X(0x25401896), X(0x7a75b74f), X(0x25702cb7), X(0x7a670d0d), X(0x25a03b11), X(0x7a584feb), X(0x25d0439f), X(0x7a497feb), X(0x26004657), X(0x7a3a9d0f), X(0x26304333), X(0x7a2ba75a), X(0x26603a2c), X(0x7a1c9ece), X(0x26902b39), X(0x7a0d836d), X(0x26c01655), X(0x79fe5539), X(0x26effb76), X(0x79ef1436), X(0x271fda96), X(0x79dfc064), X(0x274fb3ae), X(0x79d059c8), X(0x277f86b5), X(0x79c0e062), X(0x27af53a6), X(0x79b15435), X(0x27df1a77), X(0x79a1b545), X(0x280edb23), X(0x79920392), X(0x283e95a1), X(0x79823f20), X(0x286e49ea), X(0x797267f2), X(0x289df7f8), X(0x79627e08), X(0x28cd9fc1), X(0x79528167), X(0x28fd4140), X(0x79427210), X(0x292cdc6d), X(0x79325006), X(0x295c7140), X(0x79221b4b), X(0x298bffb2), X(0x7911d3e2), X(0x29bb87bc), X(0x790179cd), X(0x29eb0957), X(0x78f10d0f), X(0x2a1a847b), X(0x78e08dab), X(0x2a49f920), X(0x78cffba3), X(0x2a796740), X(0x78bf56f9), X(0x2aa8ced3), X(0x78ae9fb0), X(0x2ad82fd2), X(0x789dd5cb), X(0x2b078a36), X(0x788cf94c), X(0x2b36ddf7), X(0x787c0a36), X(0x2b662b0e), X(0x786b088c), X(0x2b957173), X(0x7859f44f), X(0x2bc4b120), X(0x7848cd83), X(0x2bf3ea0d), X(0x7837942b), X(0x2c231c33), X(0x78264849), X(0x2c52478a), X(0x7814e9df), X(0x2c816c0c), X(0x780378f1), X(0x2cb089b1), X(0x77f1f581), X(0x2cdfa071), X(0x77e05f91), X(0x2d0eb046), X(0x77ceb725), X(0x2d3db928), X(0x77bcfc3f), X(0x2d6cbb10), X(0x77ab2ee2), X(0x2d9bb5f6), X(0x77994f11), X(0x2dcaa9d5), X(0x77875cce), X(0x2df996a3), X(0x7775581d), X(0x2e287c5a), X(0x776340ff), X(0x2e575af3), X(0x77511778), X(0x2e863267), X(0x773edb8b), X(0x2eb502ae), X(0x772c8d3a), X(0x2ee3cbc1), X(0x771a2c88), X(0x2f128d99), X(0x7707b979), X(0x2f41482e), X(0x76f5340e), X(0x2f6ffb7a), X(0x76e29c4b), X(0x2f9ea775), X(0x76cff232), X(0x2fcd4c19), X(0x76bd35c7), X(0x2ffbe95d), X(0x76aa670d), X(0x302a7f3a), X(0x76978605), X(0x30590dab), X(0x768492b4), X(0x308794a6), X(0x76718d1c), X(0x30b61426), X(0x765e7540), X(0x30e48c22), X(0x764b4b23), X(0x3112fc95), X(0x76380ec8), X(0x31416576), X(0x7624c031), X(0x316fc6be), X(0x76115f63), X(0x319e2067), X(0x75fdec60), X(0x31cc7269), X(0x75ea672a), X(0x31fabcbd), X(0x75d6cfc5), X(0x3228ff5c), X(0x75c32634), X(0x32573a3f), X(0x75af6a7b), X(0x32856d5e), X(0x759b9c9b), X(0x32b398b3), X(0x7587bc98), X(0x32e1bc36), X(0x7573ca75), X(0x330fd7e1), X(0x755fc635), X(0x333debab), X(0x754bafdc), X(0x336bf78f), X(0x7537876c), X(0x3399fb85), X(0x75234ce8), X(0x33c7f785), X(0x750f0054), X(0x33f5eb89), X(0x74faa1b3), X(0x3423d78a), X(0x74e63108), X(0x3451bb81), X(0x74d1ae55), X(0x347f9766), X(0x74bd199f), X(0x34ad6b32), X(0x74a872e8), X(0x34db36df), X(0x7493ba34), X(0x3508fa66), X(0x747eef85), X(0x3536b5be), X(0x746a12df), X(0x356468e2), X(0x74552446), X(0x359213c9), X(0x744023bc), X(0x35bfb66e), X(0x742b1144), X(0x35ed50c9), X(0x7415ece2), X(0x361ae2d3), X(0x7400b69a), X(0x36486c86), X(0x73eb6e6e), X(0x3675edd9), X(0x73d61461), X(0x36a366c6), X(0x73c0a878), X(0x36d0d746), X(0x73ab2ab4), X(0x36fe3f52), X(0x73959b1b), X(0x372b9ee3), X(0x737ff9ae), X(0x3758f5f2), X(0x736a4671), X(0x37864477), X(0x73548168), X(0x37b38a6d), X(0x733eaa96), X(0x37e0c7cc), X(0x7328c1ff), X(0x380dfc8d), X(0x7312c7a5), X(0x383b28a9), X(0x72fcbb8c), X(0x38684c19), X(0x72e69db7), X(0x389566d6), X(0x72d06e2b), X(0x38c278d9), X(0x72ba2cea), X(0x38ef821c), X(0x72a3d9f7), X(0x391c8297), X(0x728d7557), X(0x39497a43), X(0x7276ff0d), X(0x39766919), X(0x7260771b), X(0x39a34f13), X(0x7249dd86), X(0x39d02c2a), X(0x72333251), X(0x39fd0056), X(0x721c7580), X(0x3a29cb91), X(0x7205a716), X(0x3a568dd4), X(0x71eec716), X(0x3a834717), X(0x71d7d585), X(0x3aaff755), X(0x71c0d265), X(0x3adc9e86), X(0x71a9bdba), X(0x3b093ca3), X(0x71929789), X(0x3b35d1a5), X(0x717b5fd3), X(0x3b625d86), X(0x7164169d), X(0x3b8ee03e), X(0x714cbbeb), X(0x3bbb59c7), X(0x71354fc0), X(0x3be7ca1a), X(0x711dd220), X(0x3c143130), X(0x7106430e), X(0x3c408f03), X(0x70eea28e), X(0x3c6ce38a), X(0x70d6f0a4), X(0x3c992ec0), X(0x70bf2d53), X(0x3cc5709e), X(0x70a7589f), X(0x3cf1a91c), X(0x708f728b), X(0x3d1dd835), X(0x70777b1c), X(0x3d49fde1), X(0x705f7255), X(0x3d761a19), X(0x70475839), X(0x3da22cd7), X(0x702f2ccd), X(0x3dce3614), X(0x7016f014), X(0x3dfa35c8), X(0x6ffea212), X(0x3e262bee), X(0x6fe642ca), X(0x3e52187f), X(0x6fcdd241), X(0x3e7dfb73), X(0x6fb5507a), X(0x3ea9d4c3), X(0x6f9cbd79), X(0x3ed5a46b), X(0x6f841942), X(0x3f016a61), X(0x6f6b63d8), X(0x3f2d26a0), X(0x6f529d40), X(0x3f58d921), X(0x6f39c57d), X(0x3f8481dd), X(0x6f20dc92), X(0x3fb020ce), X(0x6f07e285), X(0x3fdbb5ec), X(0x6eeed758), X(0x40074132), X(0x6ed5bb10), X(0x4032c297), X(0x6ebc8db0), X(0x405e3a16), X(0x6ea34f3d), X(0x4089a7a8), X(0x6e89ffb9), X(0x40b50b46), X(0x6e709f2a), X(0x40e064ea), X(0x6e572d93), X(0x410bb48c), X(0x6e3daaf8), X(0x4136fa27), X(0x6e24175c), X(0x416235b2), X(0x6e0a72c5), X(0x418d6729), X(0x6df0bd35), X(0x41b88e84), X(0x6dd6f6b1), X(0x41e3abbc), X(0x6dbd1f3c), X(0x420ebecb), X(0x6da336dc), X(0x4239c7aa), X(0x6d893d93), X(0x4264c653), X(0x6d6f3365), X(0x428fbabe), X(0x6d551858), X(0x42baa4e6), X(0x6d3aec6e), X(0x42e584c3), X(0x6d20afac), X(0x43105a50), X(0x6d066215), X(0x433b2585), X(0x6cec03af), X(0x4365e65b), X(0x6cd1947c), X(0x43909ccd), X(0x6cb71482), X(0x43bb48d4), X(0x6c9c83c3), X(0x43e5ea68), X(0x6c81e245), X(0x44108184), X(0x6c67300b), X(0x443b0e21), X(0x6c4c6d1a), X(0x44659039), X(0x6c319975), X(0x449007c4), X(0x6c16b521), X(0x44ba74bd), X(0x6bfbc021), X(0x44e4d71c), X(0x6be0ba7b), X(0x450f2edb), X(0x6bc5a431), X(0x45397bf4), X(0x6baa7d49), X(0x4563be60), X(0x6b8f45c7), X(0x458df619), X(0x6b73fdae), X(0x45b82318), X(0x6b58a503), X(0x45e24556), X(0x6b3d3bcb), X(0x460c5cce), X(0x6b21c208), X(0x46366978), X(0x6b0637c1), X(0x46606b4e), X(0x6aea9cf8), X(0x468a624a), X(0x6acef1b2), X(0x46b44e65), X(0x6ab335f4), X(0x46de2f99), X(0x6a9769c1), X(0x470805df), X(0x6a7b8d1e), X(0x4731d131), X(0x6a5fa010), X(0x475b9188), X(0x6a43a29a), X(0x478546de), X(0x6a2794c1), X(0x47aef12c), X(0x6a0b7689), X(0x47d8906d), X(0x69ef47f6), X(0x48022499), X(0x69d3090e), X(0x482badab), X(0x69b6b9d3), X(0x48552b9b), X(0x699a5a4c), X(0x487e9e64), X(0x697dea7b), X(0x48a805ff), X(0x69616a65), X(0x48d16265), X(0x6944da10), X(0x48fab391), X(0x6928397e), X(0x4923f97b), X(0x690b88b5), X(0x494d341e), X(0x68eec7b9), X(0x49766373), X(0x68d1f68f), X(0x499f8774), X(0x68b5153a), X(0x49c8a01b), X(0x689823bf), X(0x49f1ad61), X(0x687b2224), X(0x4a1aaf3f), X(0x685e106c), X(0x4a43a5b0), X(0x6840ee9b), X(0x4a6c90ad), X(0x6823bcb7), X(0x4a957030), X(0x68067ac3), X(0x4abe4433), X(0x67e928c5), X(0x4ae70caf), X(0x67cbc6c0), X(0x4b0fc99d), X(0x67ae54ba), X(0x4b387af9), X(0x6790d2b6), X(0x4b6120bb), X(0x677340ba), X(0x4b89badd), X(0x67559eca), X(0x4bb24958), X(0x6737ecea), X(0x4bdacc28), X(0x671a2b20), X(0x4c034345), X(0x66fc596f), X(0x4c2baea9), X(0x66de77dc), X(0x4c540e4e), X(0x66c0866d), X(0x4c7c622d), X(0x66a28524), X(0x4ca4aa41), X(0x66847408), X(0x4ccce684), X(0x6666531d), X(0x4cf516ee), X(0x66482267), X(0x4d1d3b7a), X(0x6629e1ec), X(0x4d455422), X(0x660b91af), X(0x4d6d60df), X(0x65ed31b5), X(0x4d9561ac), X(0x65cec204), X(0x4dbd5682), X(0x65b0429f), X(0x4de53f5a), X(0x6591b38c), X(0x4e0d1c30), X(0x657314cf), X(0x4e34ecfc), X(0x6554666d), X(0x4e5cb1b9), X(0x6535a86b), X(0x4e846a60), X(0x6516dacd), X(0x4eac16eb), X(0x64f7fd98), X(0x4ed3b755), X(0x64d910d1), X(0x4efb4b96), X(0x64ba147d), X(0x4f22d3aa), X(0x649b08a0), X(0x4f4a4f89), X(0x647bed3f), X(0x4f71bf2e), X(0x645cc260), X(0x4f992293), X(0x643d8806), X(0x4fc079b1), X(0x641e3e38), X(0x4fe7c483), X(0x63fee4f8), X(0x500f0302), X(0x63df7c4d), X(0x50363529), X(0x63c0043b), X(0x505d5af1), X(0x63a07cc7), X(0x50847454), X(0x6380e5f6), X(0x50ab814d), X(0x63613fcd), X(0x50d281d5), X(0x63418a50), X(0x50f975e6), X(0x6321c585), X(0x51205d7b), X(0x6301f171), X(0x5147388c), X(0x62e20e17), X(0x516e0715), X(0x62c21b7e), X(0x5194c910), X(0x62a219aa), X(0x51bb7e75), X(0x628208a1), X(0x51e22740), X(0x6261e866), X(0x5208c36a), X(0x6241b8ff), X(0x522f52ee), X(0x62217a72), X(0x5255d5c5), X(0x62012cc2), X(0x527c4bea), X(0x61e0cff5), X(0x52a2b556), X(0x61c06410), X(0x52c91204), X(0x619fe918), X(0x52ef61ee), X(0x617f5f12), X(0x5315a50e), X(0x615ec603), X(0x533bdb5d), X(0x613e1df0), X(0x536204d7), X(0x611d66de), X(0x53882175), X(0x60fca0d2), X(0x53ae3131), X(0x60dbcbd1), X(0x53d43406), X(0x60bae7e1), X(0x53fa29ed), X(0x6099f505), X(0x542012e1), X(0x6078f344), X(0x5445eedb), X(0x6057e2a2), X(0x546bbdd7), X(0x6036c325), X(0x54917fce), X(0x601594d1), X(0x54b734ba), X(0x5ff457ad), X(0x54dcdc96), X(0x5fd30bbc), X(0x5502775c), X(0x5fb1b104), X(0x55280505), X(0x5f90478a), X(0x554d858d), X(0x5f6ecf53), X(0x5572f8ed), X(0x5f4d4865), X(0x55985f20), X(0x5f2bb2c5), X(0x55bdb81f), X(0x5f0a0e77), X(0x55e303e6), X(0x5ee85b82), X(0x5608426e), X(0x5ec699e9), X(0x562d73b2), X(0x5ea4c9b3), X(0x565297ab), X(0x5e82eae5), X(0x5677ae54), X(0x5e60fd84), X(0x569cb7a8), X(0x5e3f0194), X(0x56c1b3a1), X(0x5e1cf71c), X(0x56e6a239), X(0x5dfade20), X(0x570b8369), X(0x5dd8b6a7), X(0x5730572e), X(0x5db680b4), X(0x57551d80), X(0x5d943c4e), X(0x5779d65b), X(0x5d71e979), X(0x579e81b8), X(0x5d4f883b), X(0x57c31f92), X(0x5d2d189a), X(0x57e7afe4), X(0x5d0a9a9a), X(0x580c32a7), X(0x5ce80e41), X(0x5830a7d6), X(0x5cc57394), X(0x58550f6c), X(0x5ca2ca99), X(0x58796962), X(0x5c801354), X(0x589db5b3), X(0x5c5d4dcc), X(0x58c1f45b), X(0x5c3a7a05), X(0x58e62552), X(0x5c179806), X(0x590a4893), X(0x5bf4a7d2), X(0x592e5e19), X(0x5bd1a971), X(0x595265df), X(0x5bae9ce7), X(0x59765fde), X(0x5b8b8239), X(0x599a4c12), X(0x5b68596d), X(0x59be2a74), X(0x5b452288), X(0x59e1faff), X(0x5b21dd90), X(0x5a05bdae), X(0x5afe8a8b), X(0x5a29727b), X(0x5adb297d), X(0x5a4d1960), X(0x5ab7ba6c), X(0x5a70b258), X(0x5a943d5e), ]; } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/000077500000000000000000000000001454362722700255445ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/AllocChain.hx000066400000000000000000000003521454362722700301020ustar00rootroot00000000000000//#!/usr/bin/env python //# -*- coding: utf-8 -*- package org.xiph.fvorbis; import org.xiph.system.Bytes; class AllocChain { /* * generated source for AllocChain */ var ptr : Dynamic; var next : AllocChain; } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Block.hx000066400000000000000000000054641454362722700271500ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; import org.xiph.fogg.Packet; class Block { /* * generated source for Block */ // discarded initializer: 'new float[0]'; public var pcm : Array>; // discarded initializer: 'Buffer()'; public var opb : Buffer; public var lW : Int; public var W : Int; public var nW : Int; public var pcmend : Int; public var mode : Int; public var eofflag : Int; public var granulepos : Int; public var sequence : Int; public var vd : DspState; public var glue_bits : Int; public var time_bits : Int; public var floor_bits : Int; public var res_bits : Int; // modifiers: public public function new(vd : DspState) { pcm = new Array(); opb = new Buffer(); this.vd = vd; if (vd.analysisp != 0) { opb.writeinit(); }; } // modifiers: public public function init(vd : DspState) : Void { this.vd = vd; } // modifiers: public public function clear() : Int { if (vd != null) { if (vd.analysisp != 0) { opb.writeclear(); }; }; return 0; } // modifiers: public public function synthesis(op : Packet) : Int { var vi : Info = vd.vi; opb.readinit(op.packet_base, op.packet, op.bytes); if (opb.read(1) != 0) { return -1; }; var _mode : Int = opb.read(vd.modebits); if (_mode == -1) { return -1; }; mode = _mode; W = vi.mode_param[mode].blockflag; if (W != 0) { lW = opb.read(1); nW = opb.read(1); if (nW == -1) { return -1; }; } else { lW = 0; nW = 0; }; granulepos = op.granulepos; sequence = (op.packetno - 3); eofflag = op.e_o_s; pcmend = vi.blocksizes[W]; if (pcm.length < vi.channels) { //pcm = new float[vi.channels]; pcm = ArrayTools.alloc(vi.channels); }; // for-while; var i : Int = 0; while (i < vi.channels) { if ((pcm[i] == null) || (cast(pcm[i].length,UInt) < cast(pcmend,UInt))) { //pcm[i] = new float[pcmend]; pcm[i] = new Vector(pcmend, true); } else { // for-while; var j : Int = 0; while (j < pcmend) { pcm[i][j] = 0; j++; }; }; i++; }; var type : Int = vi.map_type[vi.mode_param[mode].mapping]; return FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/ChainingExample.hx000066400000000000000000000027071454362722700311470ustar00rootroot00000000000000//#!/usr/bin/env python //# -*- coding: utf-8 -*- package org.xiph.fvorbis; import org.xiph.system.Bytes; class ChainingExample { /* * generated source for ChainingExample */ // modifiers: static, public static public function main(arg : Array) : Void { var ov : VorbisFile = null; try { ov = VorbisFile(System.in_, null, -1); } catch (e : Exception) { trace(e); return; }; if (ov.seekable()) { print ("Input bitstream contained " + ov.streams() + " logical bitstream section(s)."); print ("Total bitstream playing time: " + ov.time_total(-1) + " seconds\n"); } else { print "Standard input was not seekable."; print "First logical bitstream information:\n"; }; // for-while; var i : Int = 0; while (i < ov.streams()) { var vi : Info = ov.getInfo(i); print ("\tlogical bitstream section " + (i + 1) + " information:"); print (((((("\t\t" + vi.rate + "Hz ") + vi.channels) + " channels bitrate ") + (ov.bitrate(i) / 1000)) + "kbps serial number=") + ov.serialnumber(i)); System.out.print_(("\t\tcompressed length: " + ov.raw_total(i)) + " bytes "); print (" play time: " + ov.time_total(i) + "s"); var vc : Comment = ov.getComment(i); print vc; i++; }; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/CodeBook.hx000066400000000000000000000440161454362722700275770ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class CodeBook { /* * generated source for CodeBook */ public var dim : Int; var entries : Int; // discarded initializer: 'StaticCodeBook()'; var c : StaticCodeBook; var valuelist : Vector; var codelist : Vector; var decode_tree : DecodeAux; // modifiers: function encode(a : Int, b : Buffer) : Int { b.write(codelist[a], c.lengthlist[a]); return c.lengthlist[a]; } // modifiers: function errorv(a : Vector) : Int { var best : Int = best(a, 1); // for-while; var k : Int = 0; while (k < dim) { a[k] = valuelist[(best * dim) + k]; k++; }; return best; } // modifiers: function encodev(best : Int, a : Vector, b : Buffer) : Int { // for-while; var k : Int = 0; while (k < dim) { a[k] = valuelist[(best * dim) + k]; k++; }; return encode(best, b); } // modifiers: function encodevs(a : Vector, b : Buffer, step : Int, addmul : Int) : Int { var best : Int = besterror(a, step, addmul); return encode(best, b); } // discarded initializer: 'new int[15]'; private var t : Vector; // modifiers: synchronized public function decodevs_add(a : Vector, offset : Int, b : Buffer, n : Int) : Int { var step : Int = Std.int(n / dim); var entry : Int; var i : Int; var j : Int; var o : Int; if (t.length < step) { //t = new int[step]; t = new Vector(step); }; // for-while; i = 0; while (i < step) { entry = decode(b); if (entry == -1) { return -1; }; t[i] = (entry * dim); i++; }; // for-while; i = 0; o = 0; while (i < dim) { // for-while; j = 0; while (j < step) { a[(offset + o) + j] += valuelist[t[j] + i]; j++; }; i++; o += step; }; return 0; } // modifiers: public function decodev_add(a : Vector, offset : Int, b : Buffer, n : Int) : Int { var i : Int; var j : Int; var entry : Int; var t : Int; if (dim > 8) { // for-while; i = 0; while (i < n) { entry = decode(b); if (entry == -1) { return -1; }; t = (entry * dim); // for-while; j = 0; while (j < dim) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; }; }; } else { // for-while; i = 0; while (i < n) { entry = decode(b); if (entry == -1) { return -1; }; t = (entry * dim); j = 0; { // FIXME: why isn't this a loop, but some voodoo // sideeffects-and-oh-wait-a-switch?! var fall : Bool = false; if (dim == 8) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 7) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 6) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 5) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 4) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 3) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 2) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; fall = true; }; if (fall || dim == 1) { // HAXE200BUG // a[offset + i++] += valuelist[t + j++]; a[offset + i] += valuelist[t + j]; i++; j++; }; /* if dim == 0 { }; */ }; }; }; return 0; } // modifiers: public function decodev_set(a : Vector, offset : Int, b : Buffer, n : Int) : Int { var i : Int; var j : Int; var entry : Int; var t : Int; // for-while; i = 0; while (i < n) { entry = decode(b); if (entry == -1) { return -1; }; t = (entry * dim); // for-while; j = 0; while (j < dim) { a[offset + i++] = valuelist[t + j++]; }; }; return 0; } // modifiers: public function decodevv_add(a : Array>, offset : Int, ch : Int, b : Buffer, n : Int) : Int { var i : Int; var j : Int; var k : Int; var entry : Int; var chptr : Int = 0; // for-while; i = Std.int(offset / ch); while (i < ((offset + n) / ch)) { entry = decode(b); if (entry == -1) { return -1; }; var t : Int = entry * dim; // for-while; j = 0; while (j < dim) { // HAXE200BUG // haXe 2.00 has a bug causing the following code line // to increment chptr twice (because of the "+=" operator?): // a[chptr++][i] += valuelist[t + j]; a[chptr][i] += valuelist[t + j]; chptr++; if (chptr == ch) { chptr = 0; i++; }; j++; }; }; return 0; } // modifiers: public function decode(b : Buffer) : Int { var ptr : Int = 0; var t : DecodeAux = decode_tree; var lok : Int = b.look(t.tabn); if (lok >= 0) { ptr = t.tab[lok]; b.adv(t.tabl[lok]); if (ptr <= 0) { return -ptr; }; }; do { { var swval = b.read1(); if (swval == 0) { ptr = t.ptr0[ptr]; } else if (swval == 1) { ptr = t.ptr1[ptr]; } else { return -1; }; }; } while (ptr > 0); return -ptr; } // modifiers: public function decodevs(a : Vector, index : Int, b : Buffer, step : Int, addmul : Int) : Int { var entry : Int = decode(b); if (entry == -1) { return -1; }; switch (addmul) { case -1: // for-while; var i : Int = 0; var o : Int = 0; while (i < dim) { a[index + o] = valuelist[(entry * dim) + i]; i++; o += step; }; case 0: // for-while; var i : Int = 0; var o : Int = 0; while (i < dim) { a[index + o] += valuelist[(entry * dim) + i]; i++; o += step; }; case 1: // for-while; var i : Int = 0; var o : Int = 0; while (i < dim) { a[index + o] *= valuelist[(entry * dim) + i]; i++; o += step; }; default: trace("CodeBook.decodeves: addmul=" + addmul); }; return entry; } // modifiers: function best(a : Vector, step : Int) : Int { var nt : EncodeAuxNearestMatch = c.nearest_tree; var tt : EncodeAuxThreshMatch = c.thresh_tree; var ptr : Int = 0; if (tt != null) { var index : Int = 0; // for-while; var k : Int = 0; var o : Int = step * (dim - 1); while (k < dim) { var i : Int; // for-while; i = 0; while (i < (tt.threshvals - 1)) { if (a[o] < tt.quantthresh[i]) { break; }; i++; }; index = ((index * tt.quantvals) + tt.quantmap[i]); k++; o -= step; }; if (c.lengthlist[index] > 0) { return index; }; }; if (nt != null) { while (true) { var c : Float = 0.; var p : Int = nt.p[ptr]; var q : Int = nt.q[ptr]; // for-while; var k : Int = 0; var o : Int = 0; while (k < dim) { c += ((valuelist[p + k] - valuelist[q + k]) * (a[o] - ((valuelist[p + k] + valuelist[q + k]) * 0.5))); k++; o += step; }; if (c > 0.) { ptr = -nt.ptr0[ptr]; } else { ptr = -nt.ptr1[ptr]; }; if (ptr <= 0) { break; }; }; return -ptr; }; var besti : Int = -1; var best : Float = 0.; var e : Int = 0; // for-while; var i : Int = 0; while (i < entries) { if (c.lengthlist[i] > 0) { var _this : Float = CodeBook.dist(dim, valuelist, e, a, step); if ((besti == -1) || (_this < best)) { best = _this; besti = i; }; }; e += dim; i++; }; return besti; } // modifiers: function besterror(a : Vector, step : Int, addmul : Int) : Int { var best : Int = best(a, step); switch (addmul) { case 0: // for-while; var i : Int = 0; var o : Int = 0; while (i < dim) { a[o] -= valuelist[(best * dim) + i]; i++; o += step; }; case 1: // for-while; var i : Int = 0; var o : Int = 0; while (i < dim) { var val : Float = valuelist[(best * dim) + i]; if (val == 0) { a[o] = 0; } else { a[o] /= val; }; i++; o += step; }; }; return best; } // modifiers: function clear() : Void { } // modifiers: static, private static private function dist(el : Int, ref : Vector, index : Int, b : Vector, step : Int) : Float { var acc : Float = 0.; // for-while; var i : Int = 0; while (i < el) { var val : Float = ref[index + i] - b[i * step]; acc += (val * val); i++; }; return acc; } // modifiers: public function init_decode(s : StaticCodeBook) : Int { c = s; entries = s.entries; dim = s.dim; valuelist = s.unquantize(); decode_tree = make_decode_tree(); if (decode_tree == null) { clear(); return -1; }; return 0; } // modifiers: static static function make_words(l : Vector, n : Int) : Vector { //var marker : Vector = new int[33]; var marker : Vector = new Vector(33, true); //var r : Vector = new int[n]; var r : Vector = new Vector(n, true); // for-while; var i : Int = 0; while (i < n) { var length : Int = l[i]; if (length > 0) { var entry : Int = marker[length]; if ((length < 32) && ((entry >>> length) != 0)) { return null; }; r[i] = entry; // for-while; var j : Int = length; while (j > 0) { if ((marker[j] & 1) != 0) { if (j == 1) { marker[1]++; } else { marker[j] = (marker[j - 1] << 1); }; break; }; marker[j]++; j--; }; // for-while; var j : Int = length + 1; while (j < 33) { if ((marker[j] >>> 1) == entry) { entry = marker[j]; marker[j] = (marker[j - 1] << 1); } else { break; }; j++; }; }; i++; }; // for-while; var i : Int = 0; while (i < n) { var temp : Int = 0; // for-while; var j : Int = 0; while (j < l[i]) { temp <<= 1; temp |= ((r[i] >>> j) & 1); j++; }; r[i] = temp; i++; }; return r; } // modifiers: function make_decode_tree() : DecodeAux { var top : Int = 0; var t : DecodeAux = new DecodeAux(); //var ptr0 : Vector = t.ptr0 = new int[entries * 2]; var ptr0 : Vector = t.ptr0 = new Vector(entries * 2, true); //var ptr1 : Vector = t.ptr1 = new int[entries * 2]; var ptr1 : Vector = t.ptr1 = new Vector(entries * 2, true); var codelist : Vector = make_words(c.lengthlist, c.entries); if (codelist == null) { return null; }; t.aux = (entries * 2); // for-while; var i : Int = 0; while (i < entries) { if (c.lengthlist[i] > 0) { var ptr : Int = 0; var j : Int; // for-while; j = 0; while (j < (c.lengthlist[i] - 1)) { var bit : Int = (codelist[i] >>> j) & 1; if (bit == 0) { if (ptr0[ptr] == 0) { ptr0[ptr] = ++top; }; ptr = ptr0[ptr]; } else { if (ptr1[ptr] == 0) { ptr1[ptr] = ++top; }; ptr = ptr1[ptr]; }; j++; }; if (((codelist[i] >>> j) & 1) == 0) { ptr0[ptr] = -i; } else { ptr1[ptr] = -i; }; }; i++; }; t.tabn = (ilog(entries) - 4); if (t.tabn < 5) { t.tabn = 5; }; var n : Int = 1 << t.tabn; //t.tab = new int[n]; t.tab = new Vector(n, true); //t.tabl = new int[n]; t.tabl = new Vector(n, true); // for-while; var i : Int = 0; while (i < n) { var p : Int = 0; var j : Int = 0; // for-while; j = 0; while ((j < t.tabn) && ((p > 0) || (j == 0))) { if ((i & (1 << j)) != 0) { p = ptr1[p]; } else { p = ptr0[p]; }; j++; }; t.tab[i] = p; t.tabl[i] = j; i++; }; return t; } // modifiers: static, private static private function ilog(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret++; v >>>= 1; }; return ret; } public function new() { // discarded initializer: 'StaticCodeBook()'; c = new StaticCodeBook(); // discarded initializer: 'new int[15]'; t = new Vector(15, true); } } class DecodeAux { /* * generated source for DecodeAux */ public var tab : Vector; public var tabl : Vector; public var tabn : Int; public var ptr0 : Vector; public var ptr1 : Vector; public var aux : Int; public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Comment.hx000066400000000000000000000212711454362722700275120ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; import org.xiph.fogg.Packet; class Comment { /* * generated source for Comment */ static private var _vorbis : Bytes = System.fromString("vorbis"); inline static private var OV_EFAULT : Int = -129; inline static private var OV_EIMPL : Int = -130; public var user_comments : Array; public var comment_lengths : Vector; public var comments : Int; public var vendor : Bytes; // modifiers: public public function init() : Void { user_comments = null; comments = 0; vendor = null; } // modifiers: public public function addString(comment : String) : Void { add(System.fromString(comment)); } // modifiers: private private function add(comment : Bytes) : Void { // var foo : Vector = new Vector(comments + 2, true); // if (user_comments != null) { // System.arraycopyV(user_comments, 0, foo, 0, comments); // }; // user_comments = foo; if (user_comments == null) user_comments = ArrayTools.alloc(comments + 2); //else // user_comments.length = comments + 2; //var goo : Vector = new int[comments + 2]; // var goo : Vector = new Vector(comments + 2, true); // if (comment_lengths != null) { // System.arraycopyV(comment_lengths, 0, goo, 0, comments); // }; // comment_lengths = goo; if (comment_lengths == null) comment_lengths = new Vector(comments + 2, false); else comment_lengths.length = comments + 2; var bar : Bytes = System.alloc(comment.length + 1); System.bytescopy(comment, 0, bar, 0, comment.length); user_comments[comments] = bar; comment_lengths[comments] = comment.length; comments++; user_comments[comments] = null; } // modifiers: public public function add_tag(tag : String, contents : String) : Void { if (contents == null) { contents = ""; }; addString((tag + "=") + contents); } // modifiers: static static function tagcompare(s1 : Bytes, s2 : Bytes, n : Int) : Bool { // FIXME: don't compare char by cahr, use the language tools! var c : Int = 0; var u1 : Int; var u2 : Int; while (c < n) { u1 = s1[c]; u2 = s2[c]; if (u1 >= 'A'.charCodeAt(0)) { u1 = (u1 - 'A'.charCodeAt(0)) + 'a'.charCodeAt(0); }; if (u2 >= 'A'.charCodeAt(0)) { u2 = (u2 - 'A'.charCodeAt(0)) + 'a'.charCodeAt(0); }; if (u1 != u2) { return false; }; c++; }; return true; } /* // modifiers: public public function __query_0(tag : String) : String { return query(tag, 0); } */ // modifiers: public public function query(tag : String, count : Int = 0) : String { var foo : Int = queryBytes(System.fromString(tag), count); if (foo == -1) { return null; }; var comment : Bytes = user_comments[foo]; // for-while; var i : Int = 0; while (i < comment_lengths[foo]) { if (comment[i] == '='.charCodeAt(0)) { //return new String(comment, i + 1, comment_lengths[foo] - (i + 1)); comment.position = i + 1; return comment.readUTFBytes(comment_lengths[foo] - (i + 1)); }; i++; }; return null; } // modifiers: private private function queryBytes(tag : Bytes, count : Int) : Int { var i : Int = 0; var found : Int = 0; var taglen : Int = tag.length; var fulltag : Bytes = System.alloc(taglen + 2); System.bytescopy(tag, 0, fulltag, 0, tag.length); fulltag[tag.length] = '='.charCodeAt(0); // for-while; i = 0; while (i < comments) { if (Comment.tagcompare(user_comments[i], fulltag, taglen)) { if (count == found) { return i; } else { found++; }; }; i++; }; return -1; } // modifiers: public function unpack(opb : Buffer) : Int { var vendorlen : Int = opb.read(32); if (vendorlen < 0) { clear(); return -1; }; vendor = System.alloc(vendorlen + 1); opb.readBytes(vendor, vendorlen); comments = opb.read(32); if (comments < 0) { clear(); return -1; }; //user_comments = System.alloc(comments + 1); //user_comments = new Vector(comments + 1, false); user_comments = ArrayTools.alloc(comments + 1); //comment_lengths = new int[comments + 1]; comment_lengths = new Vector(comments + 1, true); // for-while; var i : Int = 0; while (i < comments) { var len : Int = opb.read(32); if (len < 0) { clear(); return -1; }; comment_lengths[i] = len; user_comments[i] = System.alloc(len + 1); opb.readBytes(user_comments[i], len); i++; }; if (opb.read(1) != 1) { clear(); return -1; }; return 0; } // modifiers: function pack(opb : Buffer) : Int { var temp : Bytes = System.fromString("Xiphophorus libVorbis I 20000508"); opb.write(0x03, 8); opb.writeBytes(Comment._vorbis); opb.write(temp.length, 32); opb.writeBytes(temp); opb.write(comments, 32); if (comments != 0) { // for-while; var i : Int = 0; while (i < comments) { if (user_comments[i] != null) { opb.write(comment_lengths[i], 32); opb.writeBytes(user_comments[i]); } else { opb.write(0, 32); }; i++; }; }; opb.write(1, 1); return 0; } // modifiers: public public function header_out(op : Packet) : Int { var opb : Buffer = new Buffer(); opb.writeinit(); if (pack(opb) != 0) { return Comment.OV_EIMPL; }; op.packet_base = System.alloc(opb.bytes()); op.packet = 0; op.bytes = opb.bytes(); System.bytescopy(opb.buffer, 0, op.packet_base, 0, op.bytes); op.b_o_s = 0; op.e_o_s = 0; op.granulepos = 0; return 0; } // modifiers: public function clear() : Void { // for-while; var i : Int = 0; while (i < comments) { user_comments[i] = null; i++; }; user_comments = null; vendor = null; } // modifiers: public public function getVendor() : String { //return String(vendor, 0, vendor.length - 1); vendor.position = 0; return vendor.readUTFBytes(vendor.length - 1); } // modifiers: public public function getComment(i : Int) : String { if (comments <= i) { return null; }; //return String(user_comments[i], 0, user_comments[i].length - 1); user_comments[i].position = 0; return user_comments[i].readUTFBytes(user_comments[i].length - 1); } // modifiers: public public function toString() : String { vendor.position = 0; var foo : String = "Vendor: " + vendor.readUTFBytes(vendor.length - 1); // for-while; var i : Int = 0; while (i < comments) { user_comments[i].position = 0; foo = (foo + "\nComment: ") + user_comments[i].readUTFBytes(user_comments[i].length - 1); i++; }; foo = (foo + "\n"); return foo; } /* // modifiers: inline, public inline public function add() : Void { // FIXME: implement disambiguation handler; // __add_0(comment : String) : Void; // __add_1(comment : Bytes) : Void; throw "NotImplementedError"; } */ /* // modifiers: inline, public inline public function query() : String { // FIXME: implement disambiguation handler; // __query_0(tag : String) : String; // __query_1(tag : String, count : Int) : String; // __query_2(tag : Bytes, count : Int) : Int; throw "NotImplementedError"; } */ public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/DecodeExample.hx000066400000000000000000000203511454362722700306050ustar00rootroot00000000000000//#!/usr/bin/env python //# -*- coding: utf-8 -*- package org.xiph.fvorbis; import org.xiph.system.Bytes; import org.xiph.fogg.*; class DecodeExample { /* * generated source for DecodeExample */ static var convsize : Int = 4096 * 2; static var convbuffer : Bytes = System.alloc(convsize); // modifiers: static, public static public function main(arg : Array) : Void { var input : ..InputStream = System.in_; if (arg.length > 0) { try { input = java.io.FileInputStream(arg[0]); } catch (e : Exception) { trace(e); }; }; var oy : SyncState = SyncState(); var os : StreamState = StreamState(); var og : Page = Page(); var op : Packet = Packet(); var vi : Info = Info(); var vc : Comment = Comment(); var vd : DspState = DspState(); var vb : Block = Block(vd); var buffer : Bytes; var bytes : Int = 0; oy.init(); while (true) { var eos : Int = 0; var index : Int = oy.buffer(4096); buffer = oy.data; try { bytes = input.read(buffer, index, 4096); } catch (e : Exception) { trace(e); System.exit(-1); }; oy.wrote(bytes); if (oy.pageout(og) != 1) { if (bytes < 4096) { break; }; trace("Input does not appear to be an Ogg bitstream."); System.exit(1); }; os.init(og.serialno()); vi.init(); vc.init(); if (os.pagein(og) < 0) { trace("Error reading first page of Ogg bitstream data."); System.exit(1); }; if (os.packetout(op) != 1) { trace("Error reading initial header packet."); System.exit(1); }; if (vi.synthesis_headerin(vc, op) < 0) { trace("This Ogg bitstream does not contain Vorbis audio data."); System.exit(1); }; var i : Int = 0; while (i < 2) { while (i < 2) { var result : Int = oy.pageout(og); if (result == 0) { break; }; if (result == 1) { os.pagein(og); while (i < 2) { result = os.packetout(op); if (result == 0) { break; }; if (result == -1) { trace("Corrupt secondary header. Exiting."); System.exit(1); }; vi.synthesis_headerin(vc, op); i++; }; }; }; index = oy.buffer(4096); buffer = oy.data; try { bytes = input.read(buffer, index, 4096); } catch (e : Exception) { trace(e); System.exit(1); }; if ((bytes == 0) && (i < 2)) { trace("End of file before finding all Vorbis headers!"); System.exit(1); }; oy.wrote(bytes); }; var ptr : Array = vc.user_comments; // for-while; var j : Int = 0; while (j < ptr.length) { if (ptr[j] == null) { break; }; trace(String(ptr[j], 0, ptr[j].length - 1)); j++; }; trace(((("\nBitstream is " + vi.channels) + " channel, ") + vi.rate) + "Hz"); trace(("Encoded by: " + String(vc.vendor, 0, vc.vendor.length - 1)) + "\n"); DecodeExample.convsize = (4096 / vi.channels); vd.synthesis_init(vi); vb.init(vd); var _pcm : Array>> = new float[1]; var _index : Array = new int[vi.channels]; while (eos == 0) { while (eos == 0) { var result : Int = oy.pageout(og); if (result == 0) { break; }; if (result == -1) { trace("Corrupt or missing data in bitstream; continuing..."); } else { os.pagein(og); while (true) { result = os.packetout(op); if (result == 0) { break; }; if (result == -1) { } else { var samples : Int; if (vb.synthesis(op) == 0) { vd.synthesis_blockin(vb); }; while ((samples = vd.synthesis_pcmout(_pcm, _index)) > 0) { var pcm : Array> = _pcm[0]; var clipflag : Bool = false; var bout : Int = (samples < DecodeExample.convsize ? samples : DecodeExample.convsize); // for-while; i = 0; while (i < vi.channels) { var ptr : Int = i * 2; var mono : Int = _index[i]; // for-while; var j : Int = 0; while (j < bout) { var val : Int = pcm[i][mono + j] * 32767.; if (val > 32767) { val = 32767; clipflag = true; }; if (val < -32768) { val = -32768; clipflag = true; }; if (val < 0) { val = (val | 0x8000); }; DecodeExample.convbuffer[ptr] = val; DecodeExample.convbuffer[ptr + 1] = val >>> 8; ptr += (2 * vi.channels); j++; }; i++; }; System.out.write(DecodeExample.convbuffer, 0, (2 * vi.channels) * bout); vd.synthesis_read(bout); }; }; }; if (og.eos() != 0) { eos = 1; }; }; }; if (eos == 0) { index = oy.buffer(4096); buffer = oy.data; try { bytes = input.read(buffer, index, 4096); } catch (e : Exception) { trace(e); System.exit(1); }; oy.wrote(bytes); if (bytes == 0) { eos = 1; }; }; }; os.clear(); vb.clear(); vd.clear(); vi.clear(); }; oy.clear(); trace("Done."); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Drft.hx000066400000000000000000001734641454362722700270230ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Drft { /* * generated source for Drft */ var n : Int; var trigcache : Vector; var splitcache : Vector; // modifiers: public function backward(data : Vector) : Void { if (n == 1) { return; }; Drft.drftb1(n, data, trigcache, trigcache, n, splitcache); } // modifiers: public function init(n : Int) : Void { this.n = n; //trigcache = new float[3 * n]; trigcache = new Vector(3 * n, true); //splitcache = new int[32]; splitcache = new Vector(32, true); Drft.fdrffti(n, trigcache, splitcache); } // modifiers: public function clear() : Void { if (trigcache != null) { trigcache = null; }; if (splitcache != null) { splitcache = null; }; } static var ntryh : Array = [4, 2, 3, 5]; static var tpi : Float = 6.28318530717958647692528676655900577; static var hsqt2 : Float = 0.70710678118654752440084436210485; static var taui : Float = 0.86602540378443864676372317075293618; static var taur : Float = -0.5; static var sqrt2 : Float = 1.4142135623730950488016887242097; // modifiers: static static function drfti1(n : Int, wa : Vector, index : Int, ifac : Vector) : Void { var arg : Float; var argh : Float; var argld : Float; var fi : Float; var ntry : Int = 0; var i : Int; var j : Int = -1; var k1 : Int; var l1 : Int; var l2 : Int; var ib : Int; var ld : Int; var ii : Int; var ip : Int; var is_ : Int; var nq : Int; var nr : Int; var ido : Int; var ipm : Int; var nfm1 : Int; var nl : Int = n; var nf : Int = 0; var state : Int = 101; var _break_loop : Int = 0; while (true) { trace(""); while (true) { var fall = false; if (state == 101) { j++; if (j < 4) { ntry = Drft.ntryh[j]; } else { ntry += 2; }; fall = true; }; if (fall || state == 104) { nq = Std.int(nl / ntry); nr = (nl - (ntry * nq)); if (nr != 0) { state = 101; break; }; nf++; ifac[nf + 1] = ntry; nl = nq; if (ntry != 2) { state = 107; break; }; if (nf == 1) { state = 107; break; }; // for-while; i = 1; while (i < nf) { ib = ((nf - i) + 1); ifac[ib + 1] = ifac[ib]; i++; }; ifac[2] = 2; fall = true; }; if (fall || state == 107) { if (nl != 1) { state = 104; break; }; ifac[0] = n; ifac[1] = nf; argh = (Drft.tpi / n); is_ = 0; nfm1 = (nf - 1); l1 = 1; if (nfm1 == 0) { return; }; // for-while; k1 = 0; while (k1 < nfm1) { ip = ifac[k1 + 2]; ld = 0; l2 = (l1 * ip); ido = Std.int(n / l2); ipm = (ip - 1); // for-while; j = 0; while (j < ipm) { ld += l1; i = is_; argld = (ld * argh); fi = 0.; // for-while; ii = 2; while (ii < ido) { fi += 1.; arg = (fi * argld); wa[index + i++] = Math.cos(arg); wa[index + i++] = Math.sin(arg); ii += 2; }; is_ += ido; j++; }; l1 = l2; k1++; }; _break_loop = 1; break; }; break; }; if (_break_loop == 1) { break; } else { _break_loop = 0; }; }; } // modifiers: static static function fdrffti(n : Int, wsave : Vector, ifac : Vector) : Void { if (n == 1) { return; }; Drft.drfti1(n, wsave, n, ifac); } // modifiers: static static function dradf2(ido : Int, l1 : Int, cc : Vector, ch : Vector, wa1 : Vector, index : Int) : Void { var i : Int; var k : Int; var ti2 : Float; var tr2 : Float; var t0 : Int; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; t1 = 0; t0 = (t2 = (l1 * ido)); t3 = (ido << 1); // for-while; k = 0; while (k < l1) { ch[t1 << 1] = (cc[t1] + cc[t2]); ch[((t1 << 1) + t3) - 1] = (cc[t1] - cc[t2]); t1 += ido; t2 += ido; k++; }; if (ido < 2) { return; }; if (ido != 2) { t1 = 0; t2 = t0; // for-while; k = 0; while (k < l1) { t3 = t2; t4 = ((t1 << 1) + (ido << 1)); t5 = t1; t6 = (t1 + t1); // for-while; i = 2; while (i < ido) { t3 += 2; t4 -= 2; t5 += 2; t6 += 2; tr2 = ((wa1[(index + i) - 2] * cc[t3 - 1]) + (wa1[(index + i) - 1] * cc[t3])); ti2 = ((wa1[(index + i) - 2] * cc[t3]) - (wa1[(index + i) - 1] * cc[t3 - 1])); ch[t6] = (cc[t5] + ti2); ch[t4] = (ti2 - cc[t5]); ch[t6 - 1] = (cc[t5 - 1] + tr2); ch[t4 - 1] = (cc[t5 - 1] - tr2); i += 2; }; t1 += ido; t2 += ido; k++; }; if ((ido % 2) == 1) { return; }; }; t3 = (t2 = ((t1 = ido) - 1)); t2 += t0; // for-while; k = 0; while (k < l1) { ch[t1] = -cc[t2]; ch[t1 - 1] = cc[t3]; t1 += (ido << 1); t2 += ido; t3 += ido; k++; }; } // modifiers: static static function dradf4(ido : Int, l1 : Int, cc : Vector, ch : Vector, wa1 : Vector, index1 : Int, wa2 : Vector, index2 : Int, wa3 : Vector, index3 : Int) : Void { var i : Int; var k : Int; var t0 : Int; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var ci2 : Float; var ci3 : Float; var ci4 : Float; var cr2 : Float; var cr3 : Float; var cr4 : Float; var ti1 : Float; var ti2 : Float; var ti3 : Float; var ti4 : Float; var tr1 : Float; var tr2 : Float; var tr3 : Float; var tr4 : Float; t0 = (l1 * ido); t1 = t0; t4 = (t1 << 1); t2 = (t1 + (t1 << 1)); t3 = 0; // for-while; k = 0; while (k < l1) { tr1 = (cc[t1] + cc[t2]); tr2 = (cc[t3] + cc[t4]); // ch[t5 = (t3 << 2)] = (tr1 + tr2); t5 = (t3 << 2); ch[t5] = (tr1 + tr2); ch[((ido << 2) + t5) - 1] = (tr2 - tr1); // ch[(t5 += (ido << 1)) - 1] = (cc[t3] - cc[t4]); t5 += (ido << 1); ch[t5 - 1] = (cc[t3] - cc[t4]); ch[t5] = (cc[t2] - cc[t1]); t1 += ido; t2 += ido; t3 += ido; t4 += ido; k++; }; if (ido < 2) { return; }; if (ido != 2) { t1 = 0; // for-while; k = 0; while (k < l1) { t2 = t1; t4 = (t1 << 2); t5 = ((t6 = (ido << 1)) + t4); // for-while; i = 2; while (i < ido) { t3 = (t2 += 2); t4 += 2; t5 -= 2; t3 += t0; cr2 = ((wa1[(index1 + i) - 2] * cc[t3 - 1]) + (wa1[(index1 + i) - 1] * cc[t3])); ci2 = ((wa1[(index1 + i) - 2] * cc[t3]) - (wa1[(index1 + i) - 1] * cc[t3 - 1])); t3 += t0; cr3 = ((wa2[(index2 + i) - 2] * cc[t3 - 1]) + (wa2[(index2 + i) - 1] * cc[t3])); ci3 = ((wa2[(index2 + i) - 2] * cc[t3]) - (wa2[(index2 + i) - 1] * cc[t3 - 1])); t3 += t0; cr4 = ((wa3[(index3 + i) - 2] * cc[t3 - 1]) + (wa3[(index3 + i) - 1] * cc[t3])); ci4 = ((wa3[(index3 + i) - 2] * cc[t3]) - (wa3[(index3 + i) - 1] * cc[t3 - 1])); tr1 = (cr2 + cr4); tr4 = (cr4 - cr2); ti1 = (ci2 + ci4); ti4 = (ci2 - ci4); ti2 = (cc[t2] + ci3); ti3 = (cc[t2] - ci3); tr2 = (cc[t2 - 1] + cr3); tr3 = (cc[t2 - 1] - cr3); ch[t4 - 1] = (tr1 + tr2); ch[t4] = (ti1 + ti2); ch[t5 - 1] = (tr3 - ti4); ch[t5] = (tr4 - ti3); ch[(t4 + t6) - 1] = (ti4 + tr3); ch[t4 + t6] = (tr4 + ti3); ch[(t5 + t6) - 1] = (tr2 - tr1); ch[t5 + t6] = (ti1 - ti2); i += 2; }; t1 += ido; k++; }; if ((ido & 1) != 0) { return; }; }; t2 = ((t1 = ((t0 + ido) - 1)) + (t0 << 1)); t3 = (ido << 2); t4 = ido; t5 = (ido << 1); t6 = ido; // for-while; k = 0; while (k < l1) { ti1 = (-Drft.hsqt2 * (cc[t1] + cc[t2])); tr1 = (Drft.hsqt2 * (cc[t1] - cc[t2])); ch[t4 - 1] = (tr1 + cc[t6 - 1]); ch[(t4 + t5) - 1] = (cc[t6 - 1] - tr1); ch[t4] = (ti1 - cc[t1 + t0]); ch[t4 + t5] = (ti1 + cc[t1 + t0]); t1 += ido; t2 += ido; t4 += t3; t6 += ido; k++; }; } // modifiers: static static function dradfg(ido : Int, ip : Int, l1 : Int, idl1 : Int, cc : Vector, c1 : Vector, c2 : Vector, ch : Vector, ch2 : Vector, wa : Vector, index : Int) : Void { var idij : Int; var ipph : Int; var i : Int; var j : Int; var k : Int; var l : Int; var ic : Int; var ik : Int; var is_ : Int; var t0 : Int; var t1 : Int; var t2 : Int = 0; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var t7 : Int; var t8 : Int; var t9 : Int; var t10 : Int; var dc2 : Float; var ai1 : Float; var ai2 : Float; var ar1 : Float; var ar2 : Float; var ds2 : Float; var nbd : Int; var dcp : Float = 0; var arg : Float; var dsp : Float = 0; var ar1h : Float; var ar2h : Float; var idp2 : Int; var ipp2 : Int; arg = (Drft.tpi / ip); dcp = Math.cos(arg); dsp = Math.sin(arg); ipph = ((ip + 1) >> 1); ipp2 = ip; idp2 = ido; nbd = ((ido - 1) >> 1); t0 = (l1 * ido); t10 = (ip * ido); var state : Int = 100; var _break_loop : Int = 0; while (true) { // switch (state) ... while (true) { var fall = false; if (state == 101) { if (ido == 1) { state = 119; break; }; // for-while; ik = 0; while (ik < idl1) { ch2[ik] = c2[ik]; ik++; }; t1 = 0; // for-while; j = 1; while (j < ip) { t1 += t0; t2 = t1; // for-while; k = 0; while (k < l1) { ch[t2] = c1[t2]; t2 += ido; k++; }; j++; }; is_ = -ido; t1 = 0; if (nbd > l1) { // for-while; j = 1; while (j < ip) { t1 += t0; is_ += ido; t2 = (-ido + t1); // for-while; k = 0; while (k < l1) { idij = (is_ - 1); t2 += ido; t3 = t2; // for-while; i = 2; while (i < ido) { idij += 2; t3 += 2; ch[t3 - 1] = ((wa[(index + idij) - 1] * c1[t3 - 1]) + (wa[index + idij] * c1[t3])); ch[t3] = ((wa[(index + idij) - 1] * c1[t3]) - (wa[index + idij] * c1[t3 - 1])); i += 2; }; k++; }; j++; }; } else { // for-while; j = 1; while (j < ip) { is_ += ido; idij = (is_ - 1); t1 += t0; t2 = t1; // for-while; i = 2; while (i < ido) { idij += 2; t2 += 2; t3 = t2; // for-while; k = 0; while (k < l1) { ch[t3 - 1] = ((wa[(index + idij) - 1] * c1[t3 - 1]) + (wa[index + idij] * c1[t3])); ch[t3] = ((wa[(index + idij) - 1] * c1[t3]) - (wa[index + idij] * c1[t3 - 1])); t3 += ido; k++; }; i += 2; }; j++; }; }; t1 = 0; t2 = (ipp2 * t0); if (nbd < l1) { // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; // for-while; i = 2; while (i < ido) { t3 += 2; t4 += 2; t5 = (t3 - ido); t6 = (t4 - ido); // for-while; k = 0; while (k < l1) { t5 += ido; t6 += ido; c1[t5 - 1] = (ch[t5 - 1] + ch[t6 - 1]); c1[t6 - 1] = (ch[t5] - ch[t6]); c1[t5] = (ch[t5] + ch[t6]); c1[t6] = (ch[t6 - 1] - ch[t5 - 1]); k++; }; i += 2; }; j++; }; } else { // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; // for-while; k = 0; while (k < l1) { t5 = t3; t6 = t4; // for-while; i = 2; while (i < ido) { t5 += 2; t6 += 2; c1[t5 - 1] = (ch[t5 - 1] + ch[t6 - 1]); c1[t6 - 1] = (ch[t5] - ch[t6]); c1[t5] = (ch[t5] + ch[t6]); c1[t6] = (ch[t6 - 1] - ch[t5 - 1]); i += 2; }; t3 += ido; t4 += ido; k++; }; j++; }; }; fall = true; }; if (fall || state == 119) { // for-while; ik = 0; while (ik < idl1) { c2[ik] = ch2[ik]; ik++; }; t1 = 0; t2 = (ipp2 * idl1); // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = (t1 - ido); t4 = (t2 - ido); // for-while; k = 0; while (k < l1) { t3 += ido; t4 += ido; c1[t3] = (ch[t3] + ch[t4]); c1[t4] = (ch[t4] - ch[t3]); k++; }; j++; }; ar1 = 1.; ai1 = 0.; t1 = 0; t2 = (ipp2 * idl1); t3 = ((ip - 1) * idl1); // for-while; l = 1; while (l < ipph) { t1 += idl1; t2 -= idl1; ar1h = ((dcp * ar1) - (dsp * ai1)); ai1 = ((dcp * ai1) + (dsp * ar1)); ar1 = ar1h; t4 = t1; t5 = t2; t6 = t3; t7 = idl1; // for-while; ik = 0; while (ik < idl1) { ch2[t4++] = (c2[ik] + (ar1 * c2[t7++])); ch2[t5++] = (ai1 * c2[t6++]); ik++; }; dc2 = ar1; ds2 = ai1; ar2 = ar1; ai2 = ai1; t4 = idl1; t5 = ((ipp2 - 1) * idl1); // for-while; j = 2; while (j < ipph) { t4 += idl1; t5 -= idl1; ar2h = ((dc2 * ar2) - (ds2 * ai2)); ai2 = ((dc2 * ai2) + (ds2 * ar2)); ar2 = ar2h; t6 = t1; t7 = t2; t8 = t4; t9 = t5; // for-while; ik = 0; while (ik < idl1) { // HAXE200BUG // ch2[t6++] += (ar2 * c2[t8++]); // ch2[t7++] += (ai2 * c2[t9++]); ch2[t6] += (ar2 * c2[t8]); t6++; t8++; ch2[t7] += (ai2 * c2[t9]); t7++; t9++; ik++; }; j++; }; l++; }; t1 = 0; // for-while; j = 1; while (j < ipph) { t1 += idl1; t2 = t1; // for-while; ik = 0; while (ik < idl1) { ch2[ik] += c2[t2++]; ik++; }; j++; }; if (ido < l1) { state = 132; break; }; t1 = 0; t2 = 0; // for-while; k = 0; while (k < l1) { t3 = t1; t4 = t2; // for-while; i = 0; while (i < ido) { cc[t4++] = ch[t3++]; i++; }; t1 += ido; t2 += t10; k++; }; state = 135; break; fall = false; }; if (state == 132) { // for-while; i = 0; while (i < ido) { t1 = i; t2 = i; // for-while; k = 0; while (k < l1) { cc[t2] = ch[t1]; t1 += ido; t2 += t10; k++; }; i++; }; fall = true; }; if (fall || state == 135) { t1 = 0; t2 = (ido << 1); t3 = 0; t4 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t2; t3 += t0; t4 -= t0; t5 = t1; t6 = t3; t7 = t4; // for-while; k = 0; while (k < l1) { cc[t5 - 1] = ch[t6]; cc[t5] = ch[t7]; t5 += t10; t6 += ido; t7 += ido; k++; }; j++; }; if (ido == 1) { return; }; if (nbd < l1) { state = 141; break; }; t1 = -ido; t3 = 0; t4 = 0; t5 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t2; t3 += t2; t4 += t0; t5 -= t0; t6 = t1; t7 = t3; t8 = t4; t9 = t5; // for-while; k = 0; while (k < l1) { // for-while; i = 2; while (i < ido) { ic = (idp2 - i); cc[(i + t7) - 1] = (ch[(i + t8) - 1] + ch[(i + t9) - 1]); cc[(ic + t6) - 1] = (ch[(i + t8) - 1] - ch[(i + t9) - 1]); cc[i + t7] = (ch[i + t8] + ch[i + t9]); cc[ic + t6] = (ch[i + t9] - ch[i + t8]); i += 2; }; t6 += t10; t7 += t10; t8 += ido; t9 += ido; k++; }; j++; }; return; }; if (state == 141) { t1 = -ido; t3 = 0; t4 = 0; t5 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t2; t3 += t2; t4 += t0; t5 -= t0; // for-while; i = 2; while (i < ido) { t6 = ((idp2 + t1) - i); t7 = (i + t3); t8 = (i + t4); t9 = (i + t5); // for-while; k = 0; while (k < l1) { cc[t7 - 1] = (ch[t8 - 1] + ch[t9 - 1]); cc[t6 - 1] = (ch[t8 - 1] - ch[t9 - 1]); cc[t7] = (ch[t8] + ch[t9]); cc[t6] = (ch[t9] - ch[t8]); t6 += t10; t7 += t10; t8 += ido; t9 += ido; k++; }; i += 2; }; j++; }; _break_loop = 1; break; }; break; }; if (_break_loop == 1) { break; } else { _break_loop = 0; }; }; } // modifiers: static static function drftf1(n : Int, c : Vector, ch : Vector, wa : Vector, ifac : Vector) : Void { var i : Int; var k1 : Int; var l1 : Int; var l2 : Int; var na : Int; var kh : Int; var nf : Int; var ip : Int; var iw : Int; var ido : Int; var idl1 : Int; var ix2 : Int; var ix3 : Int; nf = ifac[1]; na = 1; l2 = n; iw = n; // for-while; k1 = 0; while (k1 < nf) { kh = (nf - k1); ip = ifac[kh + 1]; l1 = Std.int(l2 / ip); ido = Std.int(n / l2); idl1 = (ido * l1); iw -= ((ip - 1) * ido); na = (1 - na); var state : Int = 100; var _break_loop : Int = 0; while (true) { // switch (state) ... while (true) { var fall = false; if (state == 100) { if (ip != 4) { state = 102; break; }; ix2 = (iw + ido); ix3 = (ix2 + ido); if (na != 0) { Drft.dradf4(ido, l1, ch, c, wa, iw - 1, wa, ix2 - 1, wa, ix3 - 1); } else { Drft.dradf4(ido, l1, c, ch, wa, iw - 1, wa, ix2 - 1, wa, ix3 - 1); }; state = 110; break; }; if (state == 102) { if (ip != 2) { state = 104; break; }; if (na != 0) { state = 103; break; }; Drft.dradf2(ido, l1, c, ch, wa, iw - 1); state = 110; break; }; if (state == 103) { Drft.dradf2(ido, l1, ch, c, wa, iw - 1); fall = true; }; if (fall || state == 104) { if (ido == 1) { na = (1 - na); }; if (na != 0) { state = 109; break; }; Drft.dradfg(ido, ip, l1, idl1, c, c, c, ch, ch, wa, iw - 1); na = 1; state = 110; fall = false; break; }; if (state == 109) { Drft.dradfg(ido, ip, l1, idl1, ch, ch, ch, c, c, wa, iw - 1); na = 0; fall = true; }; if (fall || state == 110) { l2 = l1; _break_loop = 1; break; }; break; }; if (_break_loop == 1) { break; } else { _break_loop = 0; }; }; k1++; }; if (na == 1) { return; }; // for-while; i = 0; while (i < n) { c[i] = ch[i]; i++; }; } // modifiers: static static function dradb2(ido : Int, l1 : Int, cc : Vector, ch : Vector, wa1 : Vector, index : Int) : Void { var i : Int; var k : Int; var t0 : Int; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var ti2 : Float; var tr2 : Float; t0 = (l1 * ido); t1 = 0; t2 = 0; t3 = ((ido << 1) - 1); // for-while; k = 0; while (k < l1) { ch[t1] = (cc[t2] + cc[t3 + t2]); ch[t1 + t0] = (cc[t2] - cc[t3 + t2]); t2 = ((t1 += ido) << 1); k++; }; if (ido < 2) { return; }; if (ido != 2) { t1 = 0; t2 = 0; // for-while; k = 0; while (k < l1) { t3 = t1; t5 = ((t4 = t2) + (ido << 1)); t6 = (t0 + t1); // for-while; i = 2; while (i < ido) { t3 += 2; t4 += 2; t5 -= 2; t6 += 2; ch[t3 - 1] = (cc[t4 - 1] + cc[t5 - 1]); tr2 = (cc[t4 - 1] - cc[t5 - 1]); ch[t3] = (cc[t4] - cc[t5]); ti2 = (cc[t4] + cc[t5]); ch[t6 - 1] = ((wa1[(index + i) - 2] * tr2) - (wa1[(index + i) - 1] * ti2)); ch[t6] = ((wa1[(index + i) - 2] * ti2) + (wa1[(index + i) - 1] * tr2)); i += 2; }; t2 = ((t1 += ido) << 1); k++; }; if ((ido % 2) == 1) { return; }; }; t1 = (ido - 1); t2 = (ido - 1); // for-while; k = 0; while (k < l1) { ch[t1] = (cc[t2] + cc[t2]); ch[t1 + t0] = -(cc[t2 + 1] + cc[t2 + 1]); t1 += ido; t2 += (ido << 1); k++; }; } // modifiers: static static function dradb3(ido : Int, l1 : Int, cc : Vector, ch : Vector, wa1 : Vector, index1 : Int, wa2 : Vector, index2 : Int) : Void { var i : Int; var k : Int; var t0 : Int; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var t7 : Int; var t8 : Int; var t9 : Int; var t10 : Int; var ci2 : Float; var ci3 : Float; var di2 : Float; var di3 : Float; var cr2 : Float; var cr3 : Float; var dr2 : Float; var dr3 : Float; var ti2 : Float; var tr2 : Float; t0 = (l1 * ido); t1 = 0; t2 = (t0 << 1); t3 = (ido << 1); t4 = (ido + (ido << 1)); t5 = 0; // for-while; k = 0; while (k < l1) { tr2 = (cc[t3 - 1] + cc[t3 - 1]); cr2 = (cc[t5] + (Drft.taur * tr2)); ch[t1] = (cc[t5] + tr2); ci3 = (Drft.taui * (cc[t3] + cc[t3])); ch[t1 + t0] = (cr2 - ci3); ch[t1 + t2] = (cr2 + ci3); t1 += ido; t3 += t4; t5 += t4; k++; }; if (ido == 1) { return; }; t1 = 0; t3 = (ido << 1); // for-while; k = 0; while (k < l1) { t7 = (t1 + (t1 << 1)); t6 = (t5 = (t7 + t3)); t8 = t1; t10 = ((t9 = (t1 + t0)) + t0); // for-while; i = 2; while (i < ido) { t5 += 2; t6 -= 2; t7 += 2; t8 += 2; t9 += 2; t10 += 2; tr2 = (cc[t5 - 1] + cc[t6 - 1]); cr2 = (cc[t7 - 1] + (Drft.taur * tr2)); ch[t8 - 1] = (cc[t7 - 1] + tr2); ti2 = (cc[t5] - cc[t6]); ci2 = (cc[t7] + (Drft.taur * ti2)); ch[t8] = (cc[t7] + ti2); cr3 = (Drft.taui * (cc[t5 - 1] - cc[t6 - 1])); ci3 = (Drft.taui * (cc[t5] + cc[t6])); dr2 = (cr2 - ci3); dr3 = (cr2 + ci3); di2 = (ci2 + cr3); di3 = (ci2 - cr3); ch[t9 - 1] = ((wa1[(index1 + i) - 2] * dr2) - (wa1[(index1 + i) - 1] * di2)); ch[t9] = ((wa1[(index1 + i) - 2] * di2) + (wa1[(index1 + i) - 1] * dr2)); ch[t10 - 1] = ((wa2[(index2 + i) - 2] * dr3) - (wa2[(index2 + i) - 1] * di3)); ch[t10] = ((wa2[(index2 + i) - 2] * di3) + (wa2[(index2 + i) - 1] * dr3)); i += 2; }; t1 += ido; k++; }; } // modifiers: static static function dradb4(ido : Int, l1 : Int, cc : Vector, ch : Vector, wa1 : Vector, index1 : Int, wa2 : Vector, index2 : Int, wa3 : Vector, index3 : Int) : Void { var i : Int; var k : Int; var t0 : Int; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var t7 : Int; var t8 : Int; var ci2 : Float; var ci3 : Float; var ci4 : Float; var cr2 : Float; var cr3 : Float; var cr4 : Float; var ti1 : Float; var ti2 : Float; var ti3 : Float; var ti4 : Float; var tr1 : Float; var tr2 : Float; var tr3 : Float; var tr4 : Float; t0 = (l1 * ido); t1 = 0; t2 = (ido << 2); t3 = 0; t6 = (ido << 1); // for-while; k = 0; while (k < l1) { t4 = (t3 + t6); t5 = t1; tr3 = (cc[t4 - 1] + cc[t4 - 1]); tr4 = (cc[t4] + cc[t4]); tr1 = (cc[t3] - cc[(t4 += t6) - 1]); tr2 = (cc[t3] + cc[t4 - 1]); ch[t5] = (tr2 + tr3); ch[t5 += t0] = (tr1 - tr4); ch[t5 += t0] = (tr2 - tr3); ch[t5 += t0] = (tr1 + tr4); t1 += ido; t3 += t2; k++; }; if (ido < 2) { return; }; if (ido != 2) { t1 = 0; // for-while; k = 0; while (k < l1) { t5 = ((t4 = (t3 = ((t2 = (t1 << 2)) + t6))) + t6); t7 = t1; // for-while; i = 2; while (i < ido) { t2 += 2; t3 += 2; t4 -= 2; t5 -= 2; t7 += 2; ti1 = (cc[t2] + cc[t5]); ti2 = (cc[t2] - cc[t5]); ti3 = (cc[t3] - cc[t4]); tr4 = (cc[t3] + cc[t4]); tr1 = (cc[t2 - 1] - cc[t5 - 1]); tr2 = (cc[t2 - 1] + cc[t5 - 1]); ti4 = (cc[t3 - 1] - cc[t4 - 1]); tr3 = (cc[t3 - 1] + cc[t4 - 1]); ch[t7 - 1] = (tr2 + tr3); cr3 = (tr2 - tr3); ch[t7] = (ti2 + ti3); ci3 = (ti2 - ti3); cr2 = (tr1 - tr4); cr4 = (tr1 + tr4); ci2 = (ti1 + ti4); ci4 = (ti1 - ti4); ch[(t8 = (t7 + t0)) - 1] = ((wa1[(index1 + i) - 2] * cr2) - (wa1[(index1 + i) - 1] * ci2)); ch[t8] = ((wa1[(index1 + i) - 2] * ci2) + (wa1[(index1 + i) - 1] * cr2)); ch[(t8 += t0) - 1] = ((wa2[(index2 + i) - 2] * cr3) - (wa2[(index2 + i) - 1] * ci3)); ch[t8] = ((wa2[(index2 + i) - 2] * ci3) + (wa2[(index2 + i) - 1] * cr3)); ch[(t8 += t0) - 1] = ((wa3[(index3 + i) - 2] * cr4) - (wa3[(index3 + i) - 1] * ci4)); ch[t8] = ((wa3[(index3 + i) - 2] * ci4) + (wa3[(index3 + i) - 1] * cr4)); i += 2; }; t1 += ido; k++; }; if ((ido % 2) == 1) { return; }; }; t1 = ido; t2 = (ido << 2); t3 = (ido - 1); t4 = (ido + (ido << 1)); // for-while; k = 0; while (k < l1) { t5 = t3; ti1 = (cc[t1] + cc[t4]); ti2 = (cc[t4] - cc[t1]); tr1 = (cc[t1 - 1] - cc[t4 - 1]); tr2 = (cc[t1 - 1] + cc[t4 - 1]); ch[t5] = (tr2 + tr2); ch[t5 += t0] = (Drft.sqrt2 * (tr1 - ti1)); ch[t5 += t0] = (ti2 + ti2); ch[t5 += t0] = (-Drft.sqrt2 * (tr1 + ti1)); t3 += ido; t1 += t2; t4 += t2; k++; }; } // modifiers: static static function dradbg(ido : Int, ip : Int, l1 : Int, idl1 : Int, cc : Vector, c1 : Vector, c2 : Vector, ch : Vector, ch2 : Vector, wa : Vector, index : Int) : Void { var idij : Int; var ipph : Int = 0; var i : Int; var j : Int; var k : Int; var l : Int; var ik : Int; var is_ : Int; var t0 : Int = 0; var t1 : Int; var t2 : Int; var t3 : Int; var t4 : Int; var t5 : Int; var t6 : Int; var t7 : Int; var t8 : Int; var t9 : Int; var t10 : Int = 0; var t11 : Int; var t12 : Int; var dc2 : Float; var ai1 : Float; var ai2 : Float; var ar1 : Float; var ar2 : Float; var ds2 : Float; var nbd : Int = 0; var dcp : Float = 0; var arg : Float; var dsp : Float = 0; var ar1h : Float; var ar2h : Float; var ipp2 : Int = 0; var state : Int = 100; var _break_loop : Int = 0; while (true) { while (true) { var fall = false; if (state == 100) { t10 = (ip * ido); t0 = (l1 * ido); arg = (Drft.tpi / ip); dcp = Math.cos(arg); dsp = Math.sin(arg); nbd = ((ido - 1) >>> 1); ipp2 = ip; ipph = ((ip + 1) >>> 1); if (ido < l1) { state = 103; break; }; t1 = 0; t2 = 0; // for-while; k = 0; while (k < l1) { t3 = t1; t4 = t2; // for-while; i = 0; while (i < ido) { ch[t3] = cc[t4]; t3++; t4++; i++; }; t1 += ido; t2 += t10; k++; }; state = 106; break; }; if (state == 103) { t1 = 0; // for-while; i = 0; while (i < ido) { t2 = t1; t3 = t1; // for-while; k = 0; while (k < l1) { ch[t2] = cc[t3]; t2 += ido; t3 += t10; k++; }; t1++; i++; }; fall = true; }; if (fall || state == 106) { t1 = 0; t2 = (ipp2 * t0); t7 = (t5 = (ido << 1)); // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t6 = t5; // for-while; k = 0; while (k < l1) { ch[t3] = (cc[t6 - 1] + cc[t6 - 1]); ch[t4] = (cc[t6] + cc[t6]); t3 += ido; t4 += ido; t6 += t10; k++; }; t5 += t7; j++; }; if (ido == 1) { state = 116; break; }; if (nbd < l1) { state = 112; break; }; t1 = 0; t2 = (ipp2 * t0); t7 = 0; // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t7 += (ido << 1); t8 = t7; // for-while; k = 0; while (k < l1) { t5 = t3; t6 = t4; t9 = t8; t11 = t8; // for-while; i = 2; while (i < ido) { t5 += 2; t6 += 2; t9 += 2; t11 -= 2; ch[t5 - 1] = (cc[t9 - 1] + cc[t11 - 1]); ch[t6 - 1] = (cc[t9 - 1] - cc[t11 - 1]); ch[t5] = (cc[t9] - cc[t11]); ch[t6] = (cc[t9] + cc[t11]); i += 2; }; t3 += ido; t4 += ido; t8 += t10; k++; }; j++; }; state = 116; break; }; if (state == 112) { t1 = 0; t2 = (ipp2 * t0); t7 = 0; // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t7 += (ido << 1); t8 = t7; t9 = t7; // for-while; i = 2; while (i < ido) { t3 += 2; t4 += 2; t8 += 2; t9 -= 2; t5 = t3; t6 = t4; t11 = t8; t12 = t9; // for-while; k = 0; while (k < l1) { ch[t5 - 1] = (cc[t11 - 1] + cc[t12 - 1]); ch[t6 - 1] = (cc[t11 - 1] - cc[t12 - 1]); ch[t5] = (cc[t11] - cc[t12]); ch[t6] = (cc[t11] + cc[t12]); t5 += ido; t6 += ido; t11 += t10; t12 += t10; k++; }; i += 2; }; j++; }; fall = true; }; if (fall || state == 116) { ar1 = 1.; ai1 = 0.; t1 = 0; t9 = (t2 = (ipp2 * idl1)); t3 = ((ip - 1) * idl1); // for-while; l = 1; while (l < ipph) { t1 += idl1; t2 -= idl1; ar1h = ((dcp * ar1) - (dsp * ai1)); ai1 = ((dcp * ai1) + (dsp * ar1)); ar1 = ar1h; t4 = t1; t5 = t2; t6 = 0; t7 = idl1; t8 = t3; // for-while; ik = 0; while (ik < idl1) { c2[t4++] = (ch2[t6++] + (ar1 * ch2[t7++])); c2[t5++] = (ai1 * ch2[t8++]); ik++; }; dc2 = ar1; ds2 = ai1; ar2 = ar1; ai2 = ai1; t6 = idl1; t7 = (t9 - idl1); // for-while; j = 2; while (j < ipph) { t6 += idl1; t7 -= idl1; ar2h = ((dc2 * ar2) - (ds2 * ai2)); ai2 = ((dc2 * ai2) + (ds2 * ar2)); ar2 = ar2h; t4 = t1; t5 = t2; t11 = t6; t12 = t7; // for-while; ik = 0; while (ik < idl1) { // HAXE200BUG // c2[t4++] += (ar2 * ch2[t11++]); // c2[t5++] += (ai2 * ch2[t12++]); c2[t4] += (ar2 * ch2[t11]); t4++; t11++; c2[t5] += (ai2 * ch2[t12]); t5++; t12++; ik++; }; j++; }; l++; }; t1 = 0; // for-while; j = 1; while (j < ipph) { t1 += idl1; t2 = t1; // for-while; ik = 0; while (ik < idl1) { ch2[ik] += ch2[t2++]; ik++; }; j++; }; t1 = 0; t2 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; // for-while; k = 0; while (k < l1) { ch[t3] = (c1[t3] - c1[t4]); ch[t4] = (c1[t3] + c1[t4]); t3 += ido; t4 += ido; k++; }; j++; }; if (ido == 1) { state = 132; break; }; if (nbd < l1) { state = 128; break; }; t1 = 0; t2 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; // for-while; k = 0; while (k < l1) { t5 = t3; t6 = t4; // for-while; i = 2; while (i < ido) { t5 += 2; t6 += 2; ch[t5 - 1] = (c1[t5 - 1] - c1[t6]); ch[t6 - 1] = (c1[t5 - 1] + c1[t6]); ch[t5] = (c1[t5] + c1[t6 - 1]); ch[t6] = (c1[t5] - c1[t6 - 1]); i += 2; }; t3 += ido; t4 += ido; k++; }; j++; }; state = 132; break; }; if (state == 128) { t1 = 0; t2 = (ipp2 * t0); // for-while; j = 1; while (j < ipph) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; // for-while; i = 2; while (i < ido) { t3 += 2; t4 += 2; t5 = t3; t6 = t4; // for-while; k = 0; while (k < l1) { ch[t5 - 1] = (c1[t5 - 1] - c1[t6]); ch[t6 - 1] = (c1[t5 - 1] + c1[t6]); ch[t5] = (c1[t5] + c1[t6 - 1]); ch[t6] = (c1[t5] - c1[t6 - 1]); t5 += ido; t6 += ido; k++; }; i += 2; }; j++; }; fall = true; }; if (fall || state == 132) { if (ido == 1) { return; }; // for-while; ik = 0; while (ik < idl1) { c2[ik] = ch2[ik]; ik++; }; t1 = 0; // for-while; j = 1; while (j < ip) { t2 = (t1 += t0); // for-while; k = 0; while (k < l1) { c1[t2] = ch[t2]; t2 += ido; k++; }; j++; }; if (nbd > l1) { state = 139; break; }; is_ = (-ido - 1); t1 = 0; // for-while; j = 1; while (j < ip) { is_ += ido; t1 += t0; idij = is_; t2 = t1; // for-while; i = 2; while (i < ido) { t2 += 2; idij += 2; t3 = t2; // for-while; k = 0; while (k < l1) { c1[t3 - 1] = ((wa[(index + idij) - 1] * ch[t3 - 1]) - (wa[index + idij] * ch[t3])); c1[t3] = ((wa[(index + idij) - 1] * ch[t3]) + (wa[index + idij] * ch[t3 - 1])); t3 += ido; k++; }; i += 2; }; j++; }; return; }; if (state == 139) { is_ = (-ido - 1); t1 = 0; // for-while; j = 1; while (j < ip) { is_ += ido; t1 += t0; t2 = t1; // for-while; k = 0; while (k < l1) { idij = is_; t3 = t2; // for-while; i = 2; while (i < ido) { idij += 2; t3 += 2; c1[t3 - 1] = ((wa[(index + idij) - 1] * ch[t3 - 1]) - (wa[index + idij] * ch[t3])); c1[t3] = ((wa[(index + idij) - 1] * ch[t3]) + (wa[index + idij] * ch[t3 - 1])); i += 2; }; t2 += ido; k++; }; j++; }; _break_loop = 1; break; }; break; }; if (_break_loop == 1) { break; } else { _break_loop = 0; }; }; } // modifiers: static static function drftb1(n : Int, c : Vector, ch : Vector, wa : Vector, index : Int, ifac : Vector) : Void { var i : Int; var k1 : Int; var l1 : Int; var l2 : Int = 0; var na : Int; var nf : Int; var ip : Int = 0; var iw : Int; var ix2 : Int; var ix3 : Int; var ido : Int = 0; var idl1 : Int = 0; nf = ifac[1]; na = 0; l1 = 1; iw = 1; // for-while; k1 = 0; while (k1 < nf) { var state : Int = 100; var _break_loop : Int = 1; while (true) { while (true) { var fall = true; if (state == 100) { ip = ifac[k1 + 2]; l2 = (ip * l1); ido = Std.int(n / l2); idl1 = (ido * l1); if (ip != 4) { state = 103; break; }; ix2 = (iw + ido); ix3 = (ix2 + ido); if (na != 0) { Drft.dradb4(ido, l1, ch, c, wa, (index + iw) - 1, wa, (index + ix2) - 1, wa, (index + ix3) - 1); } else { Drft.dradb4(ido, l1, c, ch, wa, (index + iw) - 1, wa, (index + ix2) - 1, wa, (index + ix3) - 1); }; na = (1 - na); state = 115; break; }; if (state == 103) { if (ip != 2) { state = 106; break; }; if (na != 0) { Drft.dradb2(ido, l1, ch, c, wa, (index + iw) - 1); } else { Drft.dradb2(ido, l1, c, ch, wa, (index + iw) - 1); }; na = (1 - na); state = 115; break; }; if (state == 106) { if (ip != 3) { state = 109; break; }; ix2 = (iw + ido); if (na != 0) { Drft.dradb3(ido, l1, ch, c, wa, (index + iw) - 1, wa, (index + ix2) - 1); } else { Drft.dradb3(ido, l1, c, ch, wa, (index + iw) - 1, wa, (index + ix2) - 1); }; na = (1 - na); state = 115; break; }; if (state == 109) { if (na != 0) { Drft.dradbg(ido, ip, l1, idl1, ch, ch, ch, c, c, wa, (index + iw) - 1); } else { Drft.dradbg(ido, ip, l1, idl1, c, c, c, ch, ch, wa, (index + iw) - 1); }; if (ido == 1) { na = (1 - na); }; fall = true; }; if (fall || state == 115) { l1 = l2; iw += ((ip - 1) * ido); _break_loop = 1; break; }; break; }; if (_break_loop == 1) { break; } else { _break_loop = 0; }; }; k1++; }; if (na == 0) { return; }; // for-while; i = 0; while (i < n) { c[i] = ch[i]; i++; }; } public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/DspState.hx000066400000000000000000000272601454362722700276430ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class DspState { /* * generated source for DspState */ inline static var M_PI : Float = 3.1415926539; inline static var VI_TRANSFORMB : Int = 1; inline static var VI_WINDOWB : Int = 1; public var analysisp : Int; public var vi : Info; public var modebits : Int; var pcm : Array>; var pcm_storage : Int; var pcm_current : Int; var pcm_returned : Int; var multipliers : Vector; var envelope_storage : Int; var envelope_current : Int; var eofflag : Int; public var lW : Int; var W : Int; public var nW : Int; var centerW : Int; var granulepos : Int; var sequence : Int; var glue_bits : Int; var time_bits : Int; var floor_bits : Int; var res_bits : Int; public var window : Array>>>>; public var transform : Array>; public var fullbooks : Array; public var mode : Array; var header : Bytes; var header1 : Bytes; var header2 : Bytes; // modifiers: public public function __new_0() : Void { transform = new Array(); window = new Array(); window[0] = new Array(); window[0][0] = new Array(); window[0][1] = new Array(); window[0][0][0] = new Array(); window[0][0][1] = new Array(); window[0][1][0] = new Array(); window[0][1][1] = new Array(); window[1] = new Array(); window[1][0] = new Array(); window[1][1] = new Array(); window[1][0][0] = new Array(); window[1][0][1] = new Array(); window[1][1][0] = new Array(); window[1][1][1] = new Array(); } // modifiers: static, private static private function ilog2(v : Int) : Int { var ret : Int = 0; while (v > 1) { ret++; v >>>= 1; }; return ret; } // modifiers: static static function window_(type : Int, window : Int, left : Int, right : Int) : Vector { // FIXME: shadows variable 'window'; //var ret : Array = new float[window]; var ret : Vector = new Vector(window, true); if (type == 0) { var leftbegin : Int = Std.int(window / 4) - Std.int(left / 2); var rightbegin : Int = (window - Std.int(window / 4)) - Std.int(right / 2); // for-while; var i : Int = 0; while (i < left) { var x : Float = (((i + 0.5) / left) * DspState.M_PI) / 2.; x = Math.sin(x); x *= x; x *= (DspState.M_PI / 2.); x = Math.sin(x); ret[i + leftbegin] = x; i++; }; // for-while; var i : Int = leftbegin + left; while (i < rightbegin) { ret[i] = 1.; i++; }; // for-while; var i : Int = 0; while (i < right) { var x : Float = ((((right - i) - 0.5) / right) * DspState.M_PI) / 2.; x = Math.sin(x); x *= x; x *= (DspState.M_PI / 2.); x = Math.sin(x); ret[i + rightbegin] = x; i++; }; } else { return null; }; return ret; } // modifiers: function init(vi : Info, encp : Bool) : Int { this.vi = vi; modebits = DspState.ilog2(vi.modes); //transform[0] = new Object[DspState.VI_TRANSFORMB]; //transform[0] = new Vector(DspState.VI_TRANSFORMB, true); transform[0] = ArrayTools.alloc(DspState.VI_TRANSFORMB); //transform[1] = new Object[DspState.VI_TRANSFORMB]; //transform[1] = new Vector(DspState.VI_TRANSFORMB, true); transform[1] = ArrayTools.alloc(DspState.VI_TRANSFORMB); transform[0][0] = new Mdct(); transform[1][0] = new Mdct(); transform[0][0].init(vi.blocksizes[0]); transform[1][0].init(vi.blocksizes[1]); //DspState.window[0][0][0] = new float[DspState.VI_WINDOWB]; window[0][0][0] = new Array(); window[0][0][1] = window[0][0][0]; window[0][1][0] = window[0][0][0]; window[0][1][1] = window[0][0][0]; //DspState.window[1][0][0] = new float[DspState.VI_WINDOWB]; window[1][0][0] = new Array(); //DspState.window[1][0][1] = new float[DspState.VI_WINDOWB]; window[1][0][1] = new Array(); //DspState.window[1][1][0] = new float[DspState.VI_WINDOWB]; window[1][1][0] = new Array(); //DspState.window[1][1][1] = new float[DspState.VI_WINDOWB]; window[1][1][1] = new Array(); // for-while; var i : Int = 0; while (i < DspState.VI_WINDOWB) { window[0][0][0][i] = DspState.window_(i, vi.blocksizes[0], Std.int(vi.blocksizes[0] / 2), Std.int(vi.blocksizes[0] / 2)); window[1][0][0][i] = DspState.window_(i, vi.blocksizes[1], Std.int(vi.blocksizes[0] / 2), Std.int(vi.blocksizes[0] / 2)); window[1][0][1][i] = DspState.window_(i, vi.blocksizes[1], Std.int(vi.blocksizes[0] / 2), Std.int(vi.blocksizes[1] / 2)); window[1][1][0][i] = DspState.window_(i, vi.blocksizes[1], Std.int(vi.blocksizes[1] / 2), Std.int(vi.blocksizes[0] / 2)); window[1][1][1][i] = DspState.window_(i, vi.blocksizes[1], Std.int(vi.blocksizes[1] / 2), Std.int(vi.blocksizes[1] / 2)); i++; }; //fullbooks = new CodeBook[vi.books]; //fullbooks = new Vector(vi.books, true); fullbooks = ArrayTools.alloc(vi.books); // for-while; var i : Int = 0; while (i < vi.books) { fullbooks[i] = new CodeBook(); fullbooks[i].init_decode(vi.book_param[i]); i++; }; pcm_storage = 8192; //pcm = new float[vi.channels]; //pcm = new Array(); pcm = ArrayTools.alloc(vi.channels); // for-while; var i : Int = 0; while (i < vi.channels) { //pcm[i] = new Vector(pcm_storage, true); pcm[i] = new Vector(pcm_storage, false); i++; }; lW = 0; W = 0; centerW = Std.int(vi.blocksizes[1] / 2); pcm_current = centerW; //mode = new Object[vi.modes]; //mode = new Vector(vi.modes, true); mode = ArrayTools.alloc(vi.modes); // for-while; var i : Int = 0; while (i < vi.modes) { var mapnum : Int = vi.mode_param[i].mapping; var maptype : Int = vi.map_type[mapnum]; mode[i] = FuncMapping.mapping_P[maptype].look(this, vi.mode_param[i], vi.map_param[mapnum]); i++; }; return 0; } // modifiers: public public function synthesis_init(vi : Info) : Int { init(vi, false); pcm_returned = centerW; centerW -= Std.int(vi.blocksizes[W] / 4) + Std.int(vi.blocksizes[lW] / 4); granulepos = -1; sequence = -1; return 0; } // modifiers: function __new_1(vi : Info) { __new_0(); init(vi, false); pcm_returned = centerW; centerW -= Std.int(vi.blocksizes[W] / 4) + Std.int(vi.blocksizes[lW] / 4); granulepos = -1; sequence = -1; } // modifiers: public public function synthesis_blockin(vb : Block) : Int { if ((centerW > (vi.blocksizes[1] / 2)) && (pcm_returned > 8192)) { var shiftPCM : Int = centerW - Std.int(vi.blocksizes[1] / 2); shiftPCM = ((pcm_returned < shiftPCM ? pcm_returned : shiftPCM)); pcm_current -= shiftPCM; centerW -= shiftPCM; pcm_returned -= shiftPCM; if (shiftPCM != 0) { // for-while; var i : Int = 0; while (i < vi.channels) { //System.arraycopyVF(pcm[i], shiftPCM, pcm[i], 0, pcm_current); pcm[i] = VectorTools.copyF(pcm[i], shiftPCM, pcm[i], 0, pcm_current); i++; }; }; }; lW = W; W = vb.W; nW = -1; glue_bits += vb.glue_bits; time_bits += vb.time_bits; floor_bits += vb.floor_bits; res_bits += vb.res_bits; if ((sequence + 1) != vb.sequence) { granulepos = -1; }; sequence = vb.sequence; var sizeW : Int = vi.blocksizes[W]; var _centerW : Int = centerW + Std.int(vi.blocksizes[lW] / 4) + Std.int(sizeW / 4); var beginW : Int = _centerW - Std.int(sizeW / 2); var endW : Int = beginW + sizeW; var beginSl : Int = 0; var endSl : Int = 0; if (endW > pcm_storage) { pcm_storage = endW + vi.blocksizes[1]; // for-while; var i : Int = 0; while (i < vi.channels) { //var foo : Array = new float[pcm_storage]; // var foo : Vector = new Vector(pcm_storage, true); // System.arraycopyVF(pcm[i], 0, foo, 0, pcm[i].length); // pcm[i] = foo; pcm[i].length = pcm_storage; i++; }; }; if (W == 0) { beginSl = 0; endSl = Std.int(vi.blocksizes[0] / 2); } else if (W == 1) { beginSl = Std.int(vi.blocksizes[1] / 4) - Std.int(vi.blocksizes[lW] / 4); endSl = beginSl + Std.int(vi.blocksizes[lW] / 2); }; // for-while; var j : Int = 0; while (j < vi.channels) { var _pcm : Int = beginW; var i : Int = 0; // for-while; i = beginSl; while (i < endSl) { pcm[j][_pcm + i] += vb.pcm[j][i]; i++; }; // for-while; while (i < sizeW) { pcm[j][_pcm + i] = vb.pcm[j][i]; i++; }; j++; }; if (granulepos == -1) { granulepos = vb.granulepos; } else { granulepos += (_centerW - centerW); if ((vb.granulepos != -1) && (granulepos != vb.granulepos)) { if ((granulepos > vb.granulepos) && (vb.eofflag != 0)) { _centerW -= (granulepos - vb.granulepos); }; granulepos = vb.granulepos; }; }; centerW = _centerW; pcm_current = endW; if (vb.eofflag != 0) { eofflag = 1; }; return 0; } // modifiers: public public function synthesis_pcmout(_pcm : Array>>, index : Vector) : Int { if (pcm_returned < centerW) { if (_pcm != null) { // for-while; var i : Int = 0; while (i < vi.channels) { index[i] = pcm_returned; i++; }; _pcm[0] = pcm; }; return centerW - pcm_returned; }; return 0; } // modifiers: public public function synthesis_read(bytes : Int) : Int { if ((bytes != 0) && ((pcm_returned + bytes) > centerW)) { return -1; }; pcm_returned += bytes; return 0; } // modifiers: public public function clear() : Void { } // modifiers: inline, public inline public function new(?vi : Info) { // FIXME: implement disambiguation handler; // __new_0() : float; // __new_1(vi : Info); if (vi == null) { __new_0(); } else { __new_1(vi); } } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/EncodeAuxNearestMatch.hx000066400000000000000000000005671454362722700322670ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; class EncodeAuxNearestMatch { /* * generated source for EncodeAuxNearestMatch */ public var ptr0 : Array; public var ptr1 : Array; public var p : Array; public var q : Array; public var aux : Int; public var alloc : Int; public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/EncodeAuxThreshMatch.hx000066400000000000000000000005161454362722700321150ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; class EncodeAuxThreshMatch { /* * generated source for EncodeAuxThreshMatch */ public var quantthresh : Array; public var quantmap : Array; public var quantvals : Int; public var threshvals : Int; public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Floor0.hx000066400000000000000000000306701454362722700272540ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class Floor0 extends FuncFloor { /* * generated source for Floor0 */ // modifiers: override function pack(i : Dynamic, opb : Buffer) : Void { var info : InfoFloor0 = i; opb.write(info.order, 8); opb.write(info.rate, 16); opb.write(info.barkmap, 16); opb.write(info.ampbits, 6); opb.write(info.ampdB, 8); opb.write(info.numbooks - 1, 4); // for-while; var j : Int = 0; while (j < info.numbooks) { opb.write(info.books[j], 8); j++; }; } // modifiers: override function unpack(vi : Info, opb : Buffer) : Dynamic { var info : InfoFloor0 = new InfoFloor0(); info.order = opb.read(8); info.rate = opb.read(16); info.barkmap = opb.read(16); info.ampbits = opb.read(6); info.ampdB = opb.read(8); info.numbooks = (opb.read(4) + 1); if ((((info.order < 1) || (info.rate < 1)) || (info.barkmap < 1)) || (info.numbooks < 1)) { return null; }; // for-while; var j : Int = 0; while (j < info.numbooks) { info.books[j] = opb.read(8); if ((info.books[j] < 0) || (info.books[j] >= vi.books)) { return null; }; j++; }; return info; } // modifiers: override function look(vd : DspState, mi : InfoMode, i : Dynamic) : Dynamic { var scale : Float; var vi : Info = vd.vi; var info : InfoFloor0 = i; var look : LookFloor0 = new LookFloor0(); look.m = info.order; look.n = Std.int(vi.blocksizes[mi.blockflag] / 2); look.ln = info.barkmap; look.vi = info; look.lpclook.init(look.ln, look.m); scale = (look.ln / toBARK(info.rate / 2.)); //look.linearmap = new int[look.n]; look.linearmap = new Vector(look.n, true); // for-while; var j : Int = 0; while (j < look.n) { var val : Int = Math.floor(toBARK(((info.rate / 2.) / look.n) * j) * scale); if (val >= look.ln) { val = look.ln; }; look.linearmap[j] = val; j++; }; return look; } // modifiers: static static function toBARK(f : Float) : Float { return ((13.1 * Math.atan(0.00074 * f)) + (2.24 * Math.atan((f * f) * 1.85e-8))) + (1e-4 * f); } // modifiers: function state(i : Dynamic) : Dynamic { var state : EchstateFloor0 = new EchstateFloor0(); var info : InfoFloor0 = i; //state.codewords = new int[info.order]; state.codewords = new Vector(info.order, true); //state.curve = new float[info.barkmap]; state.curve = new Vector(info.barkmap, true); state.frameno = -1; return state; } // modifiers: override function free_info(i : Dynamic) : Void { } // modifiers: override function free_look(i : Dynamic) : Void { } // modifiers: override function free_state(vs : Dynamic) : Void { } // modifiers: override function forward(vb : Block, i : Dynamic, in_ : Vector, out : Vector, vs : Dynamic) : Int { return 0; } // discarded initializer: 'null'; var lsp : Vector; // modifiers: function inverse(vb : Block, i : Dynamic, out : Vector) : Int { var look : LookFloor0 = i; var info : InfoFloor0 = look.vi; var ampraw : Int = vb.opb.read(info.ampbits); if (ampraw > 0) { var maxval : Int = (1 << info.ampbits) - 1; var amp : Float = (ampraw / maxval) * info.ampdB; var booknum : Int = vb.opb.read(ilog(info.numbooks)); if ((booknum != -1) && (booknum < info.numbooks)) { // synchronized (this) ...; { if ((lsp == null) || (lsp.length < look.m)) { //lsp = new float[look.m]; lsp = new Vector(look.m, true); } else { // for-while; var j : Int = 0; while (j < look.m) { lsp[j] = 0.; j++; }; }; var b : CodeBook = vb.vd.fullbooks[info.books[booknum]]; var last : Float = 0.; // for-while; var j : Int = 0; while (j < look.m) { out[j] = 0.0; j++; }; // for-while; var j : Int = 0; while (j < look.m) { if (b.decodevs(lsp, j, vb.opb, 1, -1) == -1) { // for-while; var k : Int = 0; while (k < look.n) { out[k] = 0.0; k++; }; return 0; }; j += b.dim; }; // for-while; var j : Int = 0; while (j < look.m) { // for-while; var k : Int = 0; while (k < b.dim) { lsp[j] += last; k++; j++; }; last = lsp[j - 1]; }; Lsp.lsp_to_curve(out, look.linearmap, look.n, look.ln, lsp, look.m, amp, info.ampdB); return 1; }; }; }; return 0; } // modifiers: override function inverse1(vb : Block, i : Dynamic, memo : Dynamic) : Dynamic { var look : LookFloor0 = i; var info : InfoFloor0 = look.vi; var lsp : Vector = null; /* if (isinstance(memo, (Vector))) { lsp = memo; }; */ if (Std.is(memo, Vector)) { lsp = memo; } var ampraw : Int = vb.opb.read(info.ampbits); if (ampraw > 0) { var maxval : Int = (1 << info.ampbits) - 1; var amp : Float = (ampraw / maxval) * info.ampdB; var booknum : Int = vb.opb.read(ilog(info.numbooks)); if ((booknum != -1) && (booknum < info.numbooks)) { var b : CodeBook = vb.vd.fullbooks[info.books[booknum]]; var last : Float = 0.; if ((lsp == null) || (lsp.length < look.m + 1)) { //lsp = new float[look.m + 1]; lsp = new Vector(look.m + 1, true); } else { // for-while; var j : Int = 0; while (j < lsp.length) { lsp[j] = 0.; j++; }; }; // for-while; var j : Int = 0; while (j < look.m) { if (b.decodev_set(lsp, j, vb.opb, b.dim) == -1) { return null; }; j += b.dim; }; // for-while; var j : Int = 0; while (j < look.m) { // for-while; var k : Int = 0; while (k < b.dim) { lsp[j] += last; k++; j++; }; last = lsp[j - 1]; }; lsp[look.m] = amp; return lsp; }; }; return null; } // modifiers: override function inverse2(vb : Block, i : Dynamic, memo : Dynamic, out : Vector) : Int { var look : LookFloor0 = i; var info : InfoFloor0 = look.vi; if (memo != null) { var lsp : Vector = memo; var amp : Float = lsp[look.m]; Lsp.lsp_to_curve(out, look.linearmap, look.n, look.ln, lsp, look.m, amp, info.ampdB); return 1; }; // for-while; var j : Int = 0; while (j < look.n) { out[j] = 0.; j++; }; return 0; } // modifiers: static static function fromdB(x : Float) : Float { return Math.exp(x * 0.11512925); } // modifiers: static, private static private function ilog(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret++; v >>>= 1; }; return ret; } // modifiers: static static function lsp_to_lpc(lsp : Vector, lpc : Vector, m : Int) : Void { var i : Int; var j : Int; var m2 : Int = Std.int(m / 2); //var O : Vector = new float[m2]; var O : Vector = new Vector(m2, true); //var E : Vector = new float[m2]; var E : Vector = new Vector(m2, true); var A : Float; //var Ae : Vector = new float[m2 + 1]; var Ae : Vector = new Vector(m2 + 1, true); //var Ao : Vector = new float[m2 + 1]; var Ao : Vector = new Vector(m2 + 1, true); var B : Float; //var Be : Vector = new float[m2]; var Be : Vector = new Vector(m2, true); //var Bo : Vector = new float[m2]; var Bo : Vector = new Vector(m2, true); var temp : Float; // for-while; i = 0; while (i < m2) { O[i] = -2. * Math.cos(lsp[i * 2]); E[i] = -2. * Math.cos(lsp[(i * 2) + 1]); i++; }; // for-while; j = 0; while (j < m2) { Ae[j] = 0.; Ao[j] = 1.; Be[j] = 0.; Bo[j] = 1.; j++; }; Ao[j] = 1.; Ae[j] = 1.; // for-while; i = 1; while (i < (m + 1)) { A = (B = 0.); // for-while; j = 0; while (j < m2) { temp = ((O[j] * Ao[j]) + Ae[j]); Ae[j] = Ao[j]; Ao[j] = A; A += temp; temp = ((E[j] * Bo[j]) + Be[j]); Be[j] = Bo[j]; Bo[j] = B; B += temp; j++; }; lpc[i - 1] = ((((A + Ao[j]) + B) - Ae[j]) / 2); Ao[j] = A; Ae[j] = B; i++; }; } // modifiers: static static function lpc_to_curve(curve : Vector, lpc : Vector, amp : Float, l : LookFloor0, name : String, frameno : Int) : Void { //var lcurve : Vector = new float[Math.max(l.ln * 2, (l.m * 2) + 2)]; var lcurve : Vector = new Vector(System.max(l.ln * 2, (l.m * 2) + 2), true); if (amp == 0) { // for-while; var j : Int = 0; while (j < l.n) { curve[j] = 0.0; j++; }; return; }; l.lpclook.lpc_to_curve(lcurve, lpc, amp); // for-while; var i : Int = 0; while (i < l.n) { curve[i] = lcurve[l.linearmap[i]]; i++; }; } public function new() { lsp = null; } } class InfoFloor0 { /* * generated source for InfoFloor0 */ public var order : Int; public var rate : Int; public var barkmap : Int; public var ampbits : Int; public var ampdB : Int; public var numbooks : Int; // discarded initializer: 'new int[16]'; public var books : Vector; public function new() { books = new Vector(16, true); } } class LookFloor0 { /* * generated source for LookFloor0 */ public var n : Int; public var ln : Int; public var m : Int; public var linearmap : Vector; public var vi : InfoFloor0; // discarded initializer: 'Lpc()'; public var lpclook : Lpc; public function new() { lpclook = new Lpc(); } } class EchstateFloor0 { /* * generated source for EchstateFloor0 */ public var codewords : Vector; public var curve : Vector; public var frameno : Int; public var codes : Int; public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Floor1.hx000066400000000000000000000564341454362722700272630ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class Floor1 extends FuncFloor { /* * generated source for Floor1 */ inline static var floor1_rangedb : Int = 140; inline static var VIF_POSIT : Int = 63; // modifiers: override function pack(i : Dynamic, opb : Buffer) : Void { var info : InfoFloor1 = i; var count : Int = 0; var rangebits : Int; var maxposit : Int = info.postlist[1]; var maxclass : Int = -1; opb.write(info.partitions, 5); // for-while; var j : Int = 0; while (j < info.partitions) { opb.write(info.partitionclass[j], 4); if (maxclass < info.partitionclass[j]) { maxclass = info.partitionclass[j]; }; j++; }; // for-while; var j : Int = 0; while (j < (maxclass + 1)) { opb.write(info.class_dim[j] - 1, 3); opb.write(info.class_subs[j], 2); if (info.class_subs[j] != 0) { opb.write(info.class_book[j], 8); }; // for-while; var k : Int = 0; while (k < (1 << info.class_subs[j])) { opb.write(info.class_subbook[j][k] + 1, 8); k++; }; j++; }; opb.write(info.mult - 1, 2); opb.write(ilog2(maxposit), 4); rangebits = ilog2(maxposit); // for-while; var j : Int = 0; var k : Int = 0; while (j < info.partitions) { count += info.class_dim[info.partitionclass[j]]; // for-while; while (k < count) { opb.write(info.postlist[k + 2], rangebits); k++; }; j++; }; } // modifiers: override function unpack(vi : Info, opb : Buffer) : Dynamic { var count : Int = 0; var maxclass : Int = -1; var rangebits : Int; var info : InfoFloor1 = new InfoFloor1(); info.partitions = opb.read(5); // for-while; var j : Int = 0; while (j < info.partitions) { info.partitionclass[j] = opb.read(4); if (maxclass < info.partitionclass[j]) { maxclass = info.partitionclass[j]; }; j++; }; // for-while; var j : Int = 0; while (j < (maxclass + 1)) { info.class_dim[j] = (opb.read(3) + 1); info.class_subs[j] = opb.read(2); if (info.class_subs[j] < 0) { info.free(); return null; }; if (info.class_subs[j] != 0) { info.class_book[j] = opb.read(8); }; if ((info.class_book[j] < 0) || (info.class_book[j] >= vi.books)) { info.free(); return null; }; // for-while; var k : Int = 0; while (k < (1 << info.class_subs[j])) { info.class_subbook[j][k] = (opb.read(8) - 1); if ((info.class_subbook[j][k] < -1) || (info.class_subbook[j][k] >= vi.books)) { info.free(); return null; }; k++; }; j++; }; info.mult = (opb.read(2) + 1); rangebits = opb.read(4); // for-while; var j : Int = 0; var k : Int = 0; while (j < info.partitions) { count += info.class_dim[info.partitionclass[j]]; // for-while; while (k < count) { var t : Int = info.postlist[k + 2] = opb.read(rangebits); if ((t < 0) || (t >= (1 << rangebits))) { info.free(); return null; }; k++; }; j++; }; info.postlist[0] = 0; info.postlist[1] = (1 << rangebits); return info; } // modifiers: override function look(vd : DspState, mi : InfoMode, i : Dynamic) : Dynamic { var _n : Int = 0; //var sortpointer : Vector = new int[Floor1.VIF_POSIT + 2]; var sortpointer : Vector = new Vector(VIF_POSIT + 2, true); var info : InfoFloor1 = i; var look : LookFloor1 = new LookFloor1(); look.vi = info; look.n = info.postlist[1]; // for-while; var j : Int = 0; while (j < info.partitions) { _n += info.class_dim[info.partitionclass[j]]; j++; }; _n += 2; look.posts = _n; // for-while; var j : Int = 0; while (j < _n) { sortpointer[j] = j; j++; }; var foo : Int; // for-while; var j : Int = 0; while (j < (_n - 1)) { // for-while; var k : Int = j; while (k < _n) { if (info.postlist[sortpointer[j]] > info.postlist[sortpointer[k]]) { foo = sortpointer[k]; sortpointer[k] = sortpointer[j]; sortpointer[j] = foo; }; k++; }; j++; }; // for-while; var j : Int = 0; while (j < _n) { look.forward_index[j] = sortpointer[j]; j++; }; // for-while; var j : Int = 0; while (j < _n) { look.reverse_index[look.forward_index[j]] = j; j++; }; // for-while; var j : Int = 0; while (j < _n) { look.sorted_index[j] = info.postlist[look.forward_index[j]]; j++; }; switch (info.mult) { case 1: look.quant_q = 256; case 2: look.quant_q = 128; case 3: look.quant_q = 86; case 4: look.quant_q = 64; default: look.quant_q = -1; }; // for-while; var j : Int = 0; while (j < (_n - 2)) { var lo : Int = 0; var hi : Int = 1; var lx : Int = 0; var hx : Int = look.n; var currentx : Int = info.postlist[j + 2]; // for-while; var k : Int = 0; while (k < (j + 2)) { var x : Int = info.postlist[k]; if ((x > lx) && (x < currentx)) { lo = k; lx = x; }; if ((x < hx) && (x > currentx)) { hi = k; hx = x; }; k++; }; look.loneighbor[j] = lo; look.hineighbor[j] = hi; j++; }; return look; } // modifiers: override function free_info(i : Dynamic) : Void { } // modifiers: override function free_look(i : Dynamic) : Void { } // modifiers: override function free_state(vs : Dynamic) : Void { } // modifiers: override function forward(vb : Block, i : Dynamic, in_ : Vector, out : Vector, vs : Dynamic) : Int { return 0; } // modifiers: override function inverse1(vb : Block, ii : Dynamic, memo : Dynamic) : Dynamic { var look : LookFloor1 = ii; var info : InfoFloor1 = look.vi; var books : Array = vb.vd.fullbooks; if (vb.opb.read(1) == 1) { var fit_value : Vector = null; if (Std.is(memo, Vector)) { fit_value = memo; }; if ((fit_value == null) || (fit_value.length < look.posts)) { //fit_value = new int[look.posts]; fit_value = new Vector(look.posts, true); } else { // for-while; var i : Int = 0; while (i < fit_value.length) { fit_value[i] = 0; i++; }; }; fit_value[0] = vb.opb.read(ilog(look.quant_q - 1)); fit_value[1] = vb.opb.read(ilog(look.quant_q - 1)); // for-while; var i : Int = 0; var j : Int = 2; while (i < info.partitions) { var clss : Int = info.partitionclass[i]; var cdim : Int = info.class_dim[clss]; var csubbits : Int = info.class_subs[clss]; var csub : Int = 1 << csubbits; var cval : Int = 0; if (csubbits != 0) { cval = books[info.class_book[clss]].decode(vb.opb); if (cval == -1) { return null; }; }; // for-while; var k : Int = 0; while (k < cdim) { var book : Int = info.class_subbook[clss][cval & (csub - 1)]; cval >>>= csubbits; if (book >= 0) { if ((fit_value[j + k] = books[book].decode(vb.opb)) == -1) { return null; }; } else { fit_value[j + k] = 0; }; k++; }; j += cdim; i++; }; // for-while; var i : Int = 2; while (i < look.posts) { var predicted : Int = render_point(info.postlist[look.loneighbor[i - 2]], info.postlist[look.hineighbor[i - 2]], fit_value[look.loneighbor[i - 2]], fit_value[look.hineighbor[i - 2]], info.postlist[i]); var hiroom : Int = look.quant_q - predicted; var loroom : Int = predicted; var room : Int = ((hiroom < loroom ? hiroom : loroom)) << 1; var val : Int = fit_value[i]; if (val != 0) { if (val >= room) { if (hiroom > loroom) { val = (val - loroom); } else { val = (-1 - (val - hiroom)); }; } else { if ((val & 1) != 0) { val = -((val + 1) >>> 1); } else { val >>= 1; }; }; fit_value[i] = (val + predicted); fit_value[look.loneighbor[i - 2]] &= 0x7fff; fit_value[look.hineighbor[i - 2]] &= 0x7fff; } else { fit_value[i] = (predicted | 0x8000); }; i++; }; return fit_value; }; return null; } // modifiers: static, private static private function render_point(x0 : Int, x1 : Int, y0 : Int, y1 : Int, x : Int) : Int { y0 &= 0x7fff; y1 &= 0x7fff; var dy : Int = y1 - y0; var adx : Int = x1 - x0; var ady : Int = System.abs(dy); var err : Int = ady * (x - x0); var off : Int = Std.int(err / adx); if (dy < 0) { return y0 - off; }; return y0 + off; } // modifiers: override function inverse2(vb : Block, i : Dynamic, memo : Dynamic, out : Vector) : Int { var look : LookFloor1 = i; var info : InfoFloor1 = look.vi; var n : Int = Std.int(vb.vd.vi.blocksizes[vb.mode] / 2); if (memo != null) { var fit_value : Vector = memo; var hx : Int = 0; var lx : Int = 0; var ly : Int = fit_value[0] * info.mult; // for-while; var j : Int = 1; while (j < look.posts) { var current : Int = look.forward_index[j]; var hy : Int = fit_value[current] & 0x7fff; if (hy == fit_value[current]) { hy *= info.mult; hx = info.postlist[current]; render_line(lx, hx, ly, hy, out); lx = hx; ly = hy; }; j++; }; // for-while; var j : Int = hx; while (j < n) { out[j] *= out[j - 1]; j++; }; return 1; }; // for-while; var j : Int = 0; while (j < n) { out[j] = 0.; j++; }; return 0; } static private var FLOOR_fromdB_LOOKUP : Array = [1.0649863e-07, 1.1341951e-07, 1.2079015e-07, 1.2863978e-07, 1.3699951e-07, 1.4590251e-07, 1.5538408e-07, 1.6548181e-07, 1.7623575e-07, 1.8768855e-07, 1.9988561e-07, 2.128753e-07, 2.2670913e-07, 2.4144197e-07, 2.5713223e-07, 2.7384213e-07, 2.9163793e-07, 3.1059021e-07, 3.3077411e-07, 3.5226968e-07, 3.7516214e-07, 3.9954229e-07, 4.2550680e-07, 4.5315863e-07, 4.8260743e-07, 5.1396998e-07, 5.4737065e-07, 5.8294187e-07, 6.2082472e-07, 6.6116941e-07, 7.0413592e-07, 7.4989464e-07, 7.9862701e-07, 8.5052630e-07, 9.0579828e-07, 9.6466216e-07, 1.0273513e-06, 1.0941144e-06, 1.1652161e-06, 1.2409384e-06, 1.3215816e-06, 1.4074654e-06, 1.4989305e-06, 1.5963394e-06, 1.7000785e-06, 1.8105592e-06, 1.9282195e-06, 2.0535261e-06, 2.1869758e-06, 2.3290978e-06, 2.4804557e-06, 2.6416497e-06, 2.8133190e-06, 2.9961443e-06, 3.1908506e-06, 3.3982101e-06, 3.6190449e-06, 3.8542308e-06, 4.1047004e-06, 4.3714470e-06, 4.6555282e-06, 4.9580707e-06, 5.2802740e-06, 5.6234160e-06, 5.9888572e-06, 6.3780469e-06, 6.7925283e-06, 7.2339451e-06, 7.7040476e-06, 8.2047000e-06, 8.7378876e-06, 9.3057248e-06, 9.9104632e-06, 1.0554501e-05, 1.1240392e-05, 1.1970856e-05, 1.2748789e-05, 1.3577278e-05, 1.4459606e-05, 1.5399272e-05, 1.6400004e-05, 1.7465768e-05, 1.8600792e-05, 1.9809576e-05, 2.1096914e-05, 2.2467911e-05, 2.3928002e-05, 2.5482978e-05, 2.7139006e-05, 2.8902651e-05, 3.0780908e-05, 3.2781225e-05, 3.4911534e-05, 3.7180282e-05, 3.9596466e-05, 4.2169667e-05, 4.4910090e-05, 4.7828601e-05, 5.0936773e-05, 5.4246931e-05, 5.7772202e-05, 6.1526565e-05, 6.5524908e-05, 6.9783085e-05, 7.4317983e-05, 7.9147585e-05, 8.4291040e-05, 8.9768747e-05, 9.5602426e-05, 0.00010181521, 0.00010843174, 0.00011547824, 0.00012298267, 0.00013097477, 0.00013948625, 0.00014855085, 0.00015820453, 0.00016848555, 0.00017943469, 0.00019109536, 0.00020351382, 0.00021673929, 0.00023082423, 0.00024582449, 0.00026179955, 0.00027881276, 0.00029693158, 0.00031622787, 0.00033677814, 0.00035866388, 0.00038197188, 0.00040679456, 0.00043323036, 0.00046138411, 0.00049136745, 0.00052329927, 0.00055730621, 0.00059352311, 0.00063209358, 0.00067317058, 0.00071691700, 0.00076350630, 0.00081312324, 0.00086596457, 0.00092223983, 0.00098217216, 0.0010459992, 0.0011139742, 0.0011863665, 0.0012634633, 0.0013455702, 0.0014330129, 0.0015261382, 0.0016253153, 0.0017309374, 0.0018434235, 0.0019632195, 0.0020908006, 0.0022266726, 0.0023713743, 0.0025254795, 0.0026895994, 0.0028643847, 0.0030505286, 0.0032487691, 0.0034598925, 0.0036847358, 0.0039241906, 0.0041792066, 0.0044507950, 0.0047400328, 0.0050480668, 0.0053761186, 0.0057254891, 0.0060975636, 0.0064938176, 0.0069158225, 0.0073652516, 0.0078438871, 0.0083536271, 0.0088964928, 0.009474637, 0.010090352, 0.010746080, 0.011444421, 0.012188144, 0.012980198, 0.013823725, 0.014722068, 0.015678791, 0.016697687, 0.017782797, 0.018938423, 0.020169149, 0.021479854, 0.022875735, 0.024362330, 0.025945531, 0.027631618, 0.029427276, 0.031339626, 0.033376252, 0.035545228, 0.037855157, 0.040315199, 0.042935108, 0.045725273, 0.048696758, 0.051861348, 0.055231591, 0.058820850, 0.062643361, 0.066714279, 0.071049749, 0.075666962, 0.080584227, 0.085821044, 0.091398179, 0.097337747, 0.10366330, 0.11039993, 0.11757434, 0.12521498, 0.13335215, 0.14201813, 0.15124727, 0.16107617, 0.17154380, 0.18269168, 0.19456402, 0.20720788, 0.22067342, 0.23501402, 0.25028656, 0.26655159, 0.28387361, 0.30232132, 0.32196786, 0.34289114, 0.36517414, 0.38890521, 0.41417847, 0.44109412, 0.46975890, 0.50028648, 0.53279791, 0.56742212, 0.60429640, 0.64356699, 0.68538959, 0.72993007, 0.77736504, 0.82788260, 0.88168307, 0.9389798, 1.]; // modifiers: static, private static private function render_line(x0 : Int, x1 : Int, y0 : Int, y1 : Int, d : Vector) : Void { var dy : Int = y1 - y0; var adx : Int = x1 - x0; var ady : Int = System.abs(dy); var base : Int = Std.int(dy / adx); var sy : Int = (dy < 0 ? base - 1 : base + 1); var x : Int = x0; var y : Int = y0; var err : Int = 0; ady -= System.abs(base * adx); d[x] *= FLOOR_fromdB_LOOKUP[y]; while (++x < x1) { err = (err + ady); if (err >= adx) { err -= adx; y += sy; } else { y += base; }; d[x] *= FLOOR_fromdB_LOOKUP[y]; }; } // modifiers: static static function ilog(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret++; v >>>= 1; }; return ret; } // modifiers: static, private static private function ilog2(v : Int) : Int { var ret : Int = 0; while (v > 1) { ret++; v >>>= 1; }; return ret; } public function new() { } } class InfoFloor1 { /* * generated source for InfoFloor1 */ inline static var VIF_POSIT : Int = 63; inline static var VIF_CLASS : Int = 16; inline static var VIF_PARTS : Int = 31; public var partitions : Int; // discarded initializer: 'new int[VIF_PARTS]'; public var partitionclass : Vector; // discarded initializer: 'new int[VIF_CLASS]'; public var class_dim : Vector; // discarded initializer: 'new int[VIF_CLASS]'; public var class_subs : Vector; // discarded initializer: 'new int[VIF_CLASS]'; public var class_book : Vector; // discarded initializer: 'new int[VIF_CLASS]'; public var class_subbook : Array>; public var mult : Int; // discarded initializer: 'new int[VIF_POSIT + 2]'; public var postlist : Vector; var maxover : Float; var maxunder : Float; var maxerr : Float; var twofitminsize : Int; var twofitminused : Int; var twofitweight : Int; var twofitatten : Float; var unusedminsize : Int; var unusedmin_n : Int; var n : Int; // modifiers: public function new() { partitionclass = new Vector(VIF_PARTS, true); class_dim = new Vector(VIF_CLASS, true); class_subs = new Vector(VIF_CLASS, true); class_book = new Vector(VIF_CLASS, true); class_subbook = new Array(); postlist = new Vector(VIF_POSIT + 2, true); // for-while; var i : Int = 0; //while (i < class_subbook.length) { while (i < VIF_CLASS) { //class_subbook[i] = new int[8]; class_subbook[i] = new Vector(8, true); i++; }; } // modifiers: public function free() : Void { partitionclass = null; class_dim = null; class_subs = null; class_book = null; class_subbook = null; postlist = null; } // modifiers: function copy_info() : Dynamic { var info : InfoFloor1 = this; var ret : InfoFloor1 = new InfoFloor1(); ret.partitions = info.partitions; // System.arraycopyV(info.partitionclass, 0, ret.partitionclass, 0, InfoFloor1.VIF_PARTS); // System.arraycopyV(info.class_dim, 0, ret.class_dim, 0, InfoFloor1.VIF_CLASS); // System.arraycopyV(info.class_subs, 0, ret.class_subs, 0, InfoFloor1.VIF_CLASS); // System.arraycopyV(info.class_book, 0, ret.class_book, 0, InfoFloor1.VIF_CLASS); ret.partitionclass = VectorTools.copyI(info.partitionclass, 0, ret.partitionclass, 0, VIF_PARTS); ret.class_dim = VectorTools.copyI(info.class_dim, 0, ret.class_dim, 0, VIF_CLASS); ret.class_subs = VectorTools.copyI(info.class_subs, 0, ret.class_subs, 0, VIF_CLASS); ret.class_book = VectorTools.copyI(info.class_book, 0, ret.class_book, 0, VIF_CLASS); // for-while; var j : Int = 0; while (j < VIF_CLASS) { //System.arraycopyV(info.class_subbook[j], 0, ret.class_subbook[j], 0, 8); ret.class_subbook[j] = VectorTools.copyI(info.class_subbook[j], 0, ret.class_subbook[j], 0, 8); j++; }; ret.mult = info.mult; //System.arraycopyV(info.postlist, 0, ret.postlist, 0, InfoFloor1.VIF_POSIT + 2); ret.postlist = VectorTools.copyI(info.postlist, 0, ret.postlist, 0, VIF_POSIT + 2); ret.maxover = info.maxover; ret.maxunder = info.maxunder; ret.maxerr = info.maxerr; ret.twofitminsize = info.twofitminsize; ret.twofitminused = info.twofitminused; ret.twofitweight = info.twofitweight; ret.twofitatten = info.twofitatten; ret.unusedminsize = info.unusedminsize; ret.unusedmin_n = info.unusedmin_n; ret.n = info.n; return ret; } } class LookFloor1 { /* * generated source for LookFloor1 */ inline static var VIF_POSIT : Int = 63; // discarded initializer: 'new int[VIF_POSIT + 2]'; public var sorted_index : Vector; // discarded initializer: 'new int[VIF_POSIT + 2]'; public var forward_index : Vector; // discarded initializer: 'new int[VIF_POSIT + 2]'; public var reverse_index : Vector; // discarded initializer: 'new int[VIF_POSIT]'; public var hineighbor : Vector; // discarded initializer: 'new int[VIF_POSIT]'; public var loneighbor : Vector; public var posts : Int; public var n : Int; public var quant_q : Int; public var vi : InfoFloor1; public var phrasebits : Int; public var postbits : Int; public var frames : Int; public function new() { sorted_index = new Vector(VIF_POSIT + 2, true); forward_index = new Vector(VIF_POSIT + 2, true); reverse_index = new Vector(VIF_POSIT + 2, true); hineighbor = new Vector(VIF_POSIT, true); loneighbor = new Vector(VIF_POSIT, true); } // modifiers: function free() : Void { sorted_index = null; forward_index = null; reverse_index = null; hineighbor = null; loneighbor = null; } } class Lsfit_acc { /* * generated source for Lsfit_acc */ var x0 : Int; var x1 : Int; var xa : Int; var ya : Int; var x2a : Int; var y2a : Int; var xya : Int; var n : Int; var an : Int; var un : Int; var edgey0 : Int; var edgey1 : Int; } class EchstateFloor1 { /* * generated source for EchstateFloor1 */ var codewords : Vector; var curve : Vector; var frameno : Int; var codes : Int; } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/FuncFloor.hx000066400000000000000000000043261454362722700300070ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class FuncFloor { /* * generated source for FuncFloor */ //static public var floor_P : Array = [Floor0(), Floor1()]; //static public var floor_P : Vector = null; static public var floor_P : Array = null; // modifiers: abstract public function pack(i : Dynamic, opb : Buffer) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract public function unpack(vi : Info, opb : Buffer) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function look(vd : DspState, mi : InfoMode, i : Dynamic) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function free_info(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function free_look(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function free_state(vs : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function forward(vb : Block, i : Dynamic, in_ : Vector, out : Vector, vs : Dynamic) : Int { throw "UnimplementedAbstractMethod"; return 0; } // modifiers: abstract public function inverse1(vb : Block, i : Dynamic, memo : Dynamic) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function inverse2(vb : Block, i : Dynamic, memo : Dynamic, out : Vector) : Int { throw "UnimplementedAbstractMethod"; return 0; } private static function __static_init__() : Void { //floor_P = new Vector(2, true); floor_P = ArrayTools.alloc(2); floor_P[0] = new Floor0(); floor_P[1] = new Floor1(); } public static function _s_init() : Void { if (floor_P == null) { __static_init__(); } } /* private static function __init__() : Void { //__static_init__(); } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/FuncMapping.hx000066400000000000000000000031721454362722700303170ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class FuncMapping { /* * generated source for FuncMapping */ //static public var mapping_P : Vector = [Mapping0()]; static public var mapping_P : Array = null; // modifiers: abstract public function pack(info : Info, imap : Dynamic, buffer : Buffer) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract public function unpack(info : Info, buffer : Buffer) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function look(vd : DspState, vm : InfoMode, m : Dynamic) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function free_info(imap : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function free_look(imap : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract public function inverse(vd : Block, lm : Dynamic) : Int { throw "UnimplementedAbstractMethod"; return 0; } private static function __static_init__() : Void { //mapping_P = new Vector(1, true); mapping_P = ArrayTools.alloc(1); mapping_P[0] = new Mapping0(); } public static function _s_init() : Void { if (mapping_P == null) { __static_init__(); } } /* private static function __init__() : Void { //__static_init__(); } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/FuncResidue.hx000066400000000000000000000036771454362722700303360ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class FuncResidue { /* * generated source for FuncResidue */ //static public var residue_P : Array = [Residue0(), Residue1(), Residue2()]; static public var residue_P : Array = null; // modifiers: abstract public function pack(vr : Dynamic, opb : Buffer) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract public function unpack(vi : Info, opb : Buffer) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function look(vd : DspState, vm : InfoMode, vr : Dynamic) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function free_info(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function free_look(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function forward(vb : Block, vl : Dynamic, in_ : Array>, ch : Int) : Int { throw "UnimplementedAbstractMethod"; return 0; } // modifiers: abstract public function inverse(vb : Block, vl : Dynamic, in_ : Array>, nonzero : Vector, ch : Int) : Int { throw "UnimplementedAbstractMethod"; return 0; } private static function __static_init__() : Void { //residue_P = new Vector(3, true); residue_P = ArrayTools.alloc(3); residue_P[0] = new Residue0(); residue_P[1] = new Residue1(); residue_P[2] = new Residue2(); } public static function _s_init() : Void { if (residue_P == null) { __static_init__(); } } /* private static function __init__() : Void { //__static_init__(); } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/FuncTime.hx000066400000000000000000000033621454362722700276230ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class FuncTime { /* * generated source for FuncTime */ //static public var time_P : Vector = [Time0()]; static public var time_P : Array = null; // modifiers: abstract public function pack(i : Dynamic, opb : Buffer) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract public function unpack(vi : Info, opb : Buffer) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function look(vd : DspState, vm : InfoMode, i : Dynamic) : Dynamic { throw "UnimplementedAbstractMethod"; return null; } // modifiers: abstract public function free_info(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function free_look(i : Dynamic) : Void { throw "UnimplementedAbstractMethod"; } // modifiers: abstract function forward(vb : Block, i : Dynamic) : Int { throw "UnimplementedAbstractMethod"; return 0; } // modifiers: abstract function inverse(vb : Block, i : Dynamic, in_ : Vector, out : Vector) : Int { throw "UnimplementedAbstractMethod"; return 0; } private static function __static_init__() : Void { //time_P = new Vector(1, true); time_P = ArrayTools.alloc(1); time_P[0] = new Time0(); } public static function _s_init() : Void { if (time_P == null) { __static_init__(); } } /* private static function __init__() : Void { //__static_init__(); } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Info.hx000066400000000000000000000344421454362722700270070ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; import org.xiph.fogg.Packet; class Info { /* * generated source for Info */ inline static private var OV_EBADPACKET : Int = -136; inline static private var OV_ENOTAUDIO : Int = -135; static private var _vorbis : Bytes = System.fromString("vorbis"); inline static private var VI_TIMEB : Int = 1; inline static private var VI_FLOORB : Int = 2; inline static private var VI_RESB : Int = 3; inline static private var VI_MAPB : Int = 1; inline static private var VI_WINDOWB : Int = 1; public var version : Int; public var channels : Int; public var rate : Int; var bitrate_upper : Int; var bitrate_nominal : Int; var bitrate_lower : Int; // discarded initializer: 'new int[2]'; public var blocksizes : Vector; public var modes : Int; var maps : Int; public var times : Int; public var floors : Int; public var residues : Int; public var books : Int; public var psys : Int; // discarded initializer: 'null'; public var mode_param : Array; // discarded initializer: 'null'; public var map_type : Vector; // discarded initializer: 'null'; public var map_param : Array; // discarded initializer: 'null'; public var time_type : Vector; // discarded initializer: 'null'; public var time_param : Array; // discarded initializer: 'null'; public var floor_type : Vector; // discarded initializer: 'null'; public var floor_param : Array; // discarded initializer: 'null'; public var residue_type : Vector; // discarded initializer: 'null'; public var residue_param : Array; // discarded initializer: 'null'; public var book_param : Array; // discarded initializer: 'new PsyInfo[64]'; // psy_param : Vector; var envelopesa : Int; var preecho_thresh : Float; var preecho_clamp : Float; // modifiers: public public function init() : Void { rate = 0; } // modifiers: public public function clear() : Void { // for-while; var i : Int = 0; while (i < modes) { mode_param[i] = null; i++; }; mode_param = null; // for-while; var i : Int = 0; while (i < maps) { FuncMapping.mapping_P[map_type[i]].free_info(map_param[i]); i++; }; map_param = null; // for-while; var i : Int = 0; while (i < times) { FuncTime.time_P[time_type[i]].free_info(time_param[i]); i++; }; time_param = null; // for-while; var i : Int = 0; while (i < floors) { FuncFloor.floor_P[floor_type[i]].free_info(floor_param[i]); i++; }; floor_param = null; // for-while; var i : Int = 0; while (i < residues) { FuncResidue.residue_P[residue_type[i]].free_info(residue_param[i]); i++; }; residue_param = null; // for-while; var i : Int = 0; while (i < books) { if (book_param[i] != null) { book_param[i].clear(); book_param[i] = null; }; i++; }; book_param = null; /* // for-while; var i : Int = 0; while (i < psys) { psy_param[i].free(); i++; }; */ } // modifiers: function unpack_info(opb : Buffer) : Int { version = opb.read(32); if (version != 0) { return -1; }; channels = opb.read(8); rate = opb.read(32); bitrate_upper = opb.read(32); bitrate_nominal = opb.read(32); bitrate_lower = opb.read(32); blocksizes[0] = (1 << opb.read(4)); blocksizes[1] = (1 << opb.read(4)); if (((((rate < 1) || (channels < 1)) || (blocksizes[0] < 8)) || (blocksizes[1] < blocksizes[0])) || (opb.read(1) != 1)) { clear(); return -1; }; return 0; } // modifiers: function unpack_books(opb : Buffer) : Int { books = (opb.read(8) + 1); if ((book_param == null) || (book_param.length != books)) { //book_param = new StaticCodeBook[books]; //book_param = new Vector(books, true); book_param = ArrayTools.alloc(books); }; // for-while; var i : Int = 0; while (i < books) { book_param[i] = new StaticCodeBook(); if (book_param[i].unpack(opb) != 0) { clear(); return -1; }; i++; }; times = (opb.read(6) + 1); if ((time_type == null) || (time_type.length != times)) { //time_type = new int[times]; time_type = new Vector(times, true); }; if ((time_param == null) || (time_param.length != times)) { //time_param = new Object[times]; //time_param = new Vector(times, true); time_param = ArrayTools.alloc(times); }; // for-while; var i : Int = 0; while (i < times) { time_type[i] = opb.read(16); if ((time_type[i] < 0) || (time_type[i] >= Info.VI_TIMEB)) { clear(); return -1; }; time_param[i] = FuncTime.time_P[time_type[i]].unpack(this, opb); if (time_param[i] == null) { clear(); return -1; }; i++; }; floors = (opb.read(6) + 1); if ((floor_type == null) || (floor_type.length != floors)) { //floor_type = new int[floors]; floor_type = new Vector(floors, true); }; if ((floor_param == null) || (floor_param.length != floors)) { //floor_param = new Object[floors]; //floor_param = new Vector(floors, true); floor_param = ArrayTools.alloc(floors, true); }; // for-while; var i : Int = 0; while (i < floors) { floor_type[i] = opb.read(16); if ((floor_type[i] < 0) || (floor_type[i] >= Info.VI_FLOORB)) { clear(); return -1; }; floor_param[i] = FuncFloor.floor_P[floor_type[i]].unpack(this, opb); if (floor_param[i] == null) { clear(); return -1; }; i++; }; residues = (opb.read(6) + 1); if ((residue_type == null) || (residue_type.length != residues)) { //residue_type = new int[residues]; residue_type = new Vector(residues, true); }; if ((residue_param == null) || (residue_param.length != residues)) { //residue_param = new Object[residues]; //residue_param = new Vector(residues, true); residue_param = ArrayTools.alloc(residues); }; // for-while; var i : Int = 0; while (i < residues) { residue_type[i] = opb.read(16); if ((residue_type[i] < 0) || (residue_type[i] >= Info.VI_RESB)) { clear(); return -1; }; residue_param[i] = FuncResidue.residue_P[residue_type[i]].unpack(this, opb); if (residue_param[i] == null) { clear(); return -1; }; i++; }; maps = (opb.read(6) + 1); if ((map_type == null) || (map_type.length != maps)) { //map_type = new int[maps]; map_type = new Vector(maps, true); }; if ((map_param == null) || (map_param.length != maps)) { //map_param = new Object[maps]; //map_param = new Vector(maps, true); map_param = ArrayTools.alloc(maps); }; // for-while; var i : Int = 0; while (i < maps) { map_type[i] = opb.read(16); if ((map_type[i] < 0) || (map_type[i] >= Info.VI_MAPB)) { clear(); return -1; }; map_param[i] = FuncMapping.mapping_P[map_type[i]].unpack(this, opb); if (map_param[i] == null) { clear(); return -1; }; i++; }; modes = (opb.read(6) + 1); if ((mode_param == null) || (mode_param.length != modes)) { //mode_param = new InfoMode[modes]; //mode_param = new Vector(modes, true); mode_param = ArrayTools.alloc(modes); }; // for-while; var i : Int = 0; while (i < modes) { mode_param[i] = new InfoMode(); mode_param[i].blockflag = opb.read(1); mode_param[i].windowtype = opb.read(16); mode_param[i].transformtype = opb.read(16); mode_param[i].mapping = opb.read(8); if (((mode_param[i].windowtype >= Info.VI_WINDOWB) || (mode_param[i].transformtype >= Info.VI_WINDOWB)) || (mode_param[i].mapping >= maps)) { clear(); return -1; }; i++; }; if (opb.read(1) != 1) { clear(); return -1; }; return 0; } // modifiers: public public function synthesis_headerin(vc : Comment, op : Packet) : Int { var opb : Buffer = new Buffer(); if (op != null) { opb.readinit(op.packet_base, op.packet, op.bytes); var buffer : Bytes = System.alloc(6); var packtype : Int = opb.read(8); opb.readBytes(buffer, 6); /* if (buffer[0] != 'v' || buffer[1] != 'o' || buffer[2] != 'r' || buffer[3] != 'b' || buffer[4] != 'i' || buffer[5] != 's') { return -1; }; */ if (buffer.toString() != "vorbis") { return -1; }; switch (packtype) { case 0x01: if (op.b_o_s == 0) { return -1; }; if (rate != 0) { return -1; }; return unpack_info(opb); case 0x03: if (rate == 0) { return -1; }; return vc.unpack(opb); case 0x05: if ((rate == 0) || (vc.vendor == null)) { return -1; }; return unpack_books(opb); default: }; }; return -1; } // modifiers: function pack_info(opb : Buffer) : Int { opb.write(0x01, 8); opb.writeBytes(Info._vorbis); opb.write(0x00, 32); opb.write(channels, 8); opb.write(rate, 32); opb.write(bitrate_upper, 32); opb.write(bitrate_nominal, 32); opb.write(bitrate_lower, 32); opb.write(Info.ilog2(blocksizes[0]), 4); opb.write(Info.ilog2(blocksizes[1]), 4); opb.write(1, 1); return 0; } // modifiers: function pack_books(opb : Buffer) : Int { opb.write(0x05, 8); opb.writeBytes(Info._vorbis); opb.write(books - 1, 8); // for-while; var i : Int = 0; while (i < books) { if (book_param[i].pack(opb) != 0) { return -1; }; i++; }; opb.write(times - 1, 6); // for-while; var i : Int = 0; while (i < times) { opb.write(time_type[i], 16); FuncTime.time_P[time_type[i]].pack(this.time_param[i], opb); i++; }; opb.write(floors - 1, 6); // for-while; var i : Int = 0; while (i < floors) { opb.write(floor_type[i], 16); FuncFloor.floor_P[floor_type[i]].pack(floor_param[i], opb); i++; }; opb.write(residues - 1, 6); // for-while; var i : Int = 0; while (i < residues) { opb.write(residue_type[i], 16); FuncResidue.residue_P[residue_type[i]].pack(residue_param[i], opb); i++; }; opb.write(maps - 1, 6); // for-while; var i : Int = 0; while (i < maps) { opb.write(map_type[i], 16); FuncMapping.mapping_P[map_type[i]].pack(this, map_param[i], opb); i++; }; opb.write(modes - 1, 6); // for-while; var i : Int = 0; while (i < modes) { opb.write(mode_param[i].blockflag, 1); opb.write(mode_param[i].windowtype, 16); opb.write(mode_param[i].transformtype, 16); opb.write(mode_param[i].mapping, 8); i++; }; opb.write(1, 1); return 0; } // modifiers: public public function blocksize(op : Packet) : Int { var opb : Buffer = new Buffer(); var mode : Int; opb.readinit(op.packet_base, op.packet, op.bytes); if (opb.read(1) != 0) { return Info.OV_ENOTAUDIO; }; var modebits : Int = 0; var v : Int = modes; while (v > 1) { modebits++; v >>>= 1; }; mode = opb.read(modebits); if (mode == -1) { return Info.OV_EBADPACKET; }; return blocksizes[mode_param[mode].blockflag]; } // modifiers: static, private static private function ilog2(v : Int) : Int { var ret : Int = 0; while (v > 1) { ret++; v >>>= 1; }; return ret; } // modifiers: public public function toString() : String { return "version:" + version + ", channels:" + channels + ", rate:" + rate + ", bitrate:" + bitrate_upper + "," + bitrate_nominal + "," + bitrate_lower; } public function new() { // collected discarded initializers: blocksizes = new Vector(2, true); mode_param = null; map_type = null; map_param = null; time_type = null; time_param = null; floor_type = null; floor_param = null; residue_type = null; residue_param = null; book_param = null; //psy_param = new Vector(64, true); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/InfoMode.hx000066400000000000000000000006351454362722700276110ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; class InfoMode { /* * generated source for InfoMode */ public var blockflag : Int; public var windowtype : Int; public var transformtype : Int; public var mapping : Int; public function new() { /* blockflag = 0; windowtype = 0; transformtype = 0; mapping = 0; */ } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/JOrbisException.hx000066400000000000000000000012351454362722700311550ustar00rootroot00000000000000//#!/usr/bin/env python //# -*- coding: utf-8 -*- package org.xiph.fvorbis; import org.xiph.system.Bytes; class JOrbisException extends Exception { /* * generated source for JOrbisException */ // modifiers: public public function __new_0() { super(); if { }; } // modifiers: public public function __new_1(s : String) { super("JOrbis: " + s); if { }; } // modifiers: inline, public inline public function new() { // FIXME: implement disambiguation handler; // __new_0(); // __new_1(s : String); throw "NotImplementedError"; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Lookup.hx000066400000000000000000000146301454362722700273620ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; class Lookup { /* * generated source for Lookup */ inline static var COS_LOOKUP_SZ : Int = 128; inline static function COS_LOOKUP() : Array{ return [1.0000000000000, 0.9996988186962, 0.9987954562052, 0.9972904566787, 0.9951847266722, 0.9924795345987, 0.9891765099648, 0.9852776423889, 0.9807852804032, 0.9757021300385, 0.9700312531945, 0.9637760657954, 0.9569403357322, 0.9495281805930, 0.9415440651830, 0.9329927988347, 0.9238795325113, 0.9142097557035, 0.9039892931234, 0.8932243011955, 0.8819212643484, 0.8700869911087, 0.8577286100003, 0.8448535652497, 0.8314696123025, 0.8175848131516, 0.8032075314806, 0.7883464276266, 0.7730104533627, 0.7572088465065, 0.7409511253550, 0.7242470829515, 0.7071067811865, 0.6895405447371, 0.6715589548470, 0.6531728429538, 0.6343932841636, 0.6152315905806, 0.5956993044924, 0.5758081914178, 0.5555702330196, 0.5349976198871, 0.5141027441932, 0.4928981922298, 0.4713967368260, 0.4496113296546, 0.4275550934303, 0.4052413140050, 0.3826834323651, 0.3598950365350, 0.3368898533922, 0.3136817403989, 0.2902846772545, 0.2667127574749, 0.2429801799033, 0.2191012401569, 0.1950903220161, 0.1709618887603, 0.1467304744554, 0.1224106751992, 0.0980171403296, 0.0735645635997, 0.0490676743274, 0.0245412285229, 0.0000000000000, -0.0245412285229, -0.0490676743274, -0.0735645635997, -0.0980171403296, -0.1224106751992, -0.1467304744554, -0.1709618887603, -0.1950903220161, -0.2191012401569, -0.2429801799033, -0.2667127574749, -0.2902846772545, -0.3136817403989, -0.3368898533922, -0.3598950365350, -0.3826834323651, -0.4052413140050, -0.4275550934303, -0.4496113296546, -0.4713967368260, -0.4928981922298, -0.5141027441932, -0.5349976198871, -0.5555702330196, -0.5758081914178, -0.5956993044924, -0.6152315905806, -0.6343932841636, -0.6531728429538, -0.6715589548470, -0.6895405447371, -0.7071067811865, -0.7242470829515, -0.7409511253550, -0.7572088465065, -0.7730104533627, -0.7883464276266, -0.8032075314806, -0.8175848131516, -0.8314696123025, -0.8448535652497, -0.8577286100003, -0.8700869911087, -0.8819212643484, -0.8932243011955, -0.9039892931234, -0.9142097557035, -0.9238795325113, -0.9329927988347, -0.9415440651830, -0.9495281805930, -0.9569403357322, -0.9637760657954, -0.9700312531945, -0.9757021300385, -0.9807852804032, -0.9852776423889, -0.9891765099648, -0.9924795345987, -0.9951847266722, -0.9972904566787, -0.9987954562052, -0.9996988186962, -1.0000000000000]; } // modifiers: static static public function coslook(a : Float) : Float { var d : Float = a * (0.31830989 * Lookup.COS_LOOKUP_SZ); var i : Int = Std.int(d); return Lookup.COS_LOOKUP()[i] + (d - i * (Lookup.COS_LOOKUP()[i + 1] - Lookup.COS_LOOKUP()[i])); } inline static var INVSQ_LOOKUP_SZ : Int = 32; inline static function INVSQ_LOOKUP() : Array{ return [1.414213562373, 1.392621247646, 1.371988681140, 1.352246807566, 1.333333333333, 1.315191898443, 1.297771369046, 1.281025230441, 1.264911064067, 1.249390095109, 1.234426799697, 1.219988562661, 1.206045378311, 1.192569588000, 1.179535649239, 1.166919931983, 1.154700538379, 1.142857142857, 1.131370849898, 1.120224067222, 1.109400392450, 1.098884511590, 1.088662107904, 1.078719779941, 1.069044967650, 1.059625885652, 1.050451462878, 1.041511287847, 1.032795558989, 1.024295039463, 1.016001016002, 1.007905261358, 1.000000000000]; } // modifiers: static static public function invsqlook(a : Float) : Float { var d : Float = (a * (2. * Lookup.INVSQ_LOOKUP_SZ)) - Lookup.INVSQ_LOOKUP_SZ; var i : Int = Std.int(d); return Lookup.INVSQ_LOOKUP()[i] + (d - i * (Lookup.INVSQ_LOOKUP()[i + 1] - Lookup.INVSQ_LOOKUP()[i])); } inline static var INVSQ2EXP_LOOKUP_MIN : Int = -32; inline static var INVSQ2EXP_LOOKUP_MAX : Int = 32; inline static function INVSQ2EXP_LOOKUP() : Array { return [65536., 46340.95001, 32768., 23170.47501, 16384., 11585.2375, 8192., 5792.618751, 4096., 2896.309376, 2048., 1448.154688, 1024., 724.0773439, 512., 362.038672, 256., 181.019336, 128., 90.50966799, 64., 45.254834, 32., 22.627417, 16., 11.3137085, 8., 5.656854249, 4., 2.828427125, 2., 1.414213562, 1., 0.7071067812, 0.5, 0.3535533906, 0.25, 0.1767766953, 0.125, 0.08838834765, 0.0625, 0.04419417382, 0.03125, 0.02209708691, 0.015625, 0.01104854346, 0.0078125, 0.005524271728, 0.00390625, 0.002762135864, 0.001953125, 0.001381067932, 0.0009765625, 0.000690533966, 0.00048828125, 0.000345266983, 0.000244140625, 0.0001726334915, 0.0001220703125, 8.631674575e-05, 6.103515625e-05, 4.315837288e-05, 3.051757812e-05, 2.157918644e-05, 1.525878906e-05];} // modifiers: static static public function invsq2explook(a : Int) : Float { return Lookup.INVSQ2EXP_LOOKUP()[a - Lookup.INVSQ2EXP_LOOKUP_MIN]; } inline static var FROMdB_LOOKUP_SZ : Int = 35; inline static var FROMdB2_LOOKUP_SZ : Int = 32; inline static var FROMdB_SHIFT : Int = 5; inline static var FROMdB2_SHIFT : Int = 3; inline static var FROMdB2_MASK : Int = 31; inline static function FROMdB_LOOKUP() : Array { return [1., 0.6309573445, 0.3981071706, 0.2511886432, 0.1584893192, 0.1, 0.06309573445, 0.03981071706, 0.02511886432, 0.01584893192, 0.01, 0.006309573445, 0.003981071706, 0.002511886432, 0.001584893192, 0.001, 0.0006309573445, 0.0003981071706, 0.0002511886432, 0.0001584893192, 0.0001, 6.309573445e-05, 3.981071706e-05, 2.511886432e-05, 1.584893192e-05, 1e-05, 6.309573445e-06, 3.981071706e-06, 2.511886432e-06, 1.584893192e-06, 1e-06, 6.309573445e-07, 3.981071706e-07, 2.511886432e-07, 1.584893192e-07];} inline static function FROMdB2_LOOKUP() : Array { return [0.9928302478, 0.9786445908, 0.9646616199, 0.9508784391, 0.9372921937, 0.92390007, 0.9106992942, 0.8976871324, 0.8848608897, 0.8722179097, 0.8597555737, 0.8474713009, 0.835362547, 0.8234268041, 0.8116616003, 0.8000644989, 0.7886330981, 0.7773650302, 0.7662579617, 0.755309592, 0.7445176537, 0.7338799116, 0.7233941627, 0.7130582353, 0.7028699885, 0.6928273125, 0.6829281272, 0.6731703824, 0.6635520573, 0.6540711597, 0.6447257262, 0.6355138211];} // modifiers: static static public function fromdBlook(a : Float) : Float { var i : Int = Std.int(a * -(1 << Lookup.FROMdB2_SHIFT)); return (i < 0 ? 1. : (i >= (Lookup.FROMdB_LOOKUP_SZ << Lookup.FROMdB_SHIFT) ? 0. : Lookup.FROMdB_LOOKUP()[i >>> Lookup.FROMdB_SHIFT] * Lookup.FROMdB2_LOOKUP()[i & Lookup.FROMdB2_MASK])); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Lpc.hx000066400000000000000000000077751454362722700266430ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Lpc { /* * generated source for Lpc */ // discarded initializer: 'Drft()'; var fft : Drft; var ln : Int; var m : Int; // modifiers: static static function lpc_from_data(data : Vector, lpc : Vector, n : Int, m : Int) : Float { //var aut : Vector = new float[m + 1]; var aut : Vector = new Vector(m + 1, true); var error : Float; var i : Int; var j : Int; j = (m + 1); while (j-- != 0) { var d : Float = 0; // for-while; i = j; while (i < n) { d += (data[i] * data[i - j]); i++; }; aut[j] = d; }; error = aut[0]; // for-while; i = 0; while (i < m) { var r : Float = -aut[i + 1]; if (error == 0) { // for-while; var k : Int = 0; while (k < m) { lpc[k] = 0.0; k++; }; return 0; }; // for-while; j = 0; while (j < i) { r -= (lpc[j] * aut[i - j]); j++; }; r /= error; lpc[i] = r; // for-while; j = 0; while (j < (i / 2)) { var tmp : Float = lpc[j]; lpc[j] += (r * lpc[(i - 1) - j]); lpc[(i - 1) - j] += (r * tmp); j++; }; if ((i % 2) != 0) { lpc[j] += (lpc[j] * r); }; error *= (1.0 - (r * r)); i++; }; return error; } // modifiers: function lpc_from_curve(curve : Vector, lpc : Vector) : Float { var n : Int = ln; //var work : Vector = new float[n + n]; var work : Vector = new Vector(n + n, true); var fscale : Float = 0.5 / n; var i : Int; var j : Int; // for-while; i = 0; while (i < n) { work[i * 2] = (curve[i] * fscale); work[(i * 2) + 1] = 0; i++; }; work[(n * 2) - 1] = (curve[n - 1] * fscale); n *= 2; fft.backward(work); // for-while; i = 0; j = Std.int(n / 2); while (i < (n / 2)) { var temp : Float = work[i]; work[i++] = work[j]; work[j++] = temp; }; return Lpc.lpc_from_data(work, lpc, n, m); } // modifiers: public function init(mapped : Int, m : Int) : Void { ln = mapped; this.m = m; fft.init(mapped * 2); } // modifiers: function clear() : Void { fft.clear(); } // modifiers: static static function FAST_HYPOT(a : Float, b : Float) : Float { return Math.sqrt((a * a) + (b * b)); } // modifiers: public function lpc_to_curve(curve : Vector, lpc : Vector, amp : Float) : Void { // for-while; var i : Int = 0; while (i < (ln * 2)) { curve[i] = 0.0; i++; }; if (amp == 0) { return; }; // for-while; var i : Int = 0; while (i < m) { curve[(i * 2) + 1] = (lpc[i] / (4 * amp)); curve[(i * 2) + 2] = (-lpc[i] / (4 * amp)); i++; }; fft.backward(curve); var l2 : Int = ln * 2; var unit : Float = 1. / amp; curve[0] = 1. / ((curve[0] * 2) + unit); // for-while; var i : Int = 1; while (i < ln) { var real : Float = curve[i] + curve[l2 - i]; var imag : Float = curve[i] - curve[l2 - i]; var a : Float = real + unit; curve[i] = 1.0 / Lpc.FAST_HYPOT(a, imag); i++; }; } public function new() { fft = new Drft(); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Lsp.hx000066400000000000000000000045141454362722700266470ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Lsp { /* * generated source for Lsp */ inline static var M_PI : Float = 3.1415926539; // modifiers: static static public function lsp_to_curve(curve : Vector, map : Vector, n : Int, ln : Int, lsp : Vector, m : Int, amp : Float, ampoffset : Float) : Void { var i : Int; var wdel : Float = Lsp.M_PI / ln; // for-while; i = 0; while (i < m) { lsp[i] = Lookup.coslook(lsp[i]); i++; }; var m2 : Int = Std.int(m / 2) * 2; i = 0; while (i < n) { var k : Int = map[i]; var p : Float = 0.7071067812; var q : Float = 0.7071067812; var w : Float = Lookup.coslook(wdel * k); var ftmp : Int = 0; var c : Int = m >>> 1; // for-while; var j : Int = 0; while (j < m2) { q *= (lsp[j] - w); p *= (lsp[j + 1] - w); j += 2; }; if ((m & 1) != 0) { q *= (lsp[m - 1] - w); q *= q; p *= (p * (1. - (w * w))); } else { q *= (q * (1. + w)); p *= (p * (1. - w)); }; q = (p + q); var hx : Int = System.floatToIntBits(q); var ix : Int = 0x7fffffff & hx; var qexp : Int = 0; if ((ix >= 0x7f800000) || (ix == 0)) { } else { if (ix < 0x00800000) { q *= 3.3554432000e+07; hx = System.floatToIntBits(q); ix = (0x7fffffff & hx); qexp = -25; }; qexp += ((ix >>> 23) - 126); hx = ((hx & 0x807fffff) | 0x3f000000); q = System.intBitsToFloat(hx); }; q = Lookup.fromdBlook(((amp * Lookup.invsqlook(q)) * Lookup.invsq2explook(qexp + m)) - ampoffset); while (true) { // HAXE200BUG // curve[i++] *= q; curve[i] *= q; i++; if (!((i < n) && (map[i] == k))) { break; }; }; }; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Mapping0.hx000066400000000000000000000315441454362722700275670ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class Mapping0 extends FuncMapping { /* * generated source for Mapping0 */ static var seq : Int = 0; // modifiers: override function free_info(imap : Dynamic) : Void { } // modifiers: override function free_look(imap : Dynamic) : Void { } // modifiers: override function look(vd : DspState, vm : InfoMode, m : Dynamic) : Dynamic { var vi : Info = vd.vi; var look : LookMapping0 = new LookMapping0(); var info : InfoMapping0 = look.map = m; look.mode = vm; // look.time_look = new Object[info.submaps]; // look.floor_look = new Object[info.submaps]; // look.residue_look = new Object[info.submaps]; // look.time_func = new FuncTime[info.submaps]; // look.floor_func = new FuncFloor[info.submaps]; // look.residue_func = new FuncResidue[info.submaps]; look.time_look = ArrayTools.alloc(info.submaps); look.floor_look = ArrayTools.alloc(info.submaps); look.residue_look = ArrayTools.alloc(info.submaps); look.time_func = ArrayTools.alloc(info.submaps); look.floor_func = ArrayTools.alloc(info.submaps); look.residue_func = ArrayTools.alloc(info.submaps); // for-while; var i : Int = 0; while (i < info.submaps) { var timenum : Int = info.timesubmap[i]; var floornum : Int = info.floorsubmap[i]; var resnum : Int = info.residuesubmap[i]; look.time_func[i] = FuncTime.time_P[vi.time_type[timenum]]; look.time_look[i] = look.time_func[i].look(vd, vm, vi.time_param[timenum]); look.floor_func[i] = FuncFloor.floor_P[vi.floor_type[floornum]]; look.floor_look[i] = look.floor_func[i].look(vd, vm, vi.floor_param[floornum]); look.residue_func[i] = FuncResidue.residue_P[vi.residue_type[resnum]]; look.residue_look[i] = look.residue_func[i].look(vd, vm, vi.residue_param[resnum]); i++; }; if ((vi.psys != 0) && (vd.analysisp != 0)) { }; look.ch = vi.channels; return look; } // modifiers: override function pack(vi : Info, imap : Dynamic, opb : Buffer) : Void { var info : InfoMapping0 = imap; if (info.submaps > 1) { opb.write(1, 1); opb.write(info.submaps - 1, 4); } else { opb.write(0, 1); }; if (info.coupling_steps > 0) { opb.write(1, 1); opb.write(info.coupling_steps - 1, 8); // for-while; var i : Int = 0; while (i < info.coupling_steps) { opb.write(info.coupling_mag[i], ilog2(vi.channels)); opb.write(info.coupling_ang[i], ilog2(vi.channels)); i++; }; } else { opb.write(0, 1); }; opb.write(0, 2); if (info.submaps > 1) { // for-while; var i : Int = 0; while (i < vi.channels) { opb.write(info.chmuxlist[i], 4); i++; }; }; // for-while; var i : Int = 0; while (i < info.submaps) { opb.write(info.timesubmap[i], 8); opb.write(info.floorsubmap[i], 8); opb.write(info.residuesubmap[i], 8); i++; }; } // modifiers: override function unpack(vi : Info, opb : Buffer) : Dynamic { var info : InfoMapping0 = new InfoMapping0(); if (opb.read(1) != 0) { info.submaps = (opb.read(4) + 1); } else { info.submaps = 1; }; if (opb.read(1) != 0) { info.coupling_steps = (opb.read(8) + 1); // for-while; var i : Int = 0; while (i < info.coupling_steps) { var testM : Int = info.coupling_mag[i] = opb.read(ilog2(vi.channels)); var testA : Int = info.coupling_ang[i] = opb.read(ilog2(vi.channels)); if (((((testM < 0) || (testA < 0)) || (testM == testA)) || (testM >= vi.channels)) || (testA >= vi.channels)) { info.free(); return null; }; i++; }; }; if (opb.read(2) > 0) { info.free(); return null; }; if (info.submaps > 1) { // for-while; var i : Int = 0; while (i < vi.channels) { info.chmuxlist[i] = opb.read(4); if (info.chmuxlist[i] >= info.submaps) { info.free(); return null; }; i++; }; }; // for-while; var i : Int = 0; while (i < info.submaps) { info.timesubmap[i] = opb.read(8); if (info.timesubmap[i] >= vi.times) { info.free(); return null; }; info.floorsubmap[i] = opb.read(8); if (info.floorsubmap[i] >= vi.floors) { info.free(); return null; }; info.residuesubmap[i] = opb.read(8); if (info.residuesubmap[i] >= vi.residues) { info.free(); return null; }; i++; }; return info; } // discarded initializer: 'null'; var pcmbundle : Array>; // discarded initializer: 'null'; var zerobundle : Vector; // discarded initializer: 'null'; var nonzero : Vector; // discarded initializer: 'null'; var floormemo : Array; // modifiers: synchronized override function inverse(vb : Block, l : Dynamic) : Int { var vd : DspState = vb.vd; var vi : Info = vd.vi; var look : LookMapping0 = l; var info : InfoMapping0 = look.map; var mode : InfoMode = look.mode; var n : Int = vb.pcmend = vi.blocksizes[vb.W]; var window : Vector = vd.window[vb.W][vb.lW][vb.nW][mode.windowtype]; if ((pcmbundle == null) || (pcmbundle.length < vi.channels)) { // pcmbundle = new float[vi.channels]; // nonzero = new int[vi.channels]; // zerobundle = new int[vi.channels]; // floormemo = new Object[vi.channels]; ////pcmbundle = new Vector(vi.channels, true); pcmbundle = ArrayTools.alloc(vi.channels); nonzero = new Vector(vi.channels, true); zerobundle = new Vector(vi.channels, true); //floormemo = new Vector(vi.channels, true); floormemo = ArrayTools.alloc(vi.channels); }; // for-while; var i : Int = 0; while (i < vi.channels) { var pcm : Vector = vb.pcm[i]; var submap : Int = info.chmuxlist[i]; floormemo[i] = look.floor_func[submap].inverse1(vb, look.floor_look[submap], floormemo[i]); if (floormemo[i] != null) { nonzero[i] = 1; } else { nonzero[i] = 0; }; // for-while; var j : Int = 0; while (j < (n / 2)) { pcm[j] = 0; j++; }; i++; }; // for-while; var i : Int = 0; while (i < info.coupling_steps) { if ((nonzero[info.coupling_mag[i]] != 0) || (nonzero[info.coupling_ang[i]] != 0)) { nonzero[info.coupling_mag[i]] = 1; nonzero[info.coupling_ang[i]] = 1; }; i++; }; // for-while; var i : Int = 0; while (i < info.submaps) { var ch_in_bundle : Int = 0; // for-while; var j : Int = 0; while (j < vi.channels) { if (info.chmuxlist[j] == i) { if (nonzero[j] != 0) { zerobundle[ch_in_bundle] = 1; } else { zerobundle[ch_in_bundle] = 0; }; pcmbundle[ch_in_bundle++] = vb.pcm[j]; }; j++; }; look.residue_func[i].inverse(vb, look.residue_look[i], pcmbundle, zerobundle, ch_in_bundle); i++; }; // for-while; var i : Int = info.coupling_steps - 1; while (i >= 0) { var pcmM : Vector = vb.pcm[info.coupling_mag[i]]; var pcmA : Vector = vb.pcm[info.coupling_ang[i]]; // for-while; var j : Int = 0; while (j < (n / 2)) { var mag : Float = pcmM[j]; var ang : Float = pcmA[j]; if (mag > 0) { if (ang > 0) { pcmM[j] = mag; pcmA[j] = (mag - ang); } else { pcmA[j] = mag; pcmM[j] = (mag + ang); }; } else { if (ang > 0) { pcmM[j] = mag; pcmA[j] = (mag + ang); } else { pcmA[j] = mag; pcmM[j] = (mag - ang); }; }; j++; }; i--; }; // for-while; var i : Int = 0; while (i < vi.channels) { var pcm : Vector = vb.pcm[i]; var submap : Int = info.chmuxlist[i]; look.floor_func[submap].inverse2(vb, look.floor_look[submap], floormemo[i], pcm); i++; }; // for-while; var i : Int = 0; while (i < vi.channels) { var pcm : Vector = vb.pcm[i]; vd.transform[vb.W][0].backward(pcm, pcm); i++; }; // for-while; var i : Int = 0; while (i < vi.channels) { var pcm : Vector = vb.pcm[i]; if (nonzero[i] != 0) { // for-while; var j : Int = 0; while (j < n) { pcm[j] *= window[j]; j++; }; } else { // for-while; var j : Int = 0; while (j < n) { pcm[j] = 0.; j++; }; }; i++; }; return 0; } // modifiers: static, private static private function ilog2(v : Int) : Int { var ret : Int = 0; while (v > 1) { ret++; v >>>= 1; }; return ret; } public function new() { pcmbundle = null; zerobundle = null; nonzero = null; floormemo = null; } } class InfoMapping0 { /* * generated source for InfoMapping0 */ public var submaps : Int; // discarded initializer: 'new int[256]'; public var chmuxlist : Vector; // discarded initializer: 'new int[16]'; public var timesubmap : Vector; // discarded initializer: 'new int[16]'; public var floorsubmap : Vector; // discarded initializer: 'new int[16]'; public var residuesubmap : Vector; // discarded initializer: 'new int[16]'; public var psysubmap : Vector; public var coupling_steps : Int; // discarded initializer: 'new int[256]'; public var coupling_mag : Vector; // discarded initializer: 'new int[256]'; public var coupling_ang : Vector; public function new() { chmuxlist = new Vector(256, true); timesubmap = new Vector(16, true); floorsubmap = new Vector(16, true); residuesubmap = new Vector(16, true); psysubmap = new Vector(16, true); coupling_mag = new Vector(256, true); coupling_ang = new Vector(256, true); } // modifiers: public function free() : Void { chmuxlist = null; timesubmap = null; floorsubmap = null; residuesubmap = null; psysubmap = null; coupling_mag = null; coupling_ang = null; } } class LookMapping0 { /* * generated source for LookMapping0 */ public var mode : InfoMode; public var map : InfoMapping0; public var time_look : Array; public var floor_look : Array; public var floor_state : Array; public var residue_look : Array; public var psy_look : Array; public var time_func : Array; public var floor_func : Array; public var residue_func : Array; public var ch : Int; public var decay : Array>; public var lastframe : Int; public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Mdct.hx000066400000000000000000000176171454362722700270100ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Mdct { /* * generated source for Mdct */ inline static private var cPI3_8 : Float = 0.38268343236508977175; inline static private var cPI2_8 : Float = 0.70710678118654752441; inline static private var cPI1_8 : Float = 0.92387953251128675613; var n : Int; var log2n : Int; var trig : Vector; var bitrev : Vector; var scale : Float; // modifiers: function init(n : Int) : Void { // bitrev = new int[n / 4]; // trig = new float[n + (n / 4)]; bitrev = new Vector(Std.int(n / 4), true); trig = new Vector(n + Std.int(n / 4), true); var n2 : Int = n >>> 1; log2n = Math.round(Math.log(n) / Math.log(2)); this.n = n; var AE : Int = 0; var AO : Int = 1; var BE : Int = AE + Std.int(n / 2); var BO : Int = BE + 1; var CE : Int = BE + Std.int(n / 2); var CO : Int = CE + 1; // for-while; var i : Int = 0; while (i < (n / 4)) { trig[AE + (i * 2)] = Math.cos((Math.PI / n) * (4 * i)); trig[AO + (i * 2)] = -Math.sin((Math.PI / n) * (4 * i)); trig[BE + (i * 2)] = Math.cos((Math.PI / (2 * n)) * ((2 * i) + 1)); trig[BO + (i * 2)] = Math.sin((Math.PI / (2 * n)) * ((2 * i) + 1)); i++; }; // for-while; var i : Int = 0; while (i < (n / 8)) { trig[CE + (i * 2)] = Math.cos((Math.PI / n) * ((4 * i) + 2)); trig[CO + (i * 2)] = -Math.sin((Math.PI / n) * ((4 * i) + 2)); i++; }; var mask : Int = (1 << (log2n - 1)) - 1; var msb : Int = 1 << (log2n - 2); // for-while; var i : Int = 0; while (i < (n / 8)) { var acc : Int = 0; // for-while; var j : Int = 0; while ((msb >>> j) != 0) { if (((msb >>> j) & i) != 0) { acc |= (1 << j); }; j++; }; bitrev[i * 2] = (~acc & mask); bitrev[(i * 2) + 1] = acc; i++; }; scale = (4. / n); } // modifiers: function clear() : Void { } // modifiers: function forward(in_ : Vector, out : Vector) : Void { } // discarded initializer: 'new float[1024]'; var _x : Vector; // discarded initializer: 'new float[1024]'; var _w : Vector; // modifiers: synchronized function backward(in_ : Vector, out : Vector) : Void { if (_x.length < (n / 2)) { // _x = new float[n / 2]; _x = new Vector(Std.int(n / 2), true); }; if (_w.length < (n / 2)) { // _w = new float[n / 2]; _w = new Vector(Std.int(n / 2), true); }; var x : Vector = _x; var w : Vector = _w; var n2 : Int = n >>> 1; var n4 : Int = n >>> 2; var n8 : Int = n >>> 3; { var inO : Int = 1; var xO : Int = 0; var A : Int = n2; var i : Int; // for-while; i = 0; while (i < n8) { A -= 2; x[xO++] = ((-in_[inO + 2] * trig[A + 1]) - (in_[inO] * trig[A])); x[xO++] = ((in_[inO] * trig[A + 1]) - (in_[inO + 2] * trig[A])); inO += 4; i++; }; inO = (n2 - 4); // for-while; i = 0; while (i < n8) { A -= 2; x[xO++] = ((in_[inO] * trig[A + 1]) + (in_[inO + 2] * trig[A])); x[xO++] = ((in_[inO] * trig[A]) - (in_[inO + 2] * trig[A + 1])); inO -= 4; i++; }; } var xxx : Vector = mdct_kernel(x, w, n, n2, n4, n8); var xx : Int = 0; { var B : Int = n2; var o1 : Int = n4; var o2 : Int = o1 - 1; var o3 : Int = n4 + n2; var o4 : Int = o3 - 1; // for-while; var i : Int = 0; while (i < n4) { var temp1 : Float = ((xxx[xx] * trig[B + 1]) - (xxx[xx + 1] * trig[B])); var temp2 : Float = -((xxx[xx] * trig[B]) + (xxx[xx + 1] * trig[B + 1])); out[o1] = -temp1; out[o2] = temp1; out[o3] = temp2; out[o4] = temp2; o1++; o2--; o3++; o4--; xx += 2; B += 2; i++; }; } } // modifiers: private private function mdct_kernel(x : Vector, w : Vector, n : Int, n2 : Int, n4 : Int, n8 : Int) : Vector { var xA : Int = n4; var xB : Int = 0; var w2 : Int = n4; var A : Int = n2; // for-while; var i : Int = 0; while (i < n4) { var x0 : Float = x[xA] - x[xB]; var x1 : Float; w[w2 + i] = (x[xA++] + x[xB++]); x1 = (x[xA] - x[xB]); A -= 4; w[i++] = ((x0 * trig[A]) + (x1 * trig[A + 1])); w[i] = ((x1 * trig[A]) - (x0 * trig[A + 1])); w[w2 + i] = (x[xA++] + x[xB++]); i++; }; // for-while; var i : Int = 0; while (i < (log2n - 3)) { var k0 : Int = n >>> (i + 2); var k1 : Int = 1 << (i + 3); var wbase : Int = n2 - 2; A = 0; var temp : Vector; // for-while; var r : Int = 0; while (r < (k0 >>> 2)) { var w1 : Int = wbase; w2 = (w1 - (k0 >> 1)); var AEv : Float = trig[A]; var wA : Float; var AOv : Float = trig[A + 1]; var wB : Float; wbase -= 2; k0++; // for-while; var s : Int = 0; while (s < (2 << i)) { wB = (w[w1] - w[w2]); x[w1] = (w[w1] + w[w2]); wA = (w[++w1] - w[++w2]); x[w1] = (w[w1] + w[w2]); x[w2] = ((wA * AEv) - (wB * AOv)); x[w2 - 1] = ((wB * AEv) + (wA * AOv)); w1 -= k0; w2 -= k0; s++; }; k0--; A += k1; r++; }; temp = w; w = x; x = temp; i++; }; { var C : Int = n; var bit : Int = 0; var x1 : Int = 0; var x2 : Int = n2 - 1; // for-while; var i : Int = 0; while (i < n8) { var t1 : Int = bitrev[bit++]; var t2 : Int = bitrev[bit++]; var wA : Float = w[t1] - w[t2 + 1]; var wB : Float = w[t1 - 1] + w[t2]; var wC : Float = w[t1] + w[t2 + 1]; var wD : Float = w[t1 - 1] - w[t2]; var wACE : Float = wA * trig[C]; var wBCE : Float = wB * trig[C++]; var wACO : Float = wA * trig[C]; var wBCO : Float = wB * trig[C++]; x[x1++] = (((wC + wACO) + wBCE) * 0.5); x[x2--] = (((-wD + wBCO) - wACE) * 0.5); x[x1++] = (((wD + wBCO) - wACE) * 0.5); x[x2--] = (((wC - wACO) - wBCE) * 0.5); i++; }; } return x; } public function new() { _x = new Vector(1024, true); _w = new Vector(1024, true); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/PsyInfo.hx000066400000000000000000000064411454362722700275010ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class PsyInfo { /* * generated source for PsyInfo */ var athp : Int; var decayp : Int; var smoothp : Int; var noisefitp : Int; var noisefit_subblock : Int; var noisefit_threshdB : Float; var ath_att : Float; var tonemaskp : Int; // discarded initializer: 'new float[5]'; var toneatt_125Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_250Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_500Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_1000Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_2000Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_4000Hz : Vector; // discarded initializer: 'new float[5]'; var toneatt_8000Hz : Vector; var peakattp : Int; // discarded initializer: 'new float[5]'; var peakatt_125Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_250Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_500Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_1000Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_2000Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_4000Hz : Vector; // discarded initializer: 'new float[5]'; var peakatt_8000Hz : Vector; var noisemaskp : Int; // discarded initializer: 'new float[5]'; var noiseatt_125Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_250Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_500Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_1000Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_2000Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_4000Hz : Vector; // discarded initializer: 'new float[5]'; var noiseatt_8000Hz : Vector; var max_curve_dB : Float; var attack_coeff : Float; var decay_coeff : Float; // modifiers: public function free() : Void { } public function new() { toneatt_125Hz = new Vector(5, true); toneatt_250Hz = new Vector(5, true); toneatt_500Hz = new Vector(5, true); toneatt_1000Hz = new Vector(5, true); toneatt_2000Hz = new Vector(5, true); toneatt_4000Hz = new Vector(5, true); toneatt_8000Hz = new Vector(5, true); peakatt_125Hz = new Vector(5, true); peakatt_250Hz = new Vector(5, true); peakatt_500Hz = new Vector(5, true); peakatt_1000Hz = new Vector(5, true); peakatt_2000Hz = new Vector(5, true); peakatt_4000Hz = new Vector(5, true); peakatt_8000Hz = new Vector(5, true); noiseatt_125Hz = new Vector(5, true); noiseatt_250Hz = new Vector(5, true); noiseatt_500Hz = new Vector(5, true); noiseatt_1000Hz = new Vector(5, true); noiseatt_2000Hz = new Vector(5, true); noiseatt_4000Hz = new Vector(5, true); noiseatt_8000Hz = new Vector(5, true); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/PsyLook.hx000066400000000000000000000007031454362722700275050ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; class PsyLook { /* * generated source for PsyLook */ var n : Int; var vi : PsyInfo; var tonecurves : Array>>; var peakatt : Array>; var noisecurves : Array>>; var ath : Array; var octave : Array; // modifiers: function init(vi : PsyInfo, n : Int, rate : Int) : Void { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Residue0.hx000066400000000000000000000317051454362722700275730ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class Residue0 extends FuncResidue { /* * generated source for Residue0 */ // modifiers: override function pack(vr : Dynamic, opb : Buffer) : Void { var info : InfoResidue0 = vr; var acc : Int = 0; opb.write(info.begin, 24); opb.write(info.end, 24); opb.write(info.grouping - 1, 24); opb.write(info.partitions - 1, 6); opb.write(info.groupbook, 8); // for-while; var j : Int = 0; while (j < info.partitions) { if (ilog(info.secondstages[j]) > 3) { opb.write(info.secondstages[j], 3); opb.write(1, 1); opb.write(info.secondstages[j] >>> 3, 5); } else { opb.write(info.secondstages[j], 4); }; acc += icount(info.secondstages[j]); j++; }; // for-while; var j : Int = 0; while (j < acc) { opb.write(info.booklist[j], 8); j++; }; } // modifiers: override function unpack(vi : Info, opb : Buffer) : Dynamic { var acc : Int = 0; var info : InfoResidue0 = new InfoResidue0(); info.begin = opb.read(24); info.end = opb.read(24); info.grouping = (opb.read(24) + 1); info.partitions = (opb.read(6) + 1); info.groupbook = opb.read(8); // for-while; var j : Int = 0; while (j < info.partitions) { var cascade : Int = opb.read(3); if (opb.read(1) != 0) { cascade |= (opb.read(5) << 3); }; info.secondstages[j] = cascade; acc += icount(cascade); j++; }; // for-while; var j : Int = 0; while (j < acc) { info.booklist[j] = opb.read(8); j++; }; if (info.groupbook >= vi.books) { free_info(info); return null; }; // for-while; var j : Int = 0; while (j < acc) { if (info.booklist[j] >= vi.books) { free_info(info); return null; }; j++; }; return info; } // modifiers: override function look(vd : DspState, vm : InfoMode, vr : Dynamic) : Dynamic { var info : InfoResidue0 = vr; var look : LookResidue0 = new LookResidue0(); var acc : Int = 0; var dim : Int; var maxstage : Int = 0; look.info = info; look.map = vm.mapping; look.parts = info.partitions; look.fullbooks = vd.fullbooks; look.phrasebook = vd.fullbooks[info.groupbook]; dim = look.phrasebook.dim; //look.partbooks = new int[look.parts]; look.partbooks = ArrayTools.alloc(look.parts); // for-while; var j : Int = 0; while (j < look.parts) { var stages : Int = ilog(info.secondstages[j]); if (stages != 0) { if (stages > maxstage) { maxstage = stages; }; //look.partbooks[j] = new int[stages]; look.partbooks[j] = new Vector(stages, true); // for-while; var k : Int = 0; while (k < stages) { if ((info.secondstages[j] & (1 << k)) != 0) { look.partbooks[j][k] = info.booklist[acc++]; }; k++; }; }; j++; }; look.partvals = Math.round(Math.pow(look.parts, dim)); look.stages = maxstage; //look.decodemap = new int[look.partvals]; look.decodemap = new Array(); // for-while; var j : Int = 0; while (j < look.partvals) { var val : Int = j; var mult : Int = Std.int(look.partvals / look.parts); //look.decodemap[j] = new int[dim]; look.decodemap[j] = new Vector(dim, true); // for-while; var k : Int = 0; while (k < dim) { var deco : Int = Std.int(val / mult); val -= (deco * mult); mult=Math.round(mult / look.parts); look.decodemap[j][k] = deco; k++; }; j++; }; return look; } // modifiers: override function free_info(i : Dynamic) : Void { } // modifiers: override function free_look(i : Dynamic) : Void { } // modifiers: override function forward(vb : Block, vl : Dynamic, in_ : Array>, ch : Int) : Int { trace("Residue0.forward: not implemented"); return 0; } //static var partword : Array>> = new int[2]; static var partword : Array>> = [null, null]; // modifiers: static, synchronized static function _inverse01(vb : Block, vl : Dynamic, in_ : Array>, ch : Int, decodepart : Int) : Int { var i : Int; var j : Int; var k : Int; var l : Int; var s : Int; var look : LookResidue0 = vl; var info : InfoResidue0 = look.info; var samples_per_partition : Int = info.grouping; var partitions_per_word : Int = look.phrasebook.dim; var n : Int = info.end - info.begin; var partvals : Int = Std.int(n / samples_per_partition); var partwords : Int = Std.int(((partvals + partitions_per_word) - 1) / partitions_per_word); if (partword.length < ch) { //Residue0.partword = new int[ch]; partword = ArrayTools.alloc(ch); // for-while; j = 0; while (j < ch) { //Residue0.partword[j] = new int[partwords]; partword[j] = ArrayTools.alloc(partwords); j++; }; } else { // for-while; j = 0; while (j < ch) { if ((partword[j] == null) || (partword[j].length < partwords)) { //Residue0.partword[j] = new int[partwords]; partword[j] = ArrayTools.alloc(partwords); }; j++; }; }; // for-while; s = 0; while (s < look.stages) { // for-while; i = 0; l = 0; while (i < partvals) { if (s == 0) { // for-while; j = 0; while (j < ch) { var temp : Int = look.phrasebook.decode(vb.opb); if (temp == -1) { return 0; }; partword[j][l] = look.decodemap[temp]; if (partword[j][l] == null) { return 0; }; j++; }; }; // for-while; k = 0; while ((k < partitions_per_word) && (i < partvals)) { // for-while; j = 0; while (j < ch) { var offset : Int = info.begin + (i * samples_per_partition); if ((info.secondstages[partword[j][l][k]] & (1 << s)) != 0) { var stagebook : CodeBook = look.fullbooks[look.partbooks[partword[j][l][k]][s]]; if (stagebook != null) { if (decodepart == 0) { if (stagebook.decodevs_add(in_[j], offset, vb.opb, samples_per_partition) == -1) { return 0; }; } else { if (decodepart == 1) { if (stagebook.decodev_add(in_[j], offset, vb.opb, samples_per_partition) == -1) { return 0; }; }; }; }; }; j++; }; k++; i++; }; l++; }; s++; }; return 0; } // modifiers: static static function _inverse2(vb : Block, vl : Dynamic, in_ : Array>, ch : Int) : Int { var i : Int; var j : Int; var k : Int; var l : Int; var s : Int; var look : LookResidue0 = vl; var info : InfoResidue0 = look.info; var samples_per_partition : Int = info.grouping; var partitions_per_word : Int = look.phrasebook.dim; var n : Int = info.end - info.begin; var partvals : Int = Std.int(n / samples_per_partition); var partwords : Int = Std.int(((partvals + partitions_per_word) - 1) / partitions_per_word); //var partword : Array> = new int[partwords]; var partword : Array> = new Array(); // for-while; s = 0; while (s < look.stages) { // for-while; i = 0; l = 0; while (i < partvals) { if (s == 0) { var temp : Int = look.phrasebook.decode(vb.opb); if (temp == -1) { return 0; }; partword[l] = look.decodemap[temp]; if (partword[l] == null) { return 0; }; }; // for-while; k = 0; while ((k < partitions_per_word) && (i < partvals)) { var offset : Int = info.begin + (i * samples_per_partition); if ((info.secondstages[partword[l][k]] & (1 << s)) != 0) { var stagebook : CodeBook = look.fullbooks[look.partbooks[partword[l][k]][s]]; if (stagebook != null) { if (stagebook.decodevv_add(in_, offset, ch, vb.opb, samples_per_partition) == -1) { return 0; }; }; }; k++; i++; }; l++; }; s++; }; return 0; } // modifiers: override function inverse(vb : Block, vl : Dynamic, in_ : Array>, nonzero : Vector, ch : Int) : Int { var used : Int = 0; // for-while; var i : Int = 0; while (i < ch) { if (nonzero[i] != 0) { in_[used++] = in_[i]; }; i++; }; if (used != 0) { return _inverse01(vb, vl, in_, used, 0); } else { return 0; }; } // modifiers: static, private static private function ilog(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret++; v >>>= 1; }; return ret; } // modifiers: static, private static private function icount(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret += (v & 1); v >>>= 1; }; return ret; } public function new() { } } class LookResidue0 { /* * generated source for LookResidue0 */ public var info : InfoResidue0; public var map : Int; public var parts : Int; public var stages : Int; public var fullbooks : Array; public var phrasebook : CodeBook; public var partbooks : Array>; public var partvals : Int; public var decodemap : Array>; public var postbits : Int; public var phrasebits : Int; public var frames : Int; public function new() { } } class InfoResidue0 { /* * generated source for InfoResidue0 */ public var begin : Int; public var end : Int; public var grouping : Int; public var partitions : Int; public var groupbook : Int; // discarded initializer: 'new int[64]'; public var secondstages : Vector; // discarded initializer: 'new int[256]'; public var booklist : Vector; // discarded initializer: 'new float[64]'; public var entmax : Vector; // discarded initializer: 'new float[64]'; public var ampmax : Vector; // discarded initializer: 'new int[64]'; public var subgrp : Vector; // discarded initializer: 'new int[64]'; public var blimit : Vector; public function new() { secondstages = new Vector(64); booklist = new Vector(256); entmax = new Vector(64); ampmax = new Vector(64); subgrp = new Vector(64); blimit = new Vector(64); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Residue1.hx000066400000000000000000000016421454362722700275710ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Residue1 extends Residue0 { /* * generated source for Residue1 */ // modifiers: override function forward(vb : Block, vl : Dynamic, in_ : Array>, ch : Int) : Int { trace("Residue0.forward: not implemented"); return 0; } // modifiers: override function inverse(vb : Block, vl : Dynamic, in_ : Array>, nonzero : Vector, ch : Int) : Int { var used : Int = 0; // for-while; var i : Int = 0; while (i < ch) { if (nonzero[i] != 0) { in_[used++] = in_[i]; }; i++; }; if (used != 0) { return Residue0._inverse01(vb, vl, in_, used, 1); } else { return 0; }; } public function new() { super(); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Residue2.hx000066400000000000000000000015411454362722700275700ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; class Residue2 extends Residue0 { /* * generated source for Residue2 */ // modifiers: override function forward(vb : Block, vl : Dynamic, in_ : Array>, ch : Int) : Int { trace("Residue0.forward: not implemented"); return 0; } // modifiers: override function inverse(vb : Block, vl : Dynamic, in_ : Array>, nonzero : Vector, ch : Int) : Int { var i : Int = 0; // for-while; i = 0; while (i < ch) { if (nonzero[i] != 0) { break; }; i++; }; if (i == ch) { return 0; }; return Residue0._inverse2(vb, vl, in_, ch); } public function new() { super(); } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/StaticCodeBook.hx000066400000000000000000000306641454362722700307530ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; class StaticCodeBook { /* * generated source for StaticCodeBook */ public var dim : Int; public var entries : Int; public var lengthlist : Vector; var maptype : Int; var q_min : Int; var q_delta : Int; var q_quant : Int; var q_sequencep : Int; var quantlist : Vector; public var nearest_tree : EncodeAuxNearestMatch; public var thresh_tree : EncodeAuxThreshMatch; // modifiers: public function new() { } // modifiers: public function newWA(dim : Int, entries : Int, lengthlist : Vector, maptype : Int, q_min : Int, q_delta : Int, q_quant : Int, q_sequencep : Int, quantlist : Vector, nearest_tree : Dynamic, thresh_tree : Dynamic) { //this.new(); this.dim = dim; this.entries = entries; this.lengthlist = lengthlist; this.maptype = maptype; this.q_min = q_min; this.q_delta = q_delta; this.q_quant = q_quant; this.q_sequencep = q_sequencep; this.quantlist = quantlist; } // modifiers: public function pack(opb : Buffer) : Int { var i : Int; var ordered : Bool = false; opb.write(0x564342, 24); opb.write(dim, 16); opb.write(entries, 24); // for-while; i = 1; while (i < entries) { if (lengthlist[i] < lengthlist[i - 1]) { break; }; i++; }; if (i == entries) { ordered = true; }; if (ordered) { var count : Int = 0; opb.write(1, 1); opb.write(lengthlist[0] - 1, 5); // for-while; i = 1; while (i < entries) { var _this : Int = lengthlist[i]; var _last : Int = lengthlist[i - 1]; if (_this > _last) { // for-while; var j : Int = _last; while (j < _this) { opb.write(i - count, StaticCodeBook.ilog(entries - count)); count = i; j++; }; }; i++; }; opb.write(i - count, StaticCodeBook.ilog(entries - count)); } else { opb.write(0, 1); // for-while; i = 0; while (i < entries) { if (lengthlist[i] == 0) { break; }; i++; }; if (i == entries) { opb.write(0, 1); // for-while; i = 0; while (i < entries) { opb.write(lengthlist[i] - 1, 5); i++; }; } else { opb.write(1, 1); // for-while; i = 0; while (i < entries) { if (lengthlist[i] == 0) { opb.write(0, 1); } else { opb.write(1, 1); opb.write(lengthlist[i] - 1, 5); }; i++; }; }; }; opb.write(maptype, 4); while (true) { if (maptype == 0) { break; } else if (maptype == 1 || maptype == 2) { if (quantlist == null) { return -1; }; opb.write(q_min, 32); opb.write(q_delta, 32); opb.write(q_quant - 1, 4); opb.write(q_sequencep, 1); { var quantvals : Int = 0; switch (maptype) { case 1: quantvals = maptype1_quantvals(); break; case 2: quantvals = (entries * dim); break; }; // for-while; i = 0; while (i < quantvals) { opb.write(System.abs(quantlist[i]), q_quant); i++; }; }; break; }; return -1; }; return 0; } // modifiers: public function unpack(opb : Buffer) : Int { var i : Int; if (opb.read(24) != 0x564342) { clear(); return -1; }; dim = opb.read(16); entries = opb.read(24); if (entries == -1) { clear(); return -1; }; switch (opb.read(1)) { case 0: //lengthlist = new int[entries]; lengthlist = new Vector(entries, true); if (opb.read(1) != 0) { // for-while; i = 0; while (i < entries) { if (opb.read(1) != 0) { var num : Int = opb.read(5); if (num == -1) { clear(); return -1; }; lengthlist[i] = (num + 1); } else { lengthlist[i] = 0; }; i++; }; } else { // for-while; i = 0; while (i < entries) { var num : Int = opb.read(5); if (num == -1) { clear(); return -1; }; lengthlist[i] = (num + 1); i++; }; }; case 1: var length : Int = opb.read(5) + 1; //lengthlist = new int[entries]; lengthlist = new Vector(entries, true); // for-while; i = 0; while (i < entries) { var num : Int = opb.read(StaticCodeBook.ilog(entries - i)); if (num == -1) { clear(); return -1; }; // for-while; var j : Int = 0; while (j < num) { lengthlist[i] = length; j++; i++; }; length++; }; default: return -1; }; { var swval = maptype = opb.read(4); if (swval == 0) { } else if (swval == 1 || swval == 2) { q_min = opb.read(32); q_delta = opb.read(32); q_quant = (opb.read(4) + 1); q_sequencep = opb.read(1); { var quantvals : Int = 0; switch (maptype) { case 1: quantvals = maptype1_quantvals(); case 2: quantvals = (entries * dim); }; //quantlist = new int[quantvals]; quantlist = new Vector(quantvals, true); // for-while; i = 0; while (i < quantvals) { quantlist[i] = opb.read(q_quant); i++; }; if (quantlist[quantvals - 1] == -1) { clear(); return -1; }; }; } else { clear(); return -1; } }; return 0; } // modifiers: private private function maptype1_quantvals() : Int { var vals : Int = Math.floor(Math.pow(entries, 1. / dim)); while (true) { var acc : Int = 1; var acc1 : Int = 1; // for-while; var i : Int = 0; while (i < dim) { acc *= vals; acc1 *= (vals + 1); i++; }; if ((acc <= entries) && (acc1 > entries)) { return vals; } else { if (acc > entries) { vals--; } else { vals++; }; }; }; throw "NoValueToReturn"; } // modifiers: public function clear() : Void { } // modifiers: public function unquantize() : Vector { if ((maptype == 1) || (maptype == 2)) { var quantvals : Int; var mindel : Float = StaticCodeBook.float32_unpack(q_min); var delta : Float = StaticCodeBook.float32_unpack(q_delta); //var r : Vector = new float[entries * dim]; var r : Vector = new Vector(entries * dim, true); switch (maptype) { case 1: quantvals = maptype1_quantvals(); // for-while; var j : Int = 0; while (j < entries) { var last : Float = 0.; var indexdiv : Int = 1; // for-while; var k : Int = 0; while (k < dim) { var index : Int = Std.int(j / indexdiv) % quantvals; var val : Float = quantlist[index]; val = (((Math.abs(val) * delta) + mindel) + last); if (q_sequencep != 0) { last = val; }; r[(j * dim) + k] = val; indexdiv *= quantvals; k++; }; j++; }; case 2: // for-while; var j : Int = 0; while (j < entries) { var last : Float = 0.; // for-while; var k : Int = 0; while (k < dim) { var val : Float = quantlist[(j * dim) + k]; val = (((Math.abs(val) * delta) + mindel) + last); if (q_sequencep != 0) { last = val; }; r[(j * dim) + k] = val; k++; }; j++; }; }; return r; }; return null; } // modifiers: static, private static private function ilog(v : Int) : Int { var ret : Int = 0; while (v != 0) { ret++; v >>>= 1; }; return ret; } inline static var VQ_FEXP : Int = 10; inline static var VQ_FMAN : Int = 21; inline static var VQ_FEXP_BIAS : Int = 768; // modifiers: static static function float32_pack(val : Float) : Int { var sign : Int = 0; var exp : Int; var mant : Int; if (val < 0) { sign = 0x80000000; val = -val; }; exp = Math.floor(Math.log(val) / Math.log(2)); mant = Math.round(Math.pow(val, (StaticCodeBook.VQ_FMAN - 1) - exp)); exp = ((exp + StaticCodeBook.VQ_FEXP_BIAS) << StaticCodeBook.VQ_FMAN); return (sign | exp) | mant; } // modifiers: static static function float32_unpack(val : Int) : Float { var mant : Float = val & 0x1fffff; var sign : Float = val & 0x80000000; var exp : Float = (val & 0x7fe00000) >>> StaticCodeBook.VQ_FMAN; if ((val & 0x80000000) != 0) { mant = -mant; }; return StaticCodeBook.ldexp(mant, (Std.int(exp) - (StaticCodeBook.VQ_FMAN - 1)) - StaticCodeBook.VQ_FEXP_BIAS); } // modifiers: static static function ldexp(foo : Float, e : Int) : Float { return foo * Math.pow(2, e); } /* // modifiers: inline inline function new() { // FIXME: implement disambiguation handler; // __new_0(); // __new_1(dim : Int, entries : Int, lengthlist : Vector, maptype : Int, q_min : Int, q_delta : Int, q_quant : Int, q_sequencep : Int, quantlist : Vector, nearest_tree : Dynamic, thresh_tree : Dynamic); throw "NotImplementedError"; } */ } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/Time0.hx000066400000000000000000000017631454362722700270720ustar00rootroot00000000000000package org.xiph.fvorbis; import org.xiph.system.Bytes; import flash.Vector; import org.xiph.fogg.Buffer; import org.xiph.fvorbis.FuncTime; class Time0 extends FuncTime { /* * generated source for Time0 */ // modifiers: override function pack(i : Dynamic, opb : Buffer) : Void { } // modifiers: override public function unpack(vi : Info, opb : Buffer) : Dynamic { return ""; } // modifiers: override function look(vd : DspState, mi : InfoMode, i : Dynamic) : Dynamic { return ""; } // modifiers: override function free_info(i : Dynamic) : Void { } // modifiers: override function free_look(i : Dynamic) : Void { } // modifiers: override function forward(vb : Block, i : Dynamic) : Int { return 0; } // modifiers: override function inverse(vb : Block, i : Dynamic, in_ : Vector, out : Vector) : Int { return 0; } public function new() { } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/fvorbis/VorbisFile.hx000066400000000000000000001214761454362722700301640ustar00rootroot00000000000000//#!/usr/bin/env python //# -*- coding: utf-8 -*- package org.xiph.fvorbis; import org.xiph.system.Bytes; import org.xiph.fogg.*; import java.io.*; class VorbisFile { /* * generated source for VorbisFile */ inline static var CHUNKSIZE : Int = 8500; inline static var SEEK_SET : Int = 0; inline static var SEEK_CUR : Int = 1; inline static var SEEK_END : Int = 2; inline static var OV_FALSE : Int = -1; inline static var OV_EOF : Int = -2; inline static var OV_HOLE : Int = -3; inline static var OV_EREAD : Int = -128; inline static var OV_EFAULT : Int = -129; inline static var OV_EIMPL : Int = -130; inline static var OV_EINVAL : Int = -131; inline static var OV_ENOTVORBIS : Int = -132; inline static var OV_EBADHEADER : Int = -133; inline static var OV_EVERSION : Int = -134; inline static var OV_ENOTAUDIO : Int = -135; inline static var OV_EBADPACKET : Int = -136; inline static var OV_EBADLINK : Int = -137; inline static var OV_ENOSEEK : Int = -138; var datasource : InputStream; // discarded initializer: 'false'; var seekable : Bool; var offset : Int; var end : Int; // discarded initializer: 'SyncState()'; var oy : SyncState; var links : Int; var offsets : Array; var dataoffsets : Array; var serialnos : Array; var pcmlengths : Array; var vi : Array; var vc : Array; var pcm_offset : Int; // discarded initializer: 'false'; var decode_ready : Bool; var current_serialno : Int; var current_link : Int; var bittrack : Float; var samptrack : Float; // discarded initializer: 'StreamState()'; var os : StreamState; // discarded initializer: 'DspState()'; var vd : DspState; // discarded initializer: 'Block(vd)'; var vb : Block; // modifiers: public, throws JOrbisException public throws JOrbisException function __new_0(file : String) { super(); if { }; var is_ : InputStream = null; try { is_ = SeekableInputStream(file); } catch (e : Exception) { raise JOrbisException("VorbisFile: " + str(e)); }; var ret : Int = open(is_, null, 0); if (ret == -1) { raise JOrbisException("VorbisFile: open return -1"); }; } // modifiers: public, throws JOrbisException public throws JOrbisException function __new_1(is_ : InputStream, initial : Bytes, ibytes : Int) { super(); if { }; var ret : Int = open(is_, initial, ibytes); if (ret == -1) { }; } // modifiers: private private function get_data() : Int { var index : Int = oy.buffer(VorbisFile.CHUNKSIZE); var buffer : Bytes = oy.data; var bytes : Int = 0; try { bytes = datasource.read(buffer, index, VorbisFile.CHUNKSIZE); } catch (e : Exception) { trace(e); return VorbisFile.OV_EREAD; }; oy.wrote(bytes); if (bytes == -1) { bytes = 0; }; return bytes; } // modifiers: private private function seek_helper(offst : Int) : Void { VorbisFile.fseek(datasource, offst, VorbisFile.SEEK_SET); this.offset = offst; oy.reset(); } // modifiers: private private function get_next_page(page : Page, boundary : Int) : Int { if (boundary > 0) { boundary += offset; }; while (true) { var more : Int; if ((boundary > 0) && (offset >= boundary)) { return VorbisFile.OV_FALSE; }; more = oy.pageseek(page); if (more < 0) { offset -= more; } else { if (more == 0) { if (boundary == 0) { return VorbisFile.OV_FALSE; }; var ret : Int = get_data(); if (ret == 0) { return VorbisFile.OV_EOF; }; if (ret < 0) { return VorbisFile.OV_EREAD; }; } else { var ret : Int = offset; offset += more; return ret; }; }; }; } // modifiers: private private function get_prev_page(page : Page) : Int { var begin : Int = offset; var ret : Int; var offst : Int = -1; while (offst == -1) { begin -= VorbisFile.CHUNKSIZE; if (begin < 0) { begin = 0; }; seek_helper(begin); while (offset < (begin + VorbisFile.CHUNKSIZE)) { ret = get_next_page(page, (begin + VorbisFile.CHUNKSIZE) - offset); if (ret == VorbisFile.OV_EREAD) { return VorbisFile.OV_EREAD; }; if (ret < 0) { break; } else { offst = ret; }; }; }; seek_helper(offst); ret = get_next_page(page, VorbisFile.CHUNKSIZE); if (ret < 0) { return VorbisFile.OV_EFAULT; }; return offst; } // modifiers: function bisect_forward_serialno(begin : Int, searched : Int, end : Int, currentno : Int, m : Int) : Int { var endsearched : Int = end; var next : Int = end; var page : Page = Page(); var ret : Int; while (searched < endsearched) { var bisect : Int; if ((endsearched - searched) < VorbisFile.CHUNKSIZE) { bisect = searched; } else { bisect = ((searched + endsearched) / 2); }; seek_helper(bisect); ret = get_next_page(page, -1); if (ret == VorbisFile.OV_EREAD) { return VorbisFile.OV_EREAD; }; if ((ret < 0) || (page.serialno() != currentno)) { endsearched = bisect; if (ret >= 0) { next = ret; }; } else { searched = ((ret + page.header_len) + page.body_len); }; }; seek_helper(next); ret = get_next_page(page, -1); if (ret == VorbisFile.OV_EREAD) { return VorbisFile.OV_EREAD; }; if ((searched >= end) || (ret == -1)) { links = (m + 1); offsets = new long[m + 2]; offsets[m + 1] = searched; } else { ret = bisect_forward_serialno(next, offset, end, page.serialno(), m + 1); if (ret == VorbisFile.OV_EREAD) { return VorbisFile.OV_EREAD; }; }; offsets[m] = begin; return 0; } // modifiers: function fetch_headers(vi : Info, vc : Comment, serialno : Array, og_ptr : Page) : Int { var og : Page = Page(); var op : Packet = Packet(); var ret : Int; if (og_ptr == null) { ret = get_next_page(og, VorbisFile.CHUNKSIZE); if (ret == VorbisFile.OV_EREAD) { return VorbisFile.OV_EREAD; }; if (ret < 0) { return VorbisFile.OV_ENOTVORBIS; }; og_ptr = og; }; if (serialno != null) { serialno[0] = og_ptr.serialno(); }; os.init(og_ptr.serialno()); vi.init(); vc.init(); var i : Int = 0; while (i < 3) { os.pagein(og_ptr); while (i < 3) { var result : Int = os.packetout(op); if (result == 0) { break; }; if (result == -1) { trace("Corrupt header in logical bitstream."); vi.clear(); vc.clear(); os.clear(); return -1; }; if (vi.synthesis_headerin(vc, op) != 0) { trace("Illegal header in logical bitstream."); vi.clear(); vc.clear(); os.clear(); return -1; }; i++; }; if (i < 3) { if (get_next_page(og_ptr, 1) < 0) { trace("Missing header in logical bitstream."); vi.clear(); vc.clear(); os.clear(); return -1; }; }; }; return 0; } // modifiers: function prefetch_all_headers(first_i : Info, first_c : Comment, dataoffset : Int) : Void { var og : Page = Page(); var ret : Int; vi = new Info[links]; vc = new Comment[links]; dataoffsets = new long[links]; pcmlengths = new long[links]; serialnos = new int[links]; // for-while; var i : Int = 0; while (i < links) { if (((first_i != null) && (first_c != null)) && (i == 0)) { vi[i] = first_i; vc[i] = first_c; dataoffsets[i] = dataoffset; } else { seek_helper(offsets[i]); if (fetch_headers(vi[i], vc[i], null, null) == -1) { trace(("Error opening logical bitstream #" + (i + 1)) + "\n"); dataoffsets[i] = -1; } else { dataoffsets[i] = offset; os.clear(); }; }; var end : Int = offsets[i + 1]; seek_helper(end); while (true) { ret = get_prev_page(og); if (ret == -1) { trace((("Could not find last page of logical " + "bitstream #") + i) + "\n"); vi[i].clear(); vc[i].clear(); break; }; if (og.granulepos() != -1) { serialnos[i] = og.serialno(); pcmlengths[i] = og.granulepos(); break; }; }; i++; }; } // modifiers: function make_decode_ready() : Int { if (decode_ready) { System.exit(1); }; vd.synthesis_init(vi[0]); vb.init(vd); decode_ready = true; return 0; } // modifiers: function open_seekable() : Int { var initial_i : Info = Info(); var initial_c : Comment = Comment(); var serialno : Int; var end : Int; var ret : Int; var dataoffset : Int; var og : Page = Page(); var foo : Array = new int[1]; ret = fetch_headers(initial_i, initial_c, foo, null); serialno = foo[0]; dataoffset = offset; os.clear(); if (ret == -1) { return -1; }; seekable = true; VorbisFile.fseek(datasource, 0, VorbisFile.SEEK_END); offset = VorbisFile.ftell(datasource); end = offset; end = get_prev_page(og); if (og.serialno() != serialno) { if (bisect_forward_serialno(0, 0, end + 1, serialno, 0) < 0) { clear(); return VorbisFile.OV_EREAD; }; } else { if (bisect_forward_serialno(0, end, end + 1, serialno, 0) < 0) { clear(); return VorbisFile.OV_EREAD; }; }; prefetch_all_headers(initial_i, initial_c, dataoffset); return raw_seek(0); } // modifiers: function open_nonseekable() : Int { links = 1; vi = new Info[links]; vi[0] = Info(); vc = new Comment[links]; vc[0] = Comment(); var foo : Array = new int[1]; if (fetch_headers(vi[0], vc[0], foo, null) == -1) { return -1; }; current_serialno = foo[0]; make_decode_ready(); return 0; } // modifiers: function decode_clear() : Void { os.clear(); vd.clear(); vb.clear(); decode_ready = false; bittrack = 0.; samptrack = 0.; } // modifiers: function process_packet(readp : Int) : Int { var og : Page = Page(); while (true) { if (decode_ready) { var op : Packet = Packet(); var result : Int = os.packetout(op); var granulepos : Int; if (result > 0) { granulepos = op.granulepos; if (vb.synthesis(op) == 0) { var oldsamples : Int = vd.synthesis_pcmout(null, null); vd.synthesis_blockin(vb); samptrack += (vd.synthesis_pcmout(null, null) - oldsamples); bittrack += (op.bytes * 8); if ((granulepos != -1) && (op.e_o_s == 0)) { var link : Int = (seekable ? current_link : 0); var samples : Int; samples = vd.synthesis_pcmout(null, null); granulepos -= samples; // for-while; var i : Int = 0; while (i < link) { granulepos += pcmlengths[i]; i++; }; pcm_offset = granulepos; }; return 1; }; }; }; if (readp == 0) { return 0; }; if (get_next_page(og, -1) < 0) { return 0; }; bittrack += (og.header_len * 8); if (decode_ready) { if (current_serialno != og.serialno()) { decode_clear(); }; }; if (!decode_ready) { var i : Int; if (seekable) { current_serialno = og.serialno(); // for-while; i = 0; while (i < links) { if (serialnos[i] == current_serialno) { break; }; i++; }; if (i == links) { return -1; }; current_link = i; os.init(current_serialno); os.reset(); } else { var foo : Array = new int[1]; var ret : Int = fetch_headers(vi[0], vc[0], foo, og); current_serialno = foo[0]; if (ret != 0) { return ret; }; current_link++; i = 0; }; make_decode_ready(); }; os.pagein(og); }; } // modifiers: function clear() : Int { vb.clear(); vd.clear(); os.clear(); if ((vi != null) && (links != 0)) { // for-while; var i : Int = 0; while (i < links) { vi[i].clear(); vc[i].clear(); i++; }; vi = null; vc = null; }; if (dataoffsets != null) { dataoffsets = null; }; if (pcmlengths != null) { pcmlengths = null; }; if (serialnos != null) { serialnos = null; }; if (offsets != null) { offsets = null; }; oy.clear(); return 0; } // modifiers: static static function fseek(fis : InputStream, off : Int, whence : Int) : Int { if (isinstance(fis, (SeekableInputStream))) { var sis : SeekableInputStream = fis; try { if (whence == VorbisFile.SEEK_SET) { sis.seek(off); } else { if (whence == VorbisFile.SEEK_END) { sis.seek(sis.getLength() - off); } else { print ("seek: " + whence + " is not supported"); }; }; } catch (e : Exception) { }; return 0; }; try { if (whence == 0) { fis.reset(); }; fis.skip(off); } catch (e : Exception) { return -1; }; return 0; } // modifiers: static static function ftell(fis : InputStream) : Int { try { if (isinstance(fis, (SeekableInputStream))) { var sis : SeekableInputStream = fis; return sis.tell(); }; } catch (e : Exception) { }; return 0; } // modifiers: function open(is_ : InputStream, initial : Bytes, ibytes : Int) : Int { return open_callbacks(is_, initial, ibytes); } // modifiers: function open_callbacks(is_ : InputStream, initial : Bytes, ibytes : Int) : Int { var ret : Int; datasource = is_; oy.init(); if (initial != null) { var index : Int = oy.buffer(ibytes); System.arraycopy(initial, 0, oy.data, index, ibytes); oy.wrote(ibytes); }; if (isinstance(is_, (SeekableInputStream))) { ret = open_seekable(); } else { ret = open_nonseekable(); }; if (ret != 0) { datasource = null; clear(); }; return ret; } // modifiers: public public function streams() : Int { return links; } // modifiers: public public function seekable() : Bool { // FIXME: shadows variable 'seekable'; return seekable; } // modifiers: public public function bitrate(i : Int) : Int { if (i >= links) { return -1; }; if (!seekable && (i != 0)) { return bitrate(0); }; if (i < 0) { var bits : Int = 0; // for-while; var j : Int = 0; while (j < links) { bits += ((offsets[j + 1] - dataoffsets[j]) * 8); j++; }; return Math.rint(bits / time_total(-1)); } else { if (seekable) { return Math.rint(((offsets[i + 1] - dataoffsets[i]) * 8) / time_total(i)); } else { if (vi[i].bitrate_nominal > 0) { return vi[i].bitrate_nominal; } else { if (vi[i].bitrate_upper > 0) { if (vi[i].bitrate_lower > 0) { return (vi[i].bitrate_upper + vi[i].bitrate_lower) / 2; } else { return vi[i].bitrate_upper; }; }; return -1; }; }; }; } // modifiers: public public function bitrate_instant() : Int { var _link : Int = (seekable ? current_link : 0); if (samptrack == 0) { return -1; }; var ret : Int = ((bittrack / samptrack) * vi[_link].rate) + 0.5; bittrack = 0.; samptrack = 0.; return ret; } // modifiers: public public function serialnumber(i : Int) : Int { if (i >= links) { return -1; }; if (!seekable && (i >= 0)) { return serialnumber(-1); }; if (i < 0) { return current_serialno; } else { return serialnos[i]; }; } // modifiers: public public function raw_total(i : Int) : Int { if (!seekable || (i >= links)) { return -1; }; if (i < 0) { var acc : Int = 0; // for-while; var j : Int = 0; while (j < links) { acc += raw_total(j); j++; }; return acc; } else { return offsets[i + 1] - offsets[i]; }; } // modifiers: public public function pcm_total(i : Int) : Int { if (!seekable || (i >= links)) { return -1; }; if (i < 0) { var acc : Int = 0; // for-while; var j : Int = 0; while (j < links) { acc += pcm_total(j); j++; }; return acc; } else { return pcmlengths[i]; }; } // modifiers: public public function time_total(i : Int) : Float { if (!seekable || (i >= links)) { return -1; }; if (i < 0) { var acc : Float = 0; // for-while; var j : Int = 0; while (j < links) { acc += time_total(j); j++; }; return acc; } else { return pcmlengths[i] / vi[i].rate; }; } // modifiers: public public function raw_seek(pos : Int) : Int { if (!seekable) { return -1; }; if ((pos < 0) || (pos > offsets[links])) { pcm_offset = -1; decode_clear(); return -1; }; pcm_offset = -1; decode_clear(); seek_helper(pos); while True { if process_packet(1) == 0 { pcm_offset = pcm_total(-1); return 0; }; if process_packet(1) == -1 { pcm_offset = -1; decode_clear(); return -1; }; break; break; }; while (true) { while True { if process_packet(0) == 0 { return 0; }; if process_packet(0) == -1 { pcm_offset = -1; decode_clear(); return -1; }; break; break; }; }; } // modifiers: public public function pcm_seek(pos : Int) : Int { var link : Int = -1; var total : Int = pcm_total(-1); if (!seekable) { return -1; }; if ((pos < 0) || (pos > total)) { pcm_offset = -1; decode_clear(); return -1; }; // for-while; link = (links - 1); while (link >= 0) { total -= pcmlengths[link]; if (pos >= total) { break; }; link--; }; var target : Int = pos - total; var end : Int = offsets[link + 1]; var begin : Int = offsets[link]; var best : Int = begin; var og : Page = Page(); while (begin < end) { var bisect : Int; var ret : Int; if ((end - begin) < VorbisFile.CHUNKSIZE) { bisect = begin; } else { bisect = ((end + begin) / 2); }; seek_helper(bisect); ret = get_next_page(og, end - bisect); if (ret == -1) { end = bisect; } else { var granulepos : Int = og.granulepos(); if (granulepos < target) { best = ret; begin = offset; } else { end = bisect; }; }; }; if (raw_seek(best) != 0) { pcm_offset = -1; decode_clear(); return -1; }; if (pcm_offset >= pos) { pcm_offset = -1; decode_clear(); return -1; }; if (pos > pcm_total(-1)) { pcm_offset = -1; decode_clear(); return -1; }; while (pcm_offset < pos) { var pcm : Array>; var target : Int = pos - pcm_offset; var _pcm : Array>> = new float[1]; var _index : Array = new int[getInfo(-1).channels]; var samples : Int = vd.synthesis_pcmout(_pcm, _index); pcm = _pcm[0]; if (samples > target) { samples = target; }; vd.synthesis_read(samples); pcm_offset += samples; if (samples < target) { if (process_packet(1) == 0) { pcm_offset = pcm_total(-1); }; }; }; return 0; } // modifiers: function time_seek(seconds : Float) : Int { var link : Int = -1; var pcm_total : Int = pcm_total(-1); var time_total : Float = time_total(-1); if (!seekable) { return -1; }; if ((seconds < 0) || (seconds > time_total)) { pcm_offset = -1; decode_clear(); return -1; }; // for-while; link = (links - 1); while (link >= 0) { pcm_total -= pcmlengths[link]; time_total -= time_total(link); if (seconds >= time_total) { break; }; link--; }; var target : Int = pcm_total + ((seconds - time_total) * vi[link].rate); return pcm_seek(target); } // modifiers: public public function raw_tell() : Int { return offset; } // modifiers: public public function pcm_tell() : Int { return pcm_offset; } // modifiers: public public function time_tell() : Float { var link : Int = -1; var pcm_total : Int = 0; var time_total : Float = 0.; if (seekable) { pcm_total = pcm_total(-1); time_total = time_total(-1); // for-while; link = (links - 1); while (link >= 0) { pcm_total -= pcmlengths[link]; time_total -= time_total(link); if (pcm_offset >= pcm_total) { break; }; link--; }; }; return time_total + (pcm_offset - pcm_total / vi[link].rate); } // modifiers: public public function __getInfo_0(link : Int) : Info { if (seekable) { if (link < 0) { if (decode_ready) { return vi[current_link]; } else { return; }; } else { if (link >= links) { return; } else { return vi[link]; }; }; } else { if (decode_ready) { return vi[0]; } else { return; }; }; } // modifiers: public public function __getComment_0(link : Int) : Comment { if (seekable) { if (link < 0) { if (decode_ready) { return vc[current_link]; } else { return; }; } else { if (link >= links) { return; } else { return vc[link]; }; }; } else { if (decode_ready) { return vc[0]; } else { return; }; }; } // modifiers: function host_is_big_endian() : Int { return 1; } // modifiers: function read(buffer : Bytes, length : Int, bigendianp : Int, word : Int, sgned : Int, bitstream : Array) : Int { var host_endian : Int = host_is_big_endian(); var index : Int = 0; while (true) { if (decode_ready) { var pcm : Array>; var _pcm : Array>> = new float[1]; var _index : Array = new int[getInfo(-1).channels]; var samples : Int = vd.synthesis_pcmout(_pcm, _index); pcm = _pcm[0]; if (samples != 0) { var channels : Int = getInfo(-1).channels; var bytespersample : Int = word * channels; if (samples > (length / bytespersample)) { samples = (length / bytespersample); }; var val : Int; if (word == 1) { var off : Int = (sgned != 0 ? 0 : 128); // for-while; var j : Int = 0; while (j < samples) { // for-while; var i : Int = 0; while (i < channels) { val = (pcm[i][_index[i] + j] * 128.) + 0.5; if (val > 127) { val = 127; } else { if (val < -128) { val = -128; }; }; buffer[index++] = val + off; i++; }; j++; }; } else { var off : Int = (sgned != 0 ? 0 : 32768); if (host_endian == bigendianp) { if (sgned != 0) { // for-while; var i : Int = 0; while (i < channels) { var src : Int = _index[i]; var dest : Int = i; // for-while; var j : Int = 0; while (j < samples) { val = (pcm[i][src + j] * 32768.) + 0.5; if (val > 32767) { val = 32767; } else { if (val < -32768) { val = -32768; }; }; buffer[dest] = val >>> 8; buffer[dest + 1] = val; dest += (channels * 2); j++; }; i++; }; } else { // for-while; var i : Int = 0; while (i < channels) { var src : Array = pcm[i]; var dest : Int = i; // for-while; var j : Int = 0; while (j < samples) { val = (src[j] * 32768.) + 0.5; if (val > 32767) { val = 32767; } else { if (val < -32768) { val = -32768; }; }; buffer[dest] = (val + off) >>> 8; buffer[dest + 1] = val + off; dest += (channels * 2); j++; }; i++; }; }; } else { if (bigendianp != 0) { // for-while; var j : Int = 0; while (j < samples) { // for-while; var i : Int = 0; while (i < channels) { val = (pcm[i][j] * 32768.) + 0.5; if (val > 32767) { val = 32767; } else { if (val < -32768) { val = -32768; }; }; val += off; buffer[index++] = val >>> 8; buffer[index++] = val; i++; }; j++; }; } else { // for-while; var j : Int = 0; while (j < samples) { // for-while; var i : Int = 0; while (i < channels) { val = (pcm[i][j] * 32768.) + 0.5; if (val > 32767) { val = 32767; } else { if (val < -32768) { val = -32768; }; }; val += off; buffer[index++] = val; buffer[index++] = val >>> 8; i++; }; j++; }; }; }; }; vd.synthesis_read(samples); pcm_offset += samples; if (bitstream != null) { bitstream[0] = current_link; }; return samples * bytespersample; }; }; while True { if process_packet(1) == 0 { return 0; }; if process_packet(1) == -1 { return -1; }; break; break; }; }; } // modifiers: public public function __getInfo_1() : Array { return vi; } // modifiers: public public function __getComment_1() : Array { return vc; } // modifiers: static, public static public function main(arg : Array) : Void { try { var foo : VorbisFile = VorbisFile(arg[0]); var links : Int = foo.streams(); print "links=" + links; var comment : Array = foo.getComment(); var info : Array = foo.getInfo(); // for-while; var i : Int = 0; while (i < links) { print info[i]; print comment[i]; i++; }; print "raw_total: " + foo.raw_total(-1); print "pcm_total: " + foo.pcm_total(-1); print "time_total: " + foo.time_total(-1); } catch (e : Exception) { trace(e); }; } class SeekableInputStream extends InputStream { /* * generated source for SeekableInputStream */ // discarded initializer: 'null'; var raf : ..RandomAccessFile; inline static var mode : String = "r"; // modifiers: private private function __new_0() { } // modifiers: throws java.io.FileNotFoundException throws java.io.FileNotFoundException function __new_1(file : String) : java.io.RandomAccessFile { raf = java.io.RandomAccessFile(file, SeekableInputStream.mode); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function __read_0() : Int { return raf.read(); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function __read_1(buf : Bytes) : Int { return raf.read(buf); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function __read_2(buf : Bytes, s : Int, len : Int) : Int { return raf.read(buf, s, len); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function skip(n : Int) : Int { return raf.skipBytes(n); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function getLength() : Int { return len(raf); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function tell() : Int { return raf.getFilePointer(); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function available() : Int { return len((raf) == raf.getFilePointer() ? 0 : 1); } // modifiers: throws java.io.IOException, public throws java.io.IOException public function close() : Void { raf.close(); } // modifiers: public, synchronized public synchronized function mark(m : Int) : Void { } // modifiers: throws java.io.IOException, public, synchronized throws java.io.IOException public synchronized function reset() : Void { } // modifiers: public public function markSupported() : Bool { return false; } // modifiers: throws java.io.IOException, public throws java.io.IOException public function seek(pos : Int) : Void { raf.seek(pos); } // modifiers: throws java.io.IOException, public, inline throws java.io.IOException public inline function read() : Int { // FIXME: implement disambiguation handler; // __read_0() : Int; // __read_1(buf : Bytes) : Int; // __read_2(buf : Bytes, s : Int, len : Int) : Int; throw "NotImplementedError"; } // modifiers: inline, private inline private function new() { // FIXME: implement disambiguation handler; // __new_0(); // __new_1(file : String) : java.io.RandomAccessFile; throw "NotImplementedError"; } } // modifiers: inline, public inline public function getComment() : Comment { // FIXME: implement disambiguation handler; // __getComment_0(link : Int) : Comment; // __getComment_1() : Array; throw "NotImplementedError"; } // modifiers: inline, public, throws JOrbisException inline public throws JOrbisException function new() { // FIXME: implement disambiguation handler; // __new_0(file : String); // __new_1(is_ : InputStream, initial : Bytes, ibytes : Int); throw "NotImplementedError"; } // modifiers: inline, public inline public function getInfo() : Info { // FIXME: implement disambiguation handler; // __getInfo_0(link : Int) : Info; // __getInfo_1() : Array; throw "NotImplementedError"; } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/system/000077500000000000000000000000001454362722700254165ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/system/AudioSink.hx000066400000000000000000000107431454362722700276520ustar00rootroot00000000000000package org.xiph.system; //import org.xiph.system.Bytes; import flash.Vector; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundTransform; import flash.events.SampleDataEvent; class AudioSink { var buffer : Bytes; public var available : Int; public var triggered : Bool; var trigger : Int; var fill : Bool; var size : Int; var volume:Int; var s : Sound; var sch : SoundChannel; var strans: SoundTransform; var statusCB : String -> Void; var bufferCB : Int -> Void; function doBuffer(value: Int) :Void { if(bufferCB != null) bufferCB(value); } public function setBufferCB(newCB : Int -> Void): Void { bufferCB = newCB; } function doStatus(state: String) :Void { if(statusCB != null) statusCB(state); } public function setStatusCB(newCB : String -> Void): Void { statusCB = newCB; } public function new(chunk_size : Int, fill = true, trigger = 0) { size = chunk_size; this.fill = fill; this.trigger = trigger; if (this.trigger == -1) this.trigger = size; triggered = false; buffer = new Bytes(); available = 0; s = new Sound(); volume=100; //strans = new SoundTransform(1,0); sch = null; } public function setVolume(vol : Int) { //strans.volume = (vol+0.0001)/100; volume = vol; if (sch != null) { //trace("Volume change:"+vol); strans = sch.soundTransform; strans.volume = (volume+0.0001)/100; sch.soundTransform = strans; } } public function play() : Void { //trace("adding callback"); s.addEventListener("sampleData", _data_cb); //trace("playing"); doStatus("playing"); sch = s.play(0,0,strans); setVolume(volume); //trace(sch); } public function stop() : Void { if (sch != null) { sch.stop(); } } function _data_cb(event : SampleDataEvent) : Void { var i : Int; var to_write : Int = available > size ? size : available; var missing = to_write < size ? size - to_write : 0; var bytes : Int = to_write * 8; if (to_write > 0) { event.data.writeBytes(buffer, 0, bytes); available -= to_write; System.bytescopy(buffer, bytes, buffer, 0, available * 8); } i = 0; if (missing > 0 && missing != size && fill) { //trace("samples data underrun: " + missing); doStatus("error=underflow"); while (i < missing) { untyped { event.data.writeFloat(0.0); event.data.writeFloat(0.0); }; i++; } } else if (missing > 0) { //trace("not enough data, stopping"); doStatus("streamstop"); //stop(); } } public function resetBuffer():Void { buffer.position=0; buffer.length=0; available=0; } public function write(pcm : Array>, index : Vector, samples : Int) : Void { var i : Int; var end : Int; buffer.position = available * 8; // 2 ch * 4 bytes per sample (float) if (pcm.length == 1) { // one channel //trace("1 chan"); var c = pcm[0]; var s : Float; i = index[0]; end = i + samples; while (i < /*samples*/end) { s = c[i++]; buffer.writeFloat(s); buffer.writeFloat(s); } } else if (pcm.length == 2) { // two channels //trace("2 chan"); var c1 = pcm[0]; var c2 = pcm[1]; i = index[0]; var i2 = index[1]; end = i + samples; while (i < end) { buffer.writeFloat(c1[i]); buffer.writeFloat(c2[i2++]); i++; } } else { throw "-EWRONGNUMCHANNELS"; doStatus("error=badformat"); } available += samples; if (!triggered && trigger > 0 && available > trigger) { triggered = true; //trace("triggered"); doBuffer(100); play(); } else if(!triggered) { var bst=Std.int(available*100/trigger); doBuffer(bst); } } } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/org/xiph/system/Bytes.hx000066400000000000000000000001571454362722700270500ustar00rootroot00000000000000package org.xiph.system; #if flash9 typedef Bytes = haxe.io.BytesData; #else typedef Bytes = Array; #end autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/test/000077500000000000000000000000001454362722700233125ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/test/TestPlayer.html000066400000000000000000000016211454362722700262740ustar00rootroot00000000000000 Testing Ogg player
Headers: --
Status: --



autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/test/player-intf.js000066400000000000000000000474251454362722700261160ustar00rootroot00000000000000/* anOggPlayer JavaScript interface reference implementation */ /* copyright (c) anon-e-moose, mico.drive@gmail.com, 2009, all rights reserved */ /* this file is released under GNU LGPL v. 2.1 (or later if permissible under law) */ /* Global Vars */ var isIE;//set after first call to any interface function var oggPlayer="haxe"; //set to name of flash control object. set automatically by this ref. interface. var oggStatus=""; //status storage var, useful. /* Events */ var doOggSongBegin=0; var doOggState=0; var doOggBuffer=0; var doOggProgress=0; /* Helper function */ function getFlashMovie(movieName) { isIE = navigator.appName.indexOf("Microsoft") != -1; return (isIE) ? window[movieName] : document[movieName]; } /* Commands */ function oggPlayURL(str)//play an url ending with .ogg or .mp3 { getFlashMovie(oggPlayer).playURL(str); } function oggStop() //stop playing and discontinue loading as well { getFlashMovie(oggPlayer).stopPlaying(); //btnSetBufferState(0); } function oggSetVolume(val)//set linear volume to 0-100 { getFlashMovie(oggPlayer).setVolume(val); } function oggPause()//toggle pause playing but continue loading { getFlashMovie(oggPlayer).pausePlay(); } function oggSeek(val)//set seek position from 0 to 1 (floating point) { getFlashMovie(oggPlayer).Seek(val); } /* Callbacks */ function onOggSongBegin(str) { //called once when new stream arrives. //str is in the form 'tag="value";tag="value";' and contains the stream details. /*BAD example handling: str is not html-safe, possible exploit by inserting html tags in ogg stream header*/ //var display = document.getElementById("hdr"); //display.innerHTML=str; if(doOggSongBegin!=0)doOggSongBegin(str); } function onOggState(str) { //called by player when state changes. //"loaded" when player initially loads and is ready. Don't do anything until loaded. //"buffering" when stream begins to load //"stopped" after stopPlay was called //"playing" after oggPlayURL was called, and buffering completed //"streamstop" after ogg stream/(or file if playing a file) ends //"error=$text" after some error happens. //Text may be "underflow", "ioerror","securerror", "badformat", "unsupported_format" or somesuch. oggStatus=str; /*example handling*/ //if(str == "streamstop")btnSetBufferState(0); //var display = document.getElementById("stt"); //display.innerHTML=str; if(doOggState!=0)doOggState(str); } function onOggBuffer(val) { //called by player on buffering progress. val is 0 to 100. /*example handling*/ //var display = document.getElementById("stt"); //display.innerHTML=val; if(doOggBuffer!=0)doOggBuffer(val); } function onOggProgress(loaded,played) { //called by player on progress //values for loaded and played are 0-100 /*example handling* var prgBar=document.getElementById("loadprogress"); var plyBar=document.getElementById("playposition"); prgBar.style.width=loaded; plyBar.style.width=played;*/ if(doOggProgress!=0)doOggProgress(loaded,played); } /* Reference visual interface */ var playerDiv=""; function initEvents() { doOggState=onStateChanged; doOggProgress=oggSetProgress; } function injectPlayerObject(parentObj)//do this only once per page! { var playerWidth=400; var playerHeight=400; var injectedHTML=" ";//make css style from it injectedHTML+="data=\"AnOgg.swf\" type=\"application\/x-shockwave-flash\" "; injectedHTML+="class='player_obj'>"; injectedHTML+=""; injectedHTML+=""; injectedHTML+=""; injectedHTML+=""; injectedHTML+=""; injectedHTML+=""; injectedHTML+="" injectedHTML+=" <\/object>"; playerDiv=document.createElement('div'); playerDiv.style.position="absolute"; playerDiv.style.top=0; //playerDiv.id="playerDiv"; playerDiv.style.left=0; playerDiv.style.zIndex=1120;//higher, higher! parentObj.appendChild(playerDiv); playerDiv.innerHTML=injectedHTML; } var ActivePlayer=""; var UrlsOfPlayers = new Array(); var oggPlayList=new Array(); var ActiveURL=""; function injectPlayerInterface(parentObj,IntfID,playURL) { var injectedHTML="
"; injectedHTML+=""; injectedHTML+="
<\/td>"; injectedHTML+=" "; injectedHTML+="
<\/td><\/tr>"; injectedHTML+="
<\/td><\/tr>
"; injectedHTML+=""; injectedHTML+="
<\/td><\/td><\/td><\/td><\/td>"; injectedHTML+="<\/td><\/td><\/td><\/tr><\/table>"; injectedHTML+="<\/td><\/tr>"; injectedHTML+="
"; injectedHTML+="
<\/td><\/td>"; injectedHTML+="<\/td><\/tr><\/table>"; injectedHTML+="<\/td><\/tr>"; injectedHTML+="
<\/td><\/tr>
<\/td><\/tr>"; injectedHTML+="<\/table><\/td><\/td><\/tr> <\/table><\/div>"; /*var cntrlDiv=document.createElement('div'); cntrlDiv.id="div"+IntfID; parentObj.appendChild(cntrlDiv); cntrlDiv.innerHTML=injectedHTML;*/ parentObj.innerHTML=injectedHTML; var playerBlock=document.getElementById("plcntr"+IntfID); var sideHeight=playerBlock.clientHeight; drawSide(true,sideHeight,"lside"+IntfID); drawSide(false,sideHeight,"rside"+IntfID); //buttons drawButton(PlayBtn,"play"+IntfID,"doPlay(\""+IntfID+"\",\""+playURL+"\")"); drawButton(ListBtn,"list"+IntfID,"doEnlist(\""+IntfID+"\")"); drawButton(StopBtn,"stop"+IntfID,"doStop(\""+IntfID+"\")"); drawVolume(vVolume,"volume"+IntfID,IntfID); //associate UrlsOfPlayers[IntfID]=playURL; } function playerLoadConfirm() { //alert("test"); playerDiv.style.top="-400px"; //playerDiv.style.display="none"; } var nextSched=false; function setModeStopped(stoptype) { oggSetProgress(0,0); drawButton(PlayBtn,"play"+ActivePlayer,"doPlay(\""+ActivePlayer+"\",\""+ActiveURL+"\")"); if((!nextSched) &&(oggPlayList.length>0)&&((stoptype=="streamstop")||(stoptype=="stopped"))){ nextSched=true; setTimeout("doPlayNext()",50); } var display = document.getElementById("stt"); display.innerHTML=display.innerHTML+":"+stoptype; } function doPlayNext() { if((oggStatus!="playing")&&(oggStatus!="paused")){ var display = document.getElementById("stt"); display.innerHTML=display.innerHTML+":[playnext]:"+oggPlayList.length; var PlayerID=oggPlayList.shift(); display.innerHTML=display.innerHTML+":"+PlayerID; var PlayURL=UrlsOfPlayers[PlayerID]; setTimeout("doPlayNextTmr(\""+PlayerID+"\")",500); } } function doPlayNextTmr(PlayerID) { var display = document.getElementById("stt"); display.innerHTML=display.innerHTML+":[doTmr]:"+nextSched; nextSched=false; doPlay(PlayerID,UrlsOfPlayers[PlayerID]); } var oggError="ok"; function onStateChanged(state) { if(state=="loaded")playerLoadConfirm(); else if(state=="streamstop")setModeStopped("streamstop"); else if(state=="stopped")setModeStopped("stopped"); else if(state.indexOf("error",0)>-1) { var errmsg=state.split("=",3); oggError=errmsg[1]; if((errmsg[1]=="underflow")||(errmsg[1]=="ioerror"))setModeStopped("stopped"); else setModeStopped("error"); } } function oggSetProgress(loaded,played) { var loadedBar=document.getElementById("pr-ld"+ActivePlayer); var playedBar=document.getElementById("pr-pl"+ActivePlayer); var emptyBar=document.getElementById("pr-em"+ActivePlayer); if(played >= loaded) { loadedBar.style.width="0%"; emptyBar.style.width=(100-loaded)+"%"; playedBar.style.width=loaded+"%" } else { loadedBar.style.width=(loaded-played)+"%"; emptyBar.style.width=(100-loaded)+"%"; playedBar.style.width=played+"%" } } //play/stop command var vVolume=60; function doEnlist(PlayerID) { oggPlayList.push(PlayerID); } function doPlay(PlayerID,playURL) { if ((oggStatus=="stopped") || (oggStatus=="loaded") || (oggStatus=="streamstop")) { ActivePlayer=PlayerID; oggPlayURL(playURL); oggSetVolume(vVolume); drawVolume(vVolume,"volume"+PlayerID,PlayerID); drawButton(PauseBtn,"play"+PlayerID,"doPlay(\""+PlayerID+"\",\""+playURL+"\")"); ActiveURL=playURL; } else if((oggStatus=="playing")||(oggStatus=="paused")) { if(ActivePlayer!=PlayerID) { oggStop(); //put this on timer? ActivePlayer=PlayerID; oggPlayURL(playURL); oggSetVolume(vVolume); drawVolume(vVolume,"volume"+PlayerID,PlayerID); drawButton(PauseBtn,"play"+PlayerID,"doPlay(\""+PlayerID+"\",\""+playURL+"\")"); ActiveURL=playURL; } else//pause { if(oggStatus=="playing")drawButton(PlayBtn,"play"+PlayerID,"doPlay(\""+PlayerID+"\",\""+playURL+"\")"); else drawButton(PauseBtn,"play"+PlayerID,"doPlay(\""+PlayerID+"\",\""+playURL+"\")"); oggPause(); } } } function doStop(PlayerID) { if(PlayerID==ActivePlayer) { //oggSetProgress(0,0); oggStop(); } } var PlayBtn =[[2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2], [2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2], [2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,2], [2,0,1,1,1,1,0,0,0,0,0,0,0,0,0,2], [2,0,1,1,1,1,1,1,0,0,0,0,0,0,0,2], [2,0,1,1, 1,1,1,1, 1,1,0,0 ,0,0,0,2], [2,0,1,1, 1,1,1,1 ,1,1,1,1, 0,0,0,2], [2,0,1,1, 1,1,1,1 ,1,1,1,1, 1,1,0,2], [2,0,1,1, 1,1,1,1 ,1,1,1,1, 0,0,0,2], [2,0,1,1, 1,1,1,1, 1,1,0,0 ,0,0,0,2], [2,0,1,1,1,1,1,1,0,0,0,0,0,0,0,2], [2,0,1,1,1,1,0,0,0,0,0,0,0,0,0,2], [2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,2], [2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2], [2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2]]; var PauseBtn =[[2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,0,0,0,1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 1,1,1,0, 0,1,1,1 ,0,0,0,2], [2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,2], [2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2]]; var StopBtn =[[2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,1,1,1,1,1, 1,1,1,1 ,1,0,0,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2]]; var ListBtn =[[2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,0,1,1, 1,1,1,1 ,1,1,1,1 ,1,1,0,2], [2,0,1,0, 0,0,0,0 ,0,0,0,0 ,0,1,0,2], [2,0,1,0, 1,1,0,0 ,1,1,1,1 ,0,1,0,2], [2,0,1,0, 0,0,0,0 ,0,0,0,0 ,0,1,0,2], [2,0,1,0, 1,1,1,1 ,1,0,0,0 ,0,1,0,2], [2,0,1,0, 0,0,0,0 ,0,0,0,0 ,0,1,0,2], [2,0,1,0, 1,1,1,1 ,0,0,1,1 ,0,1,0,2], [2,0,1,0, 0,0,0,0 ,0,0,0,0 ,0,1,0,2], [2,0,1,0, 1,1,1,1, 1,1,1,1 ,0,1,0,2], [2,0,1,0, 0,0,0,0 ,0,0,0,0 ,0,1,0,2], [2,0,1,1, 1,1,1,1 ,1,1,1,1 ,1,1,0,2], [2,0,0,0, 0,0,0,0 ,0,0,0,0 ,0,0,0,2], [2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2]]; function drawButton(whatButton,whereButton,whatOnClick) { var i,j; var contents=""; for(i=0;i<15;i++){ contents+=""; for(j=0;j<16;j++){ contents+="
<\/td>"; //else contents+="<\/td>"; } contents+="<\/tr>"; } contents+="<\/table>"; var mydiv=document.getElementById(whereButton); mydiv.innerHTML=contents; } var SideRound =[[9,9,9,9,9], [9,9,9,3,3], [9,9,3,0,0], [9,3,0,0,0], [9,3,0,0,0], [3,0,0,0,0], [9,3,0,0,0], [9,3,0,0,0], [9,9,3,0,0], [9,9,9,3,3], [9,9,9,9,9]]; var SideRect =[[3,3,3,3,3], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,0,0,0,0], [3,3,3,3,3]]; var Side=SideRound; function drawSide(isLeft,totalHeight,drawWhere,colorCode) { var i,j; var contents=""; if(!colorCode)colorCode="c"; for(i=0;i<5;i++){ contents+=""; for(j=0;j<5;j++){ if(isLeft) { contents+=""; for(j=0;j<5;j++){ if(isLeft) { contents+="
<\/td>"; } else { contents+="<\/td>"; } } contents+="<\/tr>"; } for(i=0;i<\/td>"; } else { contents+="<\/td>"; } } contents+="<\/tr>"; } for(i=0;i<5;i++){ contents+="
<\/td>"; } else { contents+="<\/td>"; } } contents+="<\/tr>"; } contents+="<\/table>"; var mydiv=document.getElementById(drawWhere); mydiv.innerHTML=contents; } function setVolume(percent,PlayerID) { if(!PlayerID)PlayerID=ActivePlayer; if(PlayerID!=ActivePlayer)return; vVolume=percent; oggSetVolume(percent); drawVolume(percent,"volume"+PlayerID,PlayerID); } function drawVolume(fillPercent,whereVolume,PlayerID) { var i,j,c; var contents=""; for(i=0;i<15;i++){ contents+=""; for(j=0;j<30;j++){ if((j==29)||(i==14)||(i+Math.ceil(j/2)==14)) { c=7; } else { if(i+(j/2)>14)c=6; else c=0; } if((j>fillPercent/3.3)&&(c==6)) c=5; contents+="r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"
<\/td>"; } contents+="<\/tr>"; } contents+="<\/table>"; var mydiv; if(whereVolume)mydiv=document.getElementById(whereVolume); else mydiv=document.getElementById("volume"+PlayerID); mydiv.innerHTML=contents; } function getAbsX(element) { var iReturnValue = 0; while( element != null ) { iReturnValue += element.offsetLeft; element = element.offsetParent; } return iReturnValue; } var volDown; function getEvtSource(event) { if(event.srcElement)return event.srcElement; else return event.target; } function getEvtCoords(event) { var posx = 0; var posy = 0; if (event.pageX || event.pageY) { posx = event.pageX; posy = event.pageY; } else if (event.clientX || event.clientY) { posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; } var retval=[]; retval.x=posx; retval.y=posy; return retval; } function onVolDown(event,PlayerID) { if (event.preventDefault){ event.preventDefault(); } else { event.returnValue=false; } setVolume((getEvtCoords(event).x-getAbsX(getEvtSource(event).offsetParent))*3.3,PlayerID); volDown=true; } function onVolMove(event,PlayerID) { if (event.preventDefault)event.preventDefault();//dont drag image else event.returnValue=false; if(volDown) { setVolume((getEvtCoords(event).x-getAbsX(getEvtSource(event).offsetParent))*3.3,PlayerID); } return false; } function onVolUp(event,PlayerID) { if (event.preventDefault)event.preventDefault();//dont popup else event.returnValue=false; if(volDown) { volDown=false; } } function onVolLeave(event,PlayerID) { if(volDown) { //volDown=false; } } function onProgDown(event,PlayerID) { if (event.preventDefault){ event.preventDefault(); } else { event.returnValue=false; } var SeekPos=(getEvtCoords(event).x-getAbsX(getEvtSource(event).offsetParent)); var SeekPossible=(getEvtSource(event).id=="pr-pl"+PlayerID)||(getEvtSource(event).id=="pr-ld"+PlayerID); if(SeekPossible &&(PlayerID==ActivePlayer))oggSeek(SeekPos/100); } autoradio-autoradio-3.6-4/anoggplayer/anoggplayer/test/player-style.css000066400000000000000000000036761454362722700264720ustar00rootroot00000000000000@media screen { body { margin: 0; padding: 8px; margin-bottom: auto; } /* player engine */ .player_obj {position:absolute; left:200px;top:0px; } /* player interface structure */ .intf_div {height:29px} .player_outside {background:#dddddd} /*set c9 to it, also this style is not used */ .player_inside {background:#eeeeee} /*also set c0 to it */ .player_controls { border: none; width:110px; font-family:"Times New Roman",monospace;float:left;} .player_tbl { border:none; width:100%;} .player_row { height:25px } /* intf_div - 4 px */ .pl_1px {height:1px} .pl_sep {width:5px} .vol_sep {width:6px} .pl_btn {height:16px} /* all buttons + volume must fit inside the player_controls table */ .pl_btnrow {height:16px} /* button row, change if making bigger buttons */ .pl_pr_env {height:8px} /* progress bar - envelope, player_row-17px (that's button row+ 1px below) */ .pl_pr_tab{margin-top:1px;border:1px solid black; width:100%} /* progress bar - table */ .pl_pr_progress{height:6px;} /*progress bar height, envelope-2px */ .pl_pr_pl {width:0%; background:yellow; } /*progress bar - played */ .pl_pr_ld {width:0%; background:blue; } /*progress bar - loaded */ .pl_pr_em {width:100%} /*progress bar - empty */ /* drawing colors */ .c0 {width:1px; height:1px; background:#eeeeee } /* background / transparent parts of player */ .c1 {width:1px; height:1px; background:#000000 } /* button glyph color */ .c2 {width:1px; height:1px; background:#707070 } /* button frame */ .c3 {width:1px; height:1px; background:#0000A0 } /* player frame */ .c5 {width:1px; height:1px; background:#F0F0f0 } /* volume empty color */ .c6 {width:1px; height:1px; background:#F07000 } /* volume fill color */ .c7 {width:1px; height:1px; background:#303030 } /* volume triangle color */ .c9 {width:1px; height:1px; background:#dddddd } /* outside of player frame */ /* cursors */ .tbtn {cursor:pointer;float:left;} /* button table style */ .tprb {cursor:crosshair;} }autoradio-autoradio-3.6-4/anoggplayer/downloads/000077500000000000000000000000001454362722700220155ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/downloads/AnOggV2_test suite.7z000066400000000000000000005221611454362722700256620ustar00rootroot000000000000007z'-$dS!Ƌ(n٢ԋ"Z1%&:23W I6/]k= gٯ>8>.=C]Bc'ʻ1kq`[~]"pFH^Hcg?ya5='NoI8L52)Ş q}*q{inHk1o&=L})eR&prۊ_D 5=ɽ Tƽ8j/@A1QO #G?1X4B2fQV@1n]fڍ%6ew9lNf,ʸ]B]FY(Yz%뫐%1S3ޠ~ 5Ú?>P:Q?O9F3\N#jepKIփ +)7(@Q@F7 &U6!Y=.RV:u|L:xWet}֝\uޤ/)_Ht:B}=&syFΦ\6|ruǘgDW4조MR6^ C{W-tBuIr)d;U:dڑQ Lnvźe\[YSjuSo/GZI]fq)Yjehf !㚪xc%Pq EAw< HUě6gOљ&l-g?RY&psEfOA,&jqE#Vb50‹s-r C(Y GQ;fx u&yv5ᚏ|ЬlUP+69q)lJT4!f ^EnY-W1΢لkQ![wUfӨ:=}н}ـ}#^F9 ]'Jb^U62(@MP2i+'-,|tZ8j7ixgll?7 QK֞LS9d{W2Ё˜$dC]TЮ;Zgܝ޿}Q^KqykYNצ69i='qAh/1Uuɀ0Ikc&LU%TQxI6m؍C9 z!&aת/\atWĶSY.9_Q]"=4h&⥯!zoN9ؿıvu0_ӈ[_>{)bL-R[6ԃ@F'& 4ML,9fҷ;3 X jʏ9RiG {|uIBz 2:gv7JF&g9?l& HA|0ZC8f^[[L|5Cٻ7у/ BhkuY17:`Nw)*2%pj>^L?i,R {nsWcC")r@ok:kePY4tެ~ѯIռ~)\䘣}F%"^jg}%JK+;ьB3Y"4 TL\V[̧ĵ)B/ݙ/] -Ww%0gagj p >J%a'G/%sdWzZ%g"Z-Єs4q:V"%L\Dq^o8ž H1 Y[WXr }n@E^x@/{*c<<+c(V.MD6M7էOX>qz+o )תԤRJbVy֢HykdFk R_2o/o5tB1U0oMw` FO6 x}*@\_n>YR+-@E\gV%[l5$XB=K//[:ו܅!x7aVG X~mݧ#G k8KN} v.6ݗq:g,5KSt@gKzG'S.fkr2o 5% a Ap0>ܑvkrDjY{:) fQߔ48a#7e Ql>F׉ : OJ(fљf02YC+^4R}NLǻcEdA =|}]"ʬgP "޾c KbZheBx⼷ZCqUEowa{Q'%?8HB!\JQ^W{;D|#*uwb6;*-JRE5_]dV]<@+6jq=!:79plt GVȃ>4Lݤ?锥"!.;CBAm}#8fa1|r E\< %4P\hU< i ZTBOYvԷ7l!}dRwI)I[1›] 5 a']~E1ڋ|FMQFY&ybX] VGC 'pڒ9J3E$>ocFBM;8J.ܪKsSl*_D\'OC(`}j2P̤W!tIj'ȐB21 q\(qKL!\;?o$Pt)+56 ,)]2\Boٹ"= r_`y[O?lm7K$/,e򯕏[sLEnQ˔s:{Pq:"JI4fHp9u7C ~\H?Tx,-&܉S1igs|ݷ( bni0^JW[QCjFՁt~g!~T+#!V}Cb } P(J(`$i܅w|NhsFߏ{im2+R/R Y!RujZmQsz=/Ujèx? 9];Ʃ#k=MŢeWV:-UBy2l>#U؃:ZTnS4"cuoC1|wq[|s 6*]D.dUHYX?;zҚ?,,zăd=R\wV7n4EhC;r92!"E|?YTs`n}yErvp@g EDMuDE5W^ޤmh%B9# {i\fc&M[qnvrjt%Ǟ{QPr%~Rw3s3'ˀĠ@ T?LsݤW*8TJ> V)Հp,0, rp _(bDvL)y/ 6BtxbI'[!;PT--ƫPۯkb{Ù}Tid*P63Xi^B5dTiZ0;8d.Ѱ(.`QiL*{Pq4>zr^ӏ:[.n_IM!ߡ ?R' ΰ.g4|C Ԍ Tc8x!{zaEeQhB勁x}f*zrmR,*ʆ0dWzL9^q@b9TH=uOSNb[z\_$*GkJY ,7JnU]sO=;;xUvJY&I3Y5*1Py[a8&#lЬѥF 45:U,t%*` {]}>c$QRqAhlVV \_]84H`蚔|"+7gJ̋ JJ܎ZC5M`Z:cxtcK>},$#Cװ̬<q4~&f\gx=5$4!g3 jFjh"J"To9O[S3(`E~K0ƔwD" IY4-!IDdф'wa-gޱ^]fQgω5A p^=!ckj[ F1ꖉt⠟c){$xTؔd~ޯ≥x?*oP(5Q<3P jrmמ&2^@`-{GPgl6WI3]9W$bAgvK:Eo} E)2˙/%Q,50zlϏ)I=w _!s̟VڹՆv}9{(DH i톐i|w$GF_'Kd ƍLBZ=ms!CBVW,h8xtYsWt7NFMC[0,Dvܯ޺oIevZ4k3C+{ICr/xAdxM/NZq@)]B4GgϨ 9jn,N6fJvO4`3POw WNa YD<^wA\i0V|b|l8 =e)o w8mi!Yq,Ǒ'qj Ml;6lDlo&ÿvHJ,I)"3 0iCQϞ&Yk4nCq`a\*MU%UBϛiɽACk/zxH3iUWE1@ħNƒYlil][.:t/JWm8艳\;!m>( T_ |{_Wۍ?M"+Dhq0 e MѺ] T,i:2LR xr#J> l`!.}rYfbyZhCjݗB?C;p:_YssFcR"ڤgj7ᡫk ȁ!Y礢SF-n%m.禙8zwLc^,}.^qUt~sQQkCN@36n\򾤅= yAR1ӗ˼P FݵCnTZQ [anϐJV} t{(؆)TO0 ln*r3GH;tЗn*5GHmXfS;ni@$xȒ%L+Ij_ʼng nǔŤbSY8 >#dNw ?] cبpPo߆.utƸ3?3&.XE\FWyB"RM 3ԋa]X@択P lh nƑ B.W .l %5OkMDFݟΐeGUڡT^grq+A XD\tWZ_%Aw̷ٵ!tdH^&/9iLog)S,/p%@Fb)98 _^ieeVQ,2䵳t|PHF;齽x9?} jc6M,~Yvw5>S)M*(ܿEK:[MJZ` V}\=_9YDbS>Ŕɇ!.m牞(,HG~hMāO PVG{Gp89S:CL|3S[b!!T·.aǖ+RxGY/~?ȝ2;Q`Uʀ=]-vrl4fP"7ӭnS$XW0u㉉XGK#pJgx6`A®7Ţ'ۨY$# aclC嚊nqK'H2Um6< V6UKS8$;N '8M7gOM̨>hNS.'&zM;d,Q;Lⴜ%60am2,$;,$ȭR[^he@wyG.Ey@g{&h{#JSnnQ(8@{Ex2ņOv r&QѶx-y@%Z fd>(Z6 mn4Y~a^JɼN49$Ɓݢ@ <&H'Nč}zjypj\ffEnxK!-+ơF'8tH[Q^O=Y b8,N<ݲۘXd>- n2(Zx7.dFR@KTI7y3pa% Wހ}[+9FU5 𐭴 ?G'-=5l3V墧6d ~©CMk`;IIk"Fo@U^af n`]z{?d`7(eXw!Cѷ9@BMbGP!LL~ he(;&0+{@ mzn:OU=Z9D V6# jTy\cc6{R+sYգ3fK h4f5"-xpޮ^,f CܽwcocPc2viTk^C<= }ey,s"bqY9&&T:4Wn,y=2YHM8Xՠ {^TgI!}2l"TN$XM= /B%Jg9[s~󋯸ɖ=rCW3{U(i.2ryx0܃*Zwr(%vcL14+2o,ɲEN47lbpv8rYv Ia,X%:$k| ŸJk΃i6mM283slȫfMC?w:it7aRTTG=()( $}fjflƥ#l/ΑIȰh^ƠQ7/F\&;Z&ή̇ZFnFMxR`=0Z\ya)`XMa7 n_\iDQJ*tpbAd2݊'!N3,zh߅1s!Ą7fUښf/˜q%P#k?.4# ulvGBI?tSԊ7jk@{`~Qɰ l/J{eOع[л8Nz`6봁N~udK)_mO1@R$vrT#O\? S$}سA"nR`o`>AO55#0"q&){P,#5͑NG-|LϼQm"!93e"d]>^o)^ƌlrڃB$ fJ6,戒u Hݜ"cZ ܜ)ݕRa$V6GV3GW엖U@a<Qp&ec,.x]]݋Oc+V^dy6JI tΌH;=X^EHX̝qw|ıGe'btiE鍙ǿ\ןtVV+2b^RNOptD}Ol#Qdh ?01uL5: e \ XP$GC߾^#[-af*"/hH ]9z126^% 4h!LNl,{$z |ny[B?ALƁ <B w:}*x-jxkz$@UЁ5+'{SUIZ Q6-Rs*iMuT Qwz}kx>t2q v玉◃i5iO7dOV:;ڒƭpE1l炍v>g-HJRW  >Vq. {ʐ(#&Џlw 9%7I2 -NR9UDg _20I#HPYfzNq֤Z;6.ibDZxJoiϑdM xCbJ"wMq0 ؟?u@o@]u\S!V-rSV{_`練`M&:6gncU fqJ =Z=I=a.im7?1kfgBO6WwkK42عxєbf`;Mj5"(CU;|Oo`ʷwh8+ ͜n i33ַ(yu-wgnN >@&4o( t Dn~wMj*9`-;[2LX9MȦSw>܉ y7ؑ m_9JdߩCA2*1=z=Yx!޲䝒|]5ҷ#f#ʦ}Ea'ͽ ^2Rޗy\(#8@D)VB4ۛ#a3>p:=7h#-,t q Ya8I? 5Ւy.2p4kԡLapQmtޕ)9܇Ңɑ VBv_=j|0aƘ˨ND! Qۋ5F̖e'3Y4lQRG_,zB3j߼w) 3p{UwWO@^ 4I'X' N #7Jc"JwMx9'(qX[4S 2zer_ʹ_^;i2TZ$XxFٌu+lڥ6꧁mc:èS(|RhV Rץ?Cn ~(8Q'V9G'߼ էZ:_BNg0ػZф"üeaÒ#ɚcg2960bE((RΓMa Uxa!+Cs=h%,/ՠ4v V6# V)Tc-x nUf়ήѫ337,e.k!_}DCg0|꣔,v?S?o_Ribn:P|IՕfÈv)D=o9* !blhhء6D:5?8%.HWԗj/; $+o?%FjpQ gtVݤ0C+4z!1^#,k~f%FJ.cnbq'(U2:tDv.j#]=ZfVlE5j`tMz (}5S2;y5rm&{.`YՈĿJ!uWlӕ;] {*fD#󮀴E]z6xPȭΑJ"ܱ%N9_ucU2 AfLĹ/aQkt5.Y}XD mT}L/߭z)#Aa*hMr!J$|<PlRXݵIi|%e@TQf dK@ Mxy!ˋ9j8<FԗwAw(d+e5:qHPU?֍ (bq4EcN 7|-jߗ94Ը,X4g7k1w\H[]{b}TЮIڭQ͂C6\4ۏ=8$>Lף)~u|,x'?t b}62a|0;Ї.0}|ӷHuh Y +ʘ뫱a2:๦z`N{`q2# c=ǜ6,{!sL H.CR8R7 ,YIvQ\d ~zio`5ݹztKEɬ*pvic[\1B+h=wq0sDM( Mc`y_Zz^h|b!v8D.fGPzu[n |<uުa$@֌;λ)0`sn;ϨoIzkU+Q^ 5Ѕ?@g9|娹JS,ތĈv=3¦4S7a'٤&P bb/ȑR-`=<mэ($UuyϚn˝S8 ]XݲlZ5a3J*G$Gx|`S|yҎTAorӅqCL tZ 𞤸ju7wi=R~?wV\:,RxT%x8+ e>_6R 4*9{] Cctq]XΚj,6YG-ʆEߣj4 =*wJH5ZFJ:sw`\ˡX 8QOlj!8qfc%+(cYMp>db*7`~qjka% `1p@ :JϏX)oO=Ys:.mݣHݦ6~|M${uZԬ)SCRA5кZMҐyZ! Ο/}I[1w\ڮ+|BGI^3+JNЏ~T3`] RT EL#:"W#bx< "1_=i,t*z/ެ3~ݴ@_3^elcdžي9qij-E.4t1ip~ѐqGcr*$ 7[7sܼcZ r='Ou`ۓobxy˝{!Mr9V6Y9 V62AIcY0T(KB8GRt:c!r 9.+Bގ|_ T~Yo b6 G@rtR(f7`DtakWyj] Dvo吱oqe- N{w L>:m,(PaH0-h&?ܜ# iTI#Jx=fits0_5ksgcb˰_¯>G24*`q2`@.6gMdk˔ZP勏~{.-̛?i[A(T3nu΢-+Ҁ2XYw^{¨gOEiY%)+mQ:ώ©OMUʉI܊{rY܇ +APh@:'^Rejc.=#[;P8-MvUP~<3DXdf АBIzn3sv:]~z"c*@]%rF eӪ!"d 9$qAR~6Oj"c${w U˦6scq5d IC ב쥍.G%:,t'"l'+sĵ1<9yQ8JLşR uG`d PA0!Y4*g 6ķn RK EÏe_3>?yj1ڽ`K48PzɪH%4'e }:V<?SU6j 4Ąi{F2dBSNe(MIgjo7wlr u#!ԾQewMYYZygB-> sIǸT\b 2) #X\ mxwμw;QI9+#*rޢ1jo/+w_#O&&e1y&E~ѻF $4Kj3lA(w 2sw'{5":zc prw)6IiLإ0YkK*RO}9Qhxen^,֢lZMh)2#p\=0vkDa[jLq=*2l0`qزP0EY͑s3o==޴x& (>ƌZJVii}6pj|0?M*6cAk CfƀG\|;P>0!,#XzSP o`Wgt''DD-:B֥\n~.<ϾtGmjoq^2:>S i=~Op>\6`(X G@[PU}(6=B|!7VV4a'GO<M8m(8S>`ܦ9zؽ Nwm4Cc3P3TӁRРg1jÆc+!# yqZ!ˆU1`7#&r@ q: ̛O:ag f)1Mk @O-Ŭh%V‘?ݖ AR8_ʖsyQ1!)QRCg̡}ÐCGφKIǪ\?ch( \Bk k` 4B%:Uz;=X$xX0ܓ ĹBz%1yEwR&FQ4tD ) cH\g'qE'EQrs?ӌegHCX>Fmk3)yuj\NT0ш$l}\5]@uI"/fsuHX.$4_foOûF-$b֦ſ8Yoo܀ե/2 K!0ZUI|)Hk|ɺoGi|`kqm L+͒5^&rh?a펏 %Z :ql>U 4]uy^\C;))q`,mxf<'9÷92Q5e|⎪Bt%H*c_ Sħ)&Ӝq;e=`lP:,W:%nhA NZUu "O?\9_:8ꩶ-A\7-rfQ|JrK,SIƒ)qZ!NJ TQu헑 -@bFVڍ}iCR>;4RKK>4*]\ J o_tk>`(V4ˡ2I_vl0!{? @AqGh#rte?4Λ#Y}s7_MLv;Y^p,1#, ,yy~ .׼kzd~A,m%$mI:#s4~8BބG\,^'o{MHu<;awH qx+ͫJeC̝sd%) fSW{&T1;dlrfDž_}%mP}XD*GOt?njK"˪F ~gJf2.Cu'*A doZ&Glx1L6\t$tۻkfm92 F w@eћFO\=e`<(*M'XW9l"pHG)#2CV+~^_4yX20Y 4/4h,2rQ6)ץ_n^]wc7N#CB@;έ l7WVpчRĿ"H񎐳:ƓLI҄x>1eSI]NY Ym{27"#aJM__k7gmq$ǟeP`lz8YĈ29^?!E3Fmm:*HI8,{~Rm'UI 6mmVop^6Y1O=;+sgg 7ec6xeK<Ȅ>CII/"5"q{k7ɁxZ? _АMVCnQinâUuP^$AHm^)~-4h*LQ$+ž!T][l9ǦiX Y^t*6e?v~UmKEnoOcvEl/%,>p)`{w^sNѺ-< h(]l~24ӏBϊCN뼙)k8 Y!NW0žm85O}@aT-70Sn\|@ީ ëBu\9>y8e#6|s]~5EY q Enɢcs8\9cp ^\; ـDGYv O ~*E 'P1 A%ĴO ^Ib 6O={>fi t(_U%$|/K=p[ M~eFTD+0@ͭ[oԄ"j[pr\$(![LZ,TE/өVgҩ$A07g orc9APceclLϗ,[N==xWc DZU̓Cѫ)l` 2A'4ǡZ$Ybs^^yzf BNv~C--4kC *ܽ^׉xӇJ-Eyl uM4o& n1P7C% 5sӐd@M8[+6.79%S!%iL 5֪90*t})v]0]CxiȎK eFeg$f4 oZ?HA,/SI ][܉6),)Xhf#4hNل4bwYժdTz EVo\w7ʱm5r Uݾ W;|F k!IBxJpBi况ؤau3f|5n|qKaPr@V܉-.CF*d`Q&$p#+4JccLD(ә!"ljcaY}'RFx4@vVOڌqKuǗ {Lˢ 'F.j/?#=jh3-̣t[68"J q3 ?骍6:>J)wLUn_}ͤd0# Oȱ쎍c Q*_ֱ*eOdv)Hٹewaav{+W(:/ L[DDDBSmˀ]9RGhB=1ة&>_0E8e!|fY|S쪅*beO{P,GqY[VL>gM򇴾Xؗb:q?E@CSA6T Ά-΀d*u=EFszjGS6PRt5m0͘c9 e]`ا߸?WR0͋蝼ȶ' tk@ǟE_˪*6oex*Hw8, 7O5E_B$DX}xX@ _<9v֟i967G!Pu I O=.tx`h[v$ T^*~hu]uA ɿ(=,JVYmݰO\zs_7o;-[l Q pT휖4Y-gdi;Nr2T\4k㔀O>wsNC_-#<dHPI[hv[`=t<`M }z-t \" 9<2'Kf V(1^gw3G!D#Ė)0 K=fom F=BcvB4s ݔMPR ?e Ex-DPQ}ZCwV 4*x oT5-zY\ F ,{A醆Kq)VܑX+@4Hv̬"쎭*ܘ<,hY-8\gAwn3L'@.V&jT4jy&SLpwie君Hw=~\Mͷ_ʎ ߐeن%Nb3*h((i^t˨I!n"b?2Xf`~`1S<䎑bf/D.hρ ϡ  PR/Jh&!#.' M6e!nH6NeS>{6Ұ% ֣Gđ0b( E^>d] As-&NtȔ3!pP̞! ȍ ]PFq%3GUL爫tGcHHX4UgJ^Gv7FM ]z Q²h>D/?ol dEOf~TNfiFY)oQ*"o("1Bm~)TbmV|IMus̹wi sm!o/3A,'bCR$r7]~g+kJSQWBX.1 l'_̮O$Eݩ&Oyד,u瑜tYL;diíꅃ AG\3. >rɛI"s0+ VQ3gX$4Y=Ꮜb >Mr+MMl(g *#²:M޽Լl+;UnvOfh!\"Y)|,F:S'A*X-j)q[4}1&h{v#x{L"\>M|cO'!' $Z|?KQbV5Nxs~M`U~cR $ٸ ɋ nw8R,a$ʻkidoSmtQ[!4:EYgΛ.DbfvJB(t[͡~]1ʩ-{pg.pRsE)[DÂ@yYôoM2]SVS:;Sfl=Q+8Oᾝ55?4MtCO!D6xxnA1!QTG=u ׈>*vbnp^kRJi8:Kv`  (M!!WEkx%Ǽ{%K>&Bz>cr54"]_ B1 68elBEr*ㄞRژwH4ut L8mvm8C!l:Thp YkLt1>Zj*rTh6I~El]d'Jq Z;+2jFu}lgle` eA%{mi{"q'>ΰ|eٵ!aU܌yhSG˔#m¸3~ӢRڨ6~ 6(MCnxۤRGSoF7-􉗂",Y*aQ#v(j.KEjQ |<8Ϫ,t}GLHM՛Zx_pKK JuKWA?!u}y&wDRrڲ[:H**U0ُn;.rT^ & 5МfV$֙RT=jD?WOꖩׄ$%e~fJNsO@kˬr,lIEZ>7篾`O,!eq:e/nJ`ye٤B"3Pdr^w=LTIo+*5o-&ٛ4DEHDfF^^mSD(u5|=ͰefL$Qb hY}6LTwf[es4a'lN eDM+25)c$lSYtj]ĵ:¬F_EYilqX U&֭#q]d@_LhGUm˭(Y; ?wAS4K3L&:? -] GR:?`hh ]>G.XCd\%@l|`̝72J]\01[X$x#yEI/azd!}^W̠qP:U&h5T$`;L)Сck/d{sdU^"9)1Wa4M4LXf3J )(<P`˲_- J^Cܙj0耋 7Dx*=\kD WpEpnHo񪅐h[ӥߤn ste-u'SRnκQA$h]?h_ּxzNQYE 4mQ?L^ oŌFGg^˜R8rZe-2Mtҟ%獢3x:4mC1V^"Ilޠڹ |-XjzҎ+ ]6aWXJt!nCXQT;xDPP#?GZ Ôa_V0ýh;v&=P.3sqmLϢ5iLXk f(/;FlWпmSJR4h_gMȓmddr?ɩS%phd07 dN~bؑ헐svTRn/IT2NX)`6wOLp(>\Y} &.JR%P)c!ՠW+O]Ԩ#&M=%ƙ7e5 H䤕g̼8=D_Gɭ6Е-@gd3:pA(j[O@>LL?_S(XXZ;q+T_j/0#`lCE;S,猈8eMe|=L'8w5b.ݳ:荅MnU%u2ǿ.݋P0ҭGN ^N-5ED~bi~9nd-.7W;e-D$˭h/6!V8(1rTMR=OzE`cmgVadkIJnA7) wV46*a“[#SłJPsLjPRՏCqZ&Tya(ƒ-,6V7]#sb1{Bt :Z/UGinxt}5.o`סi4Tk .$'1ܗfFG2\*1WTE=+3TCìk!p]>;f.;Ce|qq'⍿@_kDb^{4Xۑ9ws2 I2jĴI) K:O -gI ?oR7߅"vF2{Xm^-,-v[VC팸e,T+XF۞dh4n#F)c=3h vg=9>ǧTCMEmj?Vi{&>{u;=%̱&{3u YށeZpt'ւS`_بV@?>keFƗoB/YFi-& xx!'Xy,1=K4,wa뇫 AVpQZ*]@`JwW NRԠ7"XC/2A|fwQ^&IfwM^o?F:{;`[&QV[m[A;o[zŜVNypBS/w&i=D Q|p¦ڟ2"[wm(]me9 5o[ t -gp\ B^O rxsK{&Q>v&sOR^x^AXGzY )fE#7y1b>'uY0.n,秞c H*|I%9>wLcq&Eϝyc^IuU ]7nH.q&:y>,&0eHW6ij~E" z*,X1cT#:?ޫOxNVU5 #EtTw=V;^f|&\<½GFnBR]wD1.Vbs;>ljwREM7< uqUo'B3>N`ŹbLgXF-Ш+n n#Z-KjYEvQn"HHNn/.!d~H'֫E} W۫xpƅ}5vj4284cśeBP ,Bx(%4O+v1EBf &$#*!qՎE(A⾅B X}*Ȓ~!w|Âkn%Ye{B[l e~ѣY@_Zշb, D>.xu%^<*EcUBo+zjhH {p?x*JhTS1:nY4ch_f!0z趏q9n䍭NPjQĥ1(ZX$|S*zC@~:lr)AtMN"9С/* qK8C[^Yf}x^eh.Oh[Z_&.+S&8Fh)zrʤ9|G9.2d]y>aɫ㶬Iqafܓu17lmS*+ ʈ(}ZDsv`aRİE=(̩\eLO0C|Oc[lڅZFƒd 4K r4Po7Pvlcvr~kS;^?+zx+sJQ}:~mjRP|0h_g{qrZF Nt7)QyS]4nL)IH-S({W'cF*A xJ꺻̶-`,CēEsֳ.΋vjkN"SJ4Xt\sn-iuƻ~]wAMͷ)@']V!\XqIJ0A v0f}ȗ?'}m0i7TRSOU2;ˎJD{bl~fo?A0ՎH*sV߄2իT2LY opWgW$ (jhL 닽P?qHckl\8J'ىͼb4\̃)71Dv>7qHTJc7[nGhc!3 X)Z'8@8rf·yeB~LVJXt)"9!-&\#mf}mQ<z|^čhuYwc~տy @v:w5}rveH:F"/-E}Gc=s[;}fU3hۆPJ^!VN씺a*f5iLuJx+J'to!ݫk(c<>4F8żvMh/OAW#7L@$/sȌ2PlAlݡᗫkl}%šv+RD!#ə#9@l \P'zHOTn.1h$^(DGbJ19c&5xSL6eYM>. ćqp1 N19nڠU(UJO-#$,S:gB;Fp}[B2j(,To1̤k3A:  >t7%LF8b>pnTs=ezJ(т~ W'!A)Zg9K gHh_x#^N{n\ه8 p9Cx&&T_¥&դLzh9 q> 7Ta'Mu킔eˡGeۜ3;th;?`pJL9}vε;B2^}߯ uc\AiMd_z>si;.l96yMװց6$]N|Я-85m4\p=bтOZ\VNV7ۮ._}ܞAm/m/bSE̔$j8w% eBNʏe]OVWUݩ&S3G>Xl?1B4 )j@QqJU%$VݕXĠ\ Ͻc! c槯dM?bG()(SM B`YkJ6KKs߶nOg^^| =˪OyOYXˌrd#~qA {1ՆU2X9(F4XN3c2K(xNB_9 wiBוPײ X'یw, ʿ 5qأ13 d0DՏbdRt Z@I%dmFUFԘ︄jU^؀?8t5X8?/qur>7JW'm{/UO _8@^(=+`[(в!Vh8I'ֹm&ܦZJMfJGa)P|VA8W1i+{,#rXobUzE]EN\`Qpm Kq1d7'En|#_QHsMEaC֭0Ϡ<|я캹D1!tu*}npxH8?z$Ie #KƉ.Öycm#= cUeLgJTG\2.J>x9D9(2+oS(+g/k?a͕ <tQ3#G!ͮ eVƾdLoۺRi3, wx:šq=,ʎHϢʮ+Z ڧg+榾 LVLi L6 0d % \=3[Yk(a;еVN'aNNq=V2|ўd\)f?)UV 'fQrm O4ZNWLR_f<c<y?H'O5o!a,hfĽgGٞLd`Dux|5-seVhp3g7șg2r/lY-1޹f[ivi"еH(B ̓8~+;"Ҕ?y]ea/)_kw3Mt;iYcgH4ύV:%+4$Yc38Y 4Al/ qeLLz1cX㐱m0b]Յ#W:()C6{ ('l>j5zap.iXJBԤð{^a>U!Vw~ ]G,/=6 &`&1{!肉sW S7TSU1BǫKxMB:,5n.F<b|~WKn7JK|N0 HgYd yyR+UhsFo<'kt͉cV5VUnQsQ"%k6ŊFO]› ^.Ib;s[kk[iǛJnAsW.'zݚu )L 9ʳ/6z8ޘ<$!SpzGJuY54WurxDk 2 _K$TNJ9eiY J0' =7m:FbHT 4OHޏeG l'6:Dw˙{Hзl2P.VGjF9m/X^ 'C 6&RwU;&|! FP_E~1S]z4C:,G*wQ +kZ'؈|+P_%7YVbzYf<ak!^Ȗ(SXԒqs+@)5B^lVAuRbLWx9l}s(;\[]f'RY+hߟ%}/5qaQUDjjq?)\{ ~IMm~βa #F+$ݰ0!sǃy.͌n(fTbL>jJb-=0Q{[.􄺌,V6aI0iF2J;u"=;@AC-1-{=om"'{CU$UqALוG%WIɀźЮdFͣ"j̺Iqz(ӄY}ՖU\I Ƅ2  ^Z(7,xz^qLD2\N xaJ a|=fYiZ5LdGYz!inA<><LHohly봭-\ 0 k& $sF<*ܓ5y "O&X~U/.aʑg:l3)lsu^4g^jO f-FWR A fdG9yVD"d 4nNaKv'?YPgҔ?;[U[Tڹ :Yϳ~pjmh }}|#LvRqkڇ˺SwC׺e\^SʻOmwzwwJ.X~)]c$a@S$N |s /Mlveq.ȚZ QxޗY!(^Se #t{ҪEsX#ei$~Ҧ|EeK\--%qYs׍iR]1 W9 rDTeU(:T>9oӨ,uLtQu#]oS5>WM,iY3E_&ِ.LTa>y(⡘+S GB-HYycr x:qbӀkhiI\NԜL h&XS_٘k$ۦ"n_S"H&ZJ܈/%՛g8MH6SxcM#Pb_vc7geLqTN_T0V#K1?Pwc] jhsʰ-YZŧN;tݷر6| 2;H|YOt6zww097;Q6)QeXD@o{d{$)BEAZJn!$5W~,;`֐^[}Ih /&?pa$:v!ng:5eMvBnQf5o D 6ƲTQ3kc?_2}mI؍ ''{{{jE5ޡJld`nΏΫde^t tm"MndnCEl;5:Xg6IS\] 6u` ~3^u4$) *SSV3{^ӮVX>útF#Hm9TuZ{V1Qaŗ>tB{X\<\L?D G<_X Vh$N'2X. %@i u_7lݫU5ALjAXrҳHS܈s9 W@u=:C+}E$ɢfgYviqf1مYƘq媢SL7XdFY;$(uX᱆u:Q6MAsz#X{` _Q1pdj_s:f:R 1|tWJGfcoOa:@LL!O[Sfvm5O0}i9-҇ſ(E5w}&3^bhޝg$mu1.2fj~ -0cB(q 55IX.HgyN(:6i1% rw`R )%L02p\l-rT"+Jp]>h'{W]jl`Үpɚcx(,H.Fb6&WiPm^P=e%m*dFP4 Ħ%ޱIW<Ë ez=ȕJXģbHO(,30w]ķuaaF*AL}Hp ^qY)uFWC bVy2>4Eq ngs~Gd\Z#!e5uܡ&~UjGb_0nRc}<cm;FuTkMІh8ǽb6 gemUzi׹3caT< ix<&'sJFf@e,WHBld݅J,">*(P?; Tkqk eDz-@,2r zu1@틠ezȥzP'$Xt\*m49 $̵ k| BV3kfשG[Wy;2yVr U 4{h; У^w|,Vi^*>>D|cdxv KVmb!ly&Z(!Q%*St.zh^ږra顳:cO@+()Jb#-l*=?#zErO!+[ E6KjpEd=#Uc>Yy[5:CEsO[ޙٱ  )d.fkt$;Ɛ\a5;a<á\!tPY$̮\A@/5,kmnG_dLXBsB>8}{0/E5P NC 04i5"ڷz;_gF?wh %g?n6BvyB<0}^m8`B_w$53>\EiـiZ*\l<ݼ/4LU`R Z)abu1O]׮n%` ~&Ⱥ͕A%кVt1ˢ"Ev:cO#h^,mCRw~Е6Fba[3Q49(3W0;,^ͧKF 33n _<3^Z3yNܪHea&+>)<˟n,6/_V\/ _vcZIJH9ZV dCpCq i(ޕN:N''qU/)lI~kSV54,ׇ8м9s `-'`8Q/('uyF!g= \y.FܜH[k0 O<B;#@ c Q"pfpayqs(z%vN-ه%t-T>X1Jժ6Xtu0j1N`b:DZBۀYXK$`(~D#'qb+* !ޒp7i `)ѡ_3ȋ' S)[px]JըG2ô(1dy6 osp/Η719) 'lў~c ZupN%g&m葭zAT-Y8@IHb-٬J88_(}^SK=j`u@huc<8X8+vf 2=:C:N?s( x46.-n8 1Cۃ&Q&Xh8$9q9hٍүUG2}Qڒ&2:pJz} 4z&Lآ#IjSz? lu%+2ǣ^0rT=(i- \ѝF3wH­Znܦ˰<^ r`Z?xи1gYf" v3^ ͫ: ë N0`#rSd}nK32^ĈdufejHdHkx![B@hG $)q_KwHR?pcBL(3<uʚW yi.VJ}4[7~F!H??r6:9,8R80cOE9^l)" j²ucXH!(iz0=iv ?8ޱ$ sOcn>ϝqҵ1f"  9H .$bqWCXb2>ܼq^ [2֬3'N(,-ccZ[ aڧLN7s䐤]Ms|hxPC/f}&ȁkWGt]pv2(S;Flϳ)M"MaN. B=då&쨋lwm]#e]uF pv,-ޛ´qͿ t\u%~y+?h-xL*k\'<5W[Q=F;#DC%O1HX7^%C /{7$>"vx#N[;@cQQE;<=CП@,Su? ]:-Kw 34T\"i8l C$sib]aPe@~ڦ;}}udÏHЃ(_;.WP߁2DuNE/eLbg3D PV:jQI[x[7[(Ct1t|EęaWHi`[@1{sv|f,fyȆvmbz N}\'>5"tfWլ'>q/9gq|c0F8tkvY*IrQՔc$R2yO5q2vф ?\h.Ѫi[~v\f6b9}L-:ǽZw7V.e#}T ff?\OL`_M]Iyj~ qE72>8z Mr_ 뛷3;iKv?(eku4SgWꫝao4B .Qa Eq2 {a>uʦ$B%QDMh _>ClQV6͔ oAkk*Uc{3@ctIE-i_ TaY1Fz :mLJ tOD8}|i{JBC10mDvPj !`¦{Ǝae @~qUgKXwjvdC3|=,Ac fXr-8nwŧ?TxS\usTO7$h; 2`Qx4peɫO!h#QDxl%9 lu]:z9h[=ZCGh0kO,O$QWd :"p_X((o蘆Hnh ySOL\3%6 -9*. ÐʣץjE]O_[U8&x7J)`׵EG=Վrټ}CGFŘFX5Er֮l$S>2/ :׉J S@@)0M["m{IU#{NNL~hZ+a}MU?&:ZMj^pnìɡ{~0'窠$2C[ŐɼmE65t͚Pzϡ$^>eLCV9*G|[YV$"Opܐ[kAഭ":r?p_qu ULywhJn" u"?fk=Ӿo<@ Z4Qncm.-NF6랟fyY[$)b~n "^PgDҢJ̨1PO&Ρppd !8"5-EtpwߨۃNWj;fΡ^_[S{fӳZ~ Ll.&`awI_7@ I+li.$cbSG}`ʑ;$&ny/_qka10֦e.Ѵmdu/Z~ ck ͆-|1? 6˔T.11<Е_. uU"~oDan /ŠLNF/s=ؖZjS }ojdIw9g͗m'M N[oX2aO$Z}? 3xZ8w+Nt Q'&N2Gl;.AΪl&ώ+Oj< 7 Gᲊa䶛(Bs/<‰tA쪅gX^ͯpc2Ac^rg*p_tؾ 0 ܂4b8=ޏI=fc;:-[qN,w$ '>n^dHF0#W _äȭ› Z'V Ư-D^rB vPD&"P|~++b/ <HUI<ލӚ ~dǙND-d&$o;m ֚Tq? ZatU5B+'z/wI{zf2t8Qb;F4|x[jݴ{l?΀ڽdEP)N_w,1}59MrA&:zjwdFeKGz%n]ll+F/INI^4Ԥ8.Gm*iOdz14{:rz7!|0f:n[y X<"cp `ق* Ӱ k$B"R3P^cX$хGFubnXD0;bFG3{I$ A-}haBdBmj@;1Q=۔IbVGAHhg<T?5.a݄oV;vXEqR4ܝ)g$Kw Ii[n~E9/ Oa,FM2+NTEɎO.;̛6|[$;!;XΘ LheԵ/<&T\ mܝE! .%p<Q@x0d =+@Զ!x/HRF'鵿xnTimo`E;YD|jy̦bX 5/!_N/'?PEh=:cD\(X΢Fk0 oZpT!ǖjO7rcx t IFd(a`ݐEE:* N _#M|N -cTX\KU૎d6EzlRu/ذlOʎN@& Ne]^YSEYNzl]sR+,+$}KJ`:/\B{'"y3'SGVD\]Xf'|g9ߋnn d ݞoǞOy YkYTCK^/MJ{_wz SY ~/#SP^{ѽ5ݜ9s 0=X=ҕu1nv$%X~IEnCmVu)Nw.9'1p9 t[5|ioL ÂꡯbfGX(D3$E!8q_ (m_pĿu] !(@S~{iOyXA=O;֫,r9IskQCIΌM: ?y ȓT>ؿ3XUq,-memk/+Ql.HlX!|޸hv=W* ϑau9)b!;tmKwqkHLv9ʼx8hCv#p#bnõTqrkA)' ͅRųd1-zty !d%XUZ4/N30K͉? yf)]Եre_'BNAi /!̂-vey9L;B|ct=Mƒ&gCz&ԓGwJqZZaڳͬ+9m q_ᓭ0>ڃ`/Յ 0l4r D ntx 0]:X[V~4f&o3yl#f4[!xm%u70GT# rފ6Tܤ) L{OA^ޜZ|weKSU^!C(eOzt8E&GY{9UoTǘOZ[ӏC߆TPmd HzgZ^Yj`'L!Q!l9qߋ$Zrz 43$<]%(,ohaÆM]'l3_qQhU7ꎳVgo 07Jeڃ^C4Z1?cږܽ~oO߂LNp*ǻ'#j&7} !4f Kchc+3ؽ/  "1v,SgdtfǏ? O9-UNX¼mΓk(rq~Z)1W_Ó=Qg4u3 5Dצ›c :hPS@Du)̇ J]2 ᵉ1-V$sqÊi3pv97 }jf: #%i΄\ /'Ix?\** aIg޽ㄗ{na-=ZU 1LΡBMi`s燽N`H}׋5mv$M Sdym.a6MqБ4a3G&ʦl57R`)rM 6(mo]oߥ·%!@]oxwmm/wĶv:)TA42E&7g9\1_a+ir[M#OKXXOhDv(f27/sG< VA@߬nLrt,tlHmz !e~b zTT`ē|X](-s4n"G ʯsDHŗOlP G?n6̎q6;L~dwȣ gg y3R8f gjo'܇b_E{ME }/Ma?ar q0׏4>N ׿#m.y"=/K-WI,=3c{@ӺS(o,YOh\*f,o(VU=7ju?gU3Iٲ&Bh^u,ە:W^J;Hpѓ1IPC+_\6v$%lF!;Ezgqap˲ntFxB!7F}UMXU۸VKAmbtJCK6Ī]\EYGTn|0ή[pjҁޒxCvkPi~'V`Gꡗ4.n7/z,ZFV&ν+ A)Hip:AyXwZh-HQFRLm?&tUX/Sw۟4h' {glLSg,_10Ϸzsi6/9GHFX#G8  ZZtB}$tRg %FMQ " l8V=G5n(8^Td`N Yj {XDad ۚۤ#1hN RĠؒ5re5{,kE1K^ַi{KsS/}>(@y}[N,ddGH2nS#eM)0Bщ re@K5RXtOh5+]~}[as zRY5 g+76qwxǚz?I ]*9)#39N?<)~D W68jj(@y/ᬘPBa} z;|,wCÀ&ۋ1\DW*V[sFx4f4X ̃)'Um4x,?1ŧWSkRYNOՀGwgRhht+nLRVRQ=!;l}P\]w kA/((oR(UkU|DBVgś^euePr*L) bΓrǖݚe%'7T`G0p0$yLw@"KxdK(0\}Ƴv}|aϹf2i%b.]}Q>  Og!L Uhe_7b3܄;8WMo{~MQDH/=DdDV3+Z2{σ:;uj|-^ۖ{!X1Lm ~gf=ki\O]O%cnJf#Z7˵r:Gncnd$=){bdPl"?G~qTd!EfsJiTNH< D` CZ^ZSUrj ބ7<Tѩ3`\6 KQ,n-uw3p(L^(tH@uRY@ RSx|҈a,͗MͼTu j;_j{p7 . jqG7D.+h/԰viK2?{H?3SB2;֕94ZeyCJifI}xB#ְVj/_z02gہf{lʣ/RhnkQ;|׭?5"ʚ"R}l} Dӻ`&K6'MQN5Q_:ѝ05.vNZC򹕻*1cA7w5g-+a]i?J S[d8MIm4ϣo( UG,y3CXe h_1 ݳa9@ᘦtg f  قOchE#Sd-2i4w-o]{=y1?zp5<\~71amj3h7=(Y˷%vB9dʟ[4?]RpyH+pA,vǩG/x,~]!DHȇru X,KO+Ś:%[mOv }i)=_T DY1'$.>9T<2ʼn(BxJm߫{#B0#.s3h7BVd6J,% 7Hd%EHVz3hay,35\^y u%7@9Asʩ\uΦ_fU8GYu7~_ZMWkEգ+sҢ+X~o+\xKjClUb:W[!sZz{!v(w쩣AVE?6?ޖT̃ù'7Œh[a^E[iT;)9&(5cSRdj=bd`t-/r~FP($LTR*mBzp-98 B}Kf:0=4.~-4x42Ҩ?mi9l-w^(!$&+JP^ T h6z/!ˁFagkΌT]X6U& WiXj\ SoI~k:Ff<@vt!4Sݻ}ukqc\tmwl6 TϠ ,D<.~$ ThDTX 5]7}%bl+Yotw?G̹+rɥ-{EٞN)ȥZm6%Q!:g\dg0G7mQ:v,ܟt6kx9bK3E,#-vOm)O֕mKu=`*Q/Y ]_KC #oΦOo$ +X"Tz$^6Tx!ZTЦ>j&}xS&~SAO[?>APH^Bcm2VH%k0i胷 x&{>k,^#:Zc*$Yl.B%@Ǵ_L%g#I:hMeV\Q8t9zW{f3")`U?A9BtU|9qTĜ$n|͋,]^jbZ{Xq*4P'"V#Vu(u {7w1'hgV`xaNSZ hC +~[Ks9~_ Xs}}CH0*FC-_WZ(bqγtŎʚFlIr/d\,ѳ1%unbРU<s?E}v[fTOÌxKvH#%˦C[OW"}QK ?fdhj.zc4."+P[fj-V -a.s텊|)Sݘn`qUKڝn0)V$n7]J7n\mJU\`2Yū l6ZM^S40Z`{Ӹ<3ɥ8od-lD&vq+eU!Lzu,%'bӶ9(}=f47TpA7:Md[rafPmWE9_zk |A!OmNEN ܯaH}oҩ{qI)v''0RN,Eo9 ̅Njg_ vNNۮذMV]܅U5}Fҝ*7gj PU+2Tι:}T♻3Q,a~"g@ pEU2Xa nBJb2_c˜ SJ|hXTS8:*{݄Np4|Cǡ4ZvM:%~8M`啑uzNO=h`SYBR+8 OmYQ<@%$VTD6ozs'^% | όÕiJ_ X;&^l7cbc:u[{޾qʯxw0$ , 4HPFH,|H$uJ&f.tq7Ia$Ï`pAhKR^}qSe6sr0pCro14p?liX8T; J@2yڙ0$iAii_"F"٠V`SYB.&kgWȵaѣp#K:XaS˼yἆ:]+ qhHyq u3HIX4on;=}̰7gIkS&в;LYS?N(0^yIrb0C-ڞNZ3s`:M@Y~pPy-~,v~Ĺʇ>C'dGvD?k;JYO Hsf|޵ǒ.:tKcv8omRFe38M8xWe@8|±6*5 v<@N̍6._^ĝ Nd'ͣڥ7F@ q%×OcA'JH娾!N#O PU9ASI!t + aOp aՌ!^]{RB9.Yk7+@Z-զ fD?hTW 7Ȃ\Ovj*^i13Iݩg-e^soNlnfOK~nF}{fɲ-jn'byz7%ᩰhv7\܇vLaf[ix+n;30",8'{ ZݤOa"D[E"ƋmħGws>`ݟ5nT减;V>ΌtX@H}9p{xV*85u(&oW:31+\K[[ Ğ#gg ]@ l\k5 M~k sv$2~v̲@&טw^㨞V_L lI|Sm3e=nkb6eBk'ͨ3 g/oQkyFb?h#&"1_nW*it$E>^&$c3}qW +4*x5f+5 ,9=^.7G;2 J{A1Pj cԗwT/=jI, p=h?_Iʙ<+ )K7\e1mWZO͎\rMOqC4k`E\P9T˵ˑP"!@X ?*kۓ^x9IpV0s_Ryۼ~F.ڳ&T,U4l/C4VsB12b  p~/pdWK"RaR"jM%nȢH!}i Uv =D[)1&:?wٟx0%W>˒֜N1f2J>DKl9l U|=[0%{ 09r dʼqzqo lTWю7׫|2di[:r_ ljzf㕠_ֱ?atMg7 EjɿW5PR K ?-X ;k@R _\uNCS,90,ws{Qg54[6QFʊN[hr V<@Th1,bu@mRyy+vDl+Ir3Ş.GzO U#ze)jҰҘr{ώ$v ('+x}[\B+ >3HхyH;ڋEVCurn*sj͑V9[K>]̇i}tsԡIbL P+r$_T~,]R >?6$Տ݈\wJr V>Իg7Z̲i}+T0I3s&aI]3N׌V }[.Ma#PV,x0bHWU^lCm4#Z AtfH:G)Hz`Y7/% E+:iOhbg]Itfpq_C-\0?}0cfӒLojIUîBd@ٽ4JЄ)&Cѳ tv+0Kca#0E)'IG8^c _k8x¦,f7agy.YLLSLJA)2zM Lh"ѓIV -fxO98G{823)Ǻ+Pn%UOG=>A<#2r-^f #f -lW6v5@HՅ37ΕS%m4MR[:%=L"#CHY'߅PZv?!7\qp!4xLxo9oT+"mŋpIB@&o7FI0lʟgWE(8A'g<3"T) {K[5hڟVLLP+յeAܚ[g].o HJֳ$"ϒG}e,[+-D7βag1K" "2][)3苗r~f5zuXGdO :\rH,;;J<{j'淋Xй%=;RBͼz=SbQrx?ϗIǤmHPUbM_z y}<|VW@SML\8<(vAN,:_@ń/>痆0^k:#fL) {,0|c=y̤^'eQ^m 5"R)+Nz%1jOwynxIE2"@ 82s07rqhFdpZP> my bDIUZ k?#m~zۿ۵c'nPx{TJqS)܂p:ٷԌԽ E•gڂ8E bq frNfh&:wg"6*[oys9M/v_'Z@oj&K F/w@p/F8w_~[gC1-t5P (r Ts\:A;i 8Vg| 3&ݓ+%Yu+>\TvG@9UJ"fc拃/#anPo$-S/-K!čJB_["E3czCbfT(JCBe'#c7Z>ׂFFF4Z)"h=Ww6ew["3 [Վ9d:D7R,qkQ$ݫN~8mXlYQd tdrNғsRaA>X6ȲwZ*c^UvyUYe'2neFH$]l⠪z=cLi qѱ)vxљ+d:KwԏOT&Fxg Gzweӛwəz؂8sM!o/qpSʇ+ d^kBˆgP03t˖ՄR [9RSP@\kS7E;FZQ;^"ս\I-I)LZl`/.%i62dkrv] v2؉ 冭Lsp p'%B-ṭ/㳩O=clƜ(uѠ_<1޳5 2~!%[Azw;`| 4w@ ]`r :@e7(VDV"4JVãhs TlWjд+0o6E_Yu41΁@P0Zc>[nd#A-A;n&UK <.N E)yQHowO?rM$KO ڿHEtOU"!U&VGy 5dN[n $@V b OPƪn&5 ˺ ӽv "n3vX<|.ܐصmz?ܼȠ~?dž6$WuS$]JڐRGMMh'=vsM0XGהL!pc2P]wx͝ %FM\: f3KxFC~glwD^0-ä/8븜j)HAXo`1[4kX pt!KV:ݔ*Xl=wR3c.=A%r2mg4K=Whu[px*&DǗNJ\Dc5 7zJuM*A'9$zlHYgώ,ټ݈ߊ4}oҬS*ve 8 ?FOa$H s6NF;} Xoc1ڽ9ru#(Rݑ lOՂr-u-aokSvAȄ{ə>_|#7;ͩםD=#n=VP1 AH'b(@L'_cPCyIw= ~#QJ/ZcAkKOb_FMdFyϯܐ4^4쇮Զ%ρ0:x 7[۫}%C[E8!cMO *δyLJE'[iԚ^33 ;`ߵ)Y,O^rE,T8,kfV;c0z F,p=x*{6DmClK,3IENLBX&6 ._%/BGRBeH6J)t^`MBcFŌ&F^VaSFκsq!):h{n[]Vz-}fP;e6hy?c\_7%rvO&07i?A,YϝwP A +8xcW"ub++ [g2.VJҊ;Oby<4tx1Faatl_L8N`#2?$?mn$-Oni'g2aW]-~POY-L&4LbIfVE|0.p/_Nw.'8]υ$#+„@$w9s 5w|}*E H<;.4oN@mHH&wJZOau/g_ R%gl, } ,~ xM]ґ ջ;MaQ1ȟ (ޮ o"Y-PM <T8\6:x6C1j-bЊʬ/[uQFJA$S&kV B3`{_Z#ե$.6,(Εtc4zW^U Gj̼nmIƻΉlvOU}FWGwN'O.JIeϝ2 vSjq]ET"f΅M-4; ȏu73͈H_/ȇ'g}G&"_x|iI\ (UЀsbDTLUSQ<n;8<׽~82ߝ,>E}>ӉV0&SrW,%G۝dY@ Пlt+WVa3.$aZ*Ì-3S ԷOֽwzR*- 1}*s//4 K)Qg`+nVCTGmdqTed6{zKG]\4zsv(ܸ!? E|%4:e96VXq:D/hBXr+P;@kKPk4}qFŴ_p`"V9na( v nW=*xXP>1 1ܝ#"h0NWT*qњiN4_fyc\OW! g~hȾC kyzlDIѫDd|b3+.SOn[|FWE'S^q9 w6[+Dۀsό>{5sSi:%.Hp8D8 O/9ttrݲh?x3aovW':Ҁ|m>وrƵ9*bX- F9mg`3 3m;3_[XԚ<*q Z]ǹ6!2j@{ DX"~A Tz>iJtj٣W1 g2m.{2n$V={s-;7:!'g8xJdĉw*ɲQV^}H \^X(F&'yr5A+L@2l$H1+D AkoϘ=+Jh RtRwY%('%~@fTׂf<(nv&OrT N?>ku [מl#ckЍB8Ny~IJ'H+u݉gԑ(/4}Z8NX$yMEoCo4 PY{-%6m824W"mﰚ Hu@u tU1O?U'bZ> z>ۚꋮ'֬(Q=62~@/d݈`VlωnA/<ˡGh|D@h9x@G$߷qz+@Vo'2)BG_{5Nie&su~@k,}ºxu|EWYf#yZj]U5+^Jy*'2+]hNxo^*WS8%ad Bd^j!N1)HЄsyeBE)/g%2< ITn:S-XcOINb@~0`;sbN8IbF{&דOh-/v ^iiMSBk`O0A/k7pY\!Loymx B~ESYϤϤuPn.!فAOQ?! UT'؃|djzDZk%6h/y_S! +R?,.}&+v ˍWɊ'ͼ:Z (Jh,թ~V0.aÄDΕPL3)sG'`*mi]68U-A*$h*uF`}DX&̮8gg5EAO?ɽ[ex-&DFM{qtk|'X=!hoQǟγDat-]^B.L>˃$]=%RF}U[\/ߍTܒfl @IV~ܟELTsl*R˦~h5:U2rxJx362cSbnҸ'Uކ5!wT~h 1]ES.nz3AÕ^@;ho Ysax5n䖧؂Q5fSGk#zcY8%$)ʣ_Փ < â;ȚqAêd'a`z1H j@)>NzvWER}S\SJE\=!vd 6ő+(Ѿ4s~/ | 8O^6x b K  [V*5Np7\dуH:PX4NS\GEm9Oڧ& U֭}$Mp#F6CGXEaA _wMrf8q_ UMp/Rs*Q):d"彑KǹfOdTJs>&BC8=&WbyH]lZJ\ԎXo̙ y><5^rMM_+!Z$Fg؜ɤ碟ȆF a|2ůćB -L"p ̒ 嗄ag6ekG]8wը3~d@G~ vHbWbUOQ^d\[3Xxju5CuN ثOܷ:ܧo(=e+O*ǝl~hүY>\#eV*ODܙ<}{2-[^B!^CLޢA?kK "IRAl joeQjTs3*O| jo09[mAꦄ݊KDZa0~?CDފ)y#HK,.J^MXi9epE)<V0u*z[:[p8D7TBzɋ^aI2F9l( p J6'x3-}y-O=/γ"Us4gé}j[xq+ 3(e/8X*5 r -Znם{3{L t aWND>"EPx*sgԵNb{f >6!KsAmT%Kg;ܬX &YnP>GmO8$gYLH|M:)'_Jm.^4XPw;Ǝq[K#@71 @µ/^*:wyʷ m)+V79~lRPw=Jg!3@46Hm$5 ~N͸/#,fB[r/ [He2w'jH[l϶VxѦC˙#,CY;v^NyζV?A! Ǐuf "\hon2Rz6^"Ƣk$NbRN:iN>|HFE{W8ZԙD'\k;_p_"3^DIJAR]]K]`K\";Txdnk6D{bD!M>"(mj׷\~r0#i'8ו8˫ J7[{4w D2(i)@,#y-{dlLJm4Y||DfYuOn?#T'hMf]2#『KDs}L9-pDžTnQݿKFC (\Fc;-oEHPk9{8 #s*@B яv 9M-pU8۪˖@CquS8U8eGL E:h3q!`HaI1 $\6ÊB{{W\jkݨtYl i]VgL,0m|6BW?,jRo^o>/?.t;0sg>ky׹=ОS+*T]ˀ{<ɻְmμ)gWV܋WDxҸm2kC+T|/n4u3#o6K#LGX@,x:3"9 9jwf;W Jk*766C(:!yVd<᧭bDRùMK{cletx{bsY#r̅o]5$S74gZc%y1\P( D\Db9Mz]AI[g+{%VygY.Kc3r"}wDr^*F:yz[p\` Z >.W]I1Z2wVb )3k sgxCZ>Ь}aA#8pέw/)Ğa}? tnɚPSY@9LZյag6:ux<̗5 G$8'N/f 78T} I;4].Ư{K^ϥגW^Yn҇2rP!05mZ5@/"|d?:Rcv+O!Xɼs|9ȴ)ͣ`%n$Hw;1=wX`u텇_7uÔ 8֨`% wJ+"X1:>+s|,ӗSl yUؼADL7 cPH lSt5i_hfRT`<GbA+cFbW +~dz:JM #7f.b_rBrm ~i 8u$=K)vv~%=7nFhu>|vaѬ!eQ/zwj)[>;sE$;PJp'hۈd\+;'C21Ff>rϓ[:/Vؕ?ռEw" m&2Xc j[2"L׸+}rji`C#H:EZ%7"3}f{Y-A,!/ۏJhG,VRX2 rv /GeR *$gt?* `ĥS">])~re033?.zs€ hx6-)[D~ oK9@),t5eڒ+NEt[DLf|2nC@ Fo+ru 7#v6Z٬!}bGhNzm <:c\P;x6e -/?(=I3G30xwjE dYN%! cvͣ_lG0p*{™fw^46d”0ѢLC1ϵCP7w k.H9Nq9y] XJ ?*ҟj F_#̟^&e؀4G.s"KzCwE |y-rf[~ E<*:}>[U{~@5Z&*A.%N 17pΆXk$靹m@|cv jkPyIfi1 ё2L/-UAH5f |z̜M鏚T+HBNEO*xNmb|Z0PsK`JfcT|TH'"V}75b])ضWO/E-XfU*.P^W9U_RcnpLѪPމa㪮f1mowφD d$wDo8{3MW*I#"eͼ:饥( (m~~gqpj/Ϝ\VdڝxYMQ28Q `j;2O* !Zy? NaGڮYkrz tc*nKQH% 66]Ld-u/e;҂HM1sEL4ÒkXC'e雜g5im`4ɖj#KW bƤl;?a5Nptf'3ڂB4yzNdt)a0wp{,!gBRm/6(KZ>X2,K: ͔ /֪}wM^~ʓ4'SJye-+ś&RZ;^a::C͏dIWJ?tRjy~ `&^GMdm B{M8LHz G/vܵ(N^(%L̠#[m 8Cy6@ Kퟹ.%b_eJt2FvO wgk-lHr Aܚk hGb0ݡRH/*%єR๫\\*Ŗ/HNp2`W<qsb:ܦ(ի7(!gA"iGV>3s#jCFNfѕ1LD8> AE(wz\#NBXD !nM :OPÐ4܀xLF.ςsOa3\\P-U9;:rH:A4: =NpXD:8^Y|ۇh`IU>vQf]ƾTc#+X/SbW-90; vm씇LyvJh{K\E+3kʄn+AŹ0 0)%@3t`״йcw ŷE^%sj5tMQi*Kctc!ަb۽#Q]n~&蝷)DlCsH@6qwz-whСuT9hJO'hҷdb\zʸY؂_ B4D#KGuR*!u޴Oْpߐ[j8 n{_G; ,n]˝L۳heu4Џ9Nep5L -8;(kAz (+`eu22<Z}%냏+R<8R6At |j !L铃G<&h V&bZ-t&OHutZmx?NjiBk]^ܘp,k2DWoQt*Ξ}`o}krH CEQ$&Nx@NyЂcr ~%Yd'XX^|V-%uȗ`ʨwW}a#|~uߑ̹3Eq!荲Y'\DKXr5`&Bh#9;8{䴪tc '[Rsx w dhocz/GbLN"`TI%Jڦſ=x:̦rRԄK"~f&u-n{`;vZ&~3E6HL3mviS%ƢpFO8fpR\G(]DMMK'Ad=3JXLK?tE«oQ+vd诶ڠ9ӻcTKSB[ <5I(N9Z'2go~s#pss rDy <:WcO ¬ JE%ዕd*p%Һ6};*BFDck9MWʊ y5oqHREg_O>I;gQPGK@$./.]] f^[tjLmjwz&oV<7UyӞ. :k lWX{$P7D$ 2=v]y pRnDW{SxPqխ|f6I7@Km4&Z' RU^eogvSpyJOΤB@!s[DV&w>V1X@{B7` zis\1f:nHw8bP7W|Ki\(K05A2š%-˄]b0:D!1R#kvI g buLL[ #B~ǭ\]bC mcco ]W(#uy+LUoϓ%1 ~`ZNRTfgB Fdvh{\eZ(Y'bXNʤ@DhUϧrѫt_PYZ-* E2/n1YUT7H:ByHye}ED6ϕ` տ^T1 C6骓^K< lWf fFjY[׏dQa:B\144luY6y3U壝+,9,~ S~Gso7d:n'-%/t Ɗ¢4<7V8,BtDS70o0]eܺ%ѯbVTX) ]0PUd-KӄzA]dkO8Ha%P48Myd;o6Qfjl|:ZyM=(X%%cn. B%r^!B/|zDԡ[B A7)>a+5| mKJOVϬڔJa+DNTYĪ\*yihu-hbƉ[_;SDʱ'Ȭ#JLFgVH7hn4sqN߹plhY,흨z9>:F׃1PėpmL9ꪡpt䶶c|^48ʳKc|ieG0qw?O1%0Ag]#8=o3J0'Rށ4(C݌)1K0&I(#Pdqcj b  -a1EڭӠ=Id!<uۥ([6}Uܗp),}+hJ@!xv>Qco39cltH~Ӛ >6x hW½ b;/1팿͋.,]]Z~ϗ>6 '~eVS/gt9˖bwNza\d% <^-T^;"AZ~xt3;ۥA)Zta<;"*#=X)ʛFħuq&ݝX3r=e͑#6-^lVmq-Sy'}cjN%5!p?AU8XOOM ޞ\R c_̄j%Zh 1Φar@n;ZOp3#>'MtO|caVIX@uVV0e/6@n+:i9 D&XUd$h`%g ra< Bjuƅ/(O@g.Bב~I3\]oY]p]ňi33ˊL;:vvOIFF!ҹƦ-CGԍM)OyH%%\W b2BF1xJZIU]y15E_֫sIQ*F4lP:Xha\GEcKD6Kl_1n͐2#d˙+u4hCoA%Ί̺ fRn/ 8΀I=g˽,d2O(**CCmBv5;a^1tr'@;am7I6s>TAMD[/nn ;pU&ZhW(1ʧf"6λWZAvETXw9qxF@NCM22ti k0wGbWWZp5>v, 2q PO% PsHWT0E 0 O*L]6QGsNUP") }yj*B1aB">F?`S_sӑ `w~zD߀Hyb˦f)Q;a9yS!m8#̱e SVh % Tf̯L]8E1Coa$add -7 OGfTaHGg"/+F^bm_۰ [n+(3\%-;ݬmZr'"X4VR9}/s7|("L\kF(1 Vw_c$C=-ldXps|a9>:_aX5_1VL e֖!L)34"d= +rpBL*(۳4rڀW \$C5 CJAȍ/61xUM.~zZ6[\9 Ɖ_95@A#zw7OSױ t{%Q8+Ym28: X7ɁM.??S0JH%S1d++Yw2}?9&&L>#GU'z8 0uc;s;F{]~؈|TPe> 0ԫź9GKG4?Gm;^ΓCnP|e]̶̒n:YY'>Y}?t- $ rnBL<..Nڊ<ڨU+q5J'raiD7%fAUe38㰪3?67@I9n}RtdpXn(:~ _c#d7у1\Fcf. dY 3 ٮ0Keݮ1u!`Z%DSu {Ѻj{R |;fwvyS T*$דqأӵ Daw kUO(t !86rZyԷLh-!KPHd VʜI4+U1|\9+@kl{ E`rp߸MdN?7a?ަ]@S~~$db{Tfn"zZ\ٞ6Ub-B6}WyU7KHgמ73:1BuHj*Ϩp5ϑiI&FhWMY gZUx-gt4&V)eh"q-1@(Cu? =_֤??vTUZ迉;TU:hVp{KImhT/,Bd7/L@pE*U͎R}mCs[d./ 7 h͸:*odTE&O_uSUo棤*8Y 韢"'Ң럔滏k/5{Fy$Wч=ğ(%>{-K,~?]pNƷ{̩9;-;bо];EˊG+1"$V76ob39Yo+*=K,/?ѐ?%V)xԍ 5z=P=lEW4fr2}#c| $qa?̓l<wr["[o8H]!cKBg/_%rLծTIAfЊNn4rwUV]p Eop-S̡n:~0|x\Sl!-ɾ/bJϺ/ܞ9>?ՈD^ 6[ۅVNYF?|pZYCSƦ]:j,%WW Mg4j2gߵlOy6pUWKI1)d=|яWK4.'U`a?lheV͒~r9]`8˥JPwa\wQ=CptGOqf*I1_ւauDJ&=@0HfHBą>@;Uț,;8}/_vђZ'9;Vy&9z|$\d[F*gR, Kc%N'*]]ؘ>/22>D)XM`{wf-ɧ~E"l&Gy/k)I-"7'1BH5<ӁuD)ȪaZͥHuft]T"߸De,s*lMGt {%*?vf3]YR?xprӸesI<6/#ϹGxj.tH/>mp _p@t~_rӃlB!EӃ:D1 L7eNwal6b.)K0DPt Rss x5 R1&~JE"Mf*rikXW}4}zbO'獚q`CԮ$ smO/ǛwfH'#h!UiU(cPgЇ@Ktn/#ԏ[ 0 (`X)QҍAY(1~8JwYb+&@%1> aKM۰E<#2!IV)bR7t-RaN?!cP֛km'!˙p4_38v 9IyL`R(b@fx2,OM;TB6p~U}9}_k8B'ׁZDgAU)_j҅yIo9VmklvF4)97)uoxu=x`VZbAc+l$ 7"NuBƒ|9:ΟA&=jl9f> V\\ 6QM{*wAD!vҁL+j  8&rn;wd]7<껹CpOݲE6HVF FO ghk~,ރQ蟆+a:!B+>Y5T26`NLYKRR噻-L)l1_Xhсl{]7D{@tn$y4ㄆSʅ, ڤN' "Gmpݞ7)= +4 [ӓ]g'C5&bND0dOsY 8,M+'X*0K҉q4.~zVv2ߣx\#Ih+fz5j NQFRQ"Rs^B1gX䪩23> ;pNJ6[ m-\妣"ng=ѵK[R6L'wJn/_s`̘tzb땸 옠9=!c|l+SW5>S ק-x Td e1ͩ@d;.;!}**RX/m1@wgKWp/aիFn xFޏ;aHhSyhaf;$Ο@ю] Ի$nl(N|Еr~d&.E\NJ5;9 ed"KxoYc |DP6RY~`%>Y|Hx-4\Dž*pY`4F {۝Pg>T/ߑ,҄Iw3Dn_?1Pkf^ F RTIFbi B]nL%9 FDı̨oͼ%~Gt@W"j30x:UU:|GB'AV0:%AHˈ XPWx6N,*$*s~FpAUi[)%e4@e݅ا[~Ec-8cbQ)ސGVihT=Zi~>qbx^ɣVoŁDC1`dk/xH[rbFC/8V+~]X6+'Y ˞83fFQA)qm%PCk=,wCm=r6=xݭ_y%MXtႣ=z8kF2Q.1 ׍A؎_9;i9kS ""NҏtjzlQ.1r_QM/2BAܶ}O ϋ) o+kE}|X0JF.gss,:(!4IH^8bo ;T?7lT1;=uu旭(a*kQ*Xg!"p|ȌM Lc@z c H+ "ㅤm87^@RЌI*o[8]Cad\c2k62}pɄC 72xP%f?pjnnۑ%BY25; ;uzk J-M2Eo9o)8(A^W)yƎZWUY gp@VEb`DK@ m7\5 2 X%Lt0ӒFxj50hq8 M5,󹞄b%喰BN vS2s:t^YQ9d)W! oMUhvX®fg*0-Y=s"VЫo`PҺx OeJ='xE9kp/`t,]`9M"u].~ɱiH5Xs)suy`jո=M!?)k{D%rɨrK\>QH˫ um? E%`[>TEH0Zˀ'fe $}Oc.jݤ )t,v&T>I6q{EnWJ/lhȧ'iG~^ D:.,]@}]8M| kdLM3B斳 . z:ٹxr 'B<+~QŖBpB[B#&߹L\2R> ݻm宸D݌Ҧi]jFWKD0qDw a(S4Ư6yR=$xpt`UE9 9=Ѱ698Ύ2̓ga~iNH}%i7q?9koj~fnM jSZS!"5R;FMu_,@b DhҐt^S""EU4^;{6i*]iE2 ZWX3M[":3[v1@!SHYh+1=:pL[BϴH} Pd+DB伽Tqӌ^%N5MoY9͚#=yr ͗nW)8}e*B.|ޓ`AW^[yp4WO&hϛSMpXROŰ(碑dJ-Q$tXe$ZBD`: w?ǯK7}4i 6̋$oO2VNZ]R$L"~,,vn ɻK-R*l Xz/3\Y-OL+2dukA9I|P.uSdU[)X|yOU^ ^ߗ]L}O%VX H2\Posل=/mHg*1E OXzЗL=a<+`LwNx2Os;QLnG Nβsojiei~zN}ƥӑm=4+J%oф xVLsAZ[FUj@?x 1}ECᅆUN'scrs=U./ȿN?D!+|AbT6͢A ɝTi=\M6&ߜ-8#섈e4;:([%&NC$"߮ܟ\!Hl +'hnk(Ps  a{q\ɳ=Qu_\ [W )O іۤ?!@d-IN'Z2 ^I'7=D=~ &&3 N )s }'\PM#a<8.7BRG0B޳ @_z~+8?E)rac` M =bJD[CzZWfK;āSZA?ȥ|7 //a FLJ)M =w/n󴁅RT c*aEDP(rJPxwApw3ۡhN>?<13mZ_˷[m$ 4 =o*& ^QdF2pli--huw ӈ;_/bjFQMYA8|sׅy;gl!rsG󤤒q`_^4~|n8kհJvrdM["dlj&Au7sD6 sA'v!g2en~7TBEEw`I"j[q'} ЏџJ)l_4xV["D7W48rCat4 ~bZurH[@Kץ̳۰ҲFTS%"!͜힉 e`h#9b$'wa(+L="gQյB_S:Z4 S=FQy#䩪S;H ?"y$hޤ4x;2j,')ve˧֋6|}7͑+1E5S8-@3?`O Qnʯ(PRfZ==B"/GޛQku2\hw'7=c޾&Ű>►!~;K7`tGmS[JyBD'~Uk$ޓ⦵)呇|]q}f_HA|x0?91aTi^=A-8FQ,},F~Ksb}j] oReOĎ5ZX#l۲ ^#f u J?Ւ<΂ 䶕NdH}mB@m5+eJ܊Y>R4 h<9e]El)J$6q/ÕC^.!Gz[Y1ohocpJLTLqT"\i}J')<?WuJe ^c[.P MOd؅^JKl@Pd=<ZUX Y;CG=B#>)j >͌OQM_9dGrV8F) }` p}uT[)O%{_5*N̷FQBUsXQH&=Wшвn( @cuD7b΄JQ@GȽU(44^nH`LZͣUhIWp ,vYR -lLK'ڋP!"U3Ays\oE(sb"'OQKlQ]*ӭ "1{ȬO9י/wL;oH(eu؍&+gYL9p;4wIPOe:fZ"dHƟ^R>O$ zX_seD蹈! ̙7;eR|5MYxڍUd Jkh>T'nt/aJ&SA|ҽMQٰ-r ʈX,"z0FՍ2Is<>Ը0 Wp<|P@h]>3K)V t~Q(%z|#mlÃPSVd*!9Ȕ6>6iabp v{ۓBb#Q7~,9UBRO&5:Т6٤rѡC(D:\=lv ;0޴+=w(RxT@ڕ LvQ} O`ry~RQñ}G*'wjXR @Vd_ҩU3G5N;Lv`Jq7{?oRs~dI,X[ /J<1B8Tm:q;(6%hP&,h0y7/IT-֩}IUzsT9َ\%tpzǯڂE^YF'n;TxESoVE}zdvJ|VwBPi X5%*XuD J)s7BS Cҏ~ŷpcz2ymʽKEFn/->Eqᣝz Axs9Bz.*Leά[ű|wɪv^f40 ÂuLZ‰ ϶ו:\+U%Dq\B.,/FVo u\28RoHSoC@+4|uSe3}G4J~Nqp+rq2"(Aa^Ds* 1$9W+&ȓ2ub7)9Bk^r8AMO0ʣYs;S_l8ijOM=*Ӱd.&H9yE(#;FEz†ϗ%uTŏK\vBiQ|:;,3=TR?U9)gS#1iH"CNқߖ<ѵyݨ :hZ12%0(sxO^+hS~"6{ fC?;K `$)+"Uu@@EN[W>0 *'I_Gaݴ~v}fs5ywRG@hٍ~8_t:Zh2{ @aJGTY-tbԈ.hT[ txޞGeFL &ד⬬y-OiZjDmحgتЄ8m O`Bd~hax}XW\s_JD[GMt0XYLdZ؍ttwU@WZ ۷=|0K؏sb }tjCŽDq{_ a08mn3bFK 0WHzt;c$3II#{H禎|qU G#/}[ϗƞ;zKCJYK{%Ƴˆ0:KM:.xfc;n+62V^n׮NI'P{%O?QlDtXn!(w^#3?76)]d5_#JDT#3yߢkZ_yR\ Q-?NF0J]Z+!u>oRFQ w@،L>.f'u'd̂T{(YCdz7810wnKk`E/HTa`IZO90sڜ2}j6*nW+e?-к2Ydj.ұ (X1uRԳ=; y޽io Yw)4'. %!,潔cf>].\Zb|X0ʑa/55k4. rOU='n"Ntb "7CT )$K5V@W=jKhp')GcxG GJ~H6x7 ?z.B=&Mo n@]7}N]QNAf"df4o0ˋgLÇNiU׮!wvr{Y?$c-VɒԖxH q=*0#AÚ=ZJJ0rѹ OoPjT8ws|1iV.h*7BYx\̝gK45/ &; ]FѴ!p"h9ѧ'a@53O 9q e;蹽-Q 2f,դW>֝(b›7?1jSL7YZ/˶+9mDmro=]} angNbgQe1U{F't7/%zu S !IDOsI#!eH0fiճWhWBsm]*_:;#C3 BYMew~.ZTW|UU>M~:p/)9.0H&-8\6dƆ`<.g:R f:#B=ϖ?a}nc6&﹎ SXCW ۂ4vf;C`:5:&'jq{Xr9"hGAQ+TQsm` U0y_ c}nj5g_C@^ʭ97H |R,ge )^Ypv'Tx66_9Uڻ]'4_5\@4!6;zi|]ZHb5]s_CfCnYuC#(E)ǶEiEOqقfK쑰yЭQn˓t"ۣߵ 3&ɑZ%ۘ&U6_ l' q ]Q*$k ̈d~}#<3vBIClv4p^ԹH`M3 F Y~,h o[:5ɵ^}OFr lA,% jgЈq;QUE+pʘw*~Pzg̞\`b dڠS2 ]6"IXјTjsW}dFNr{68G&N'N:1]giEfp]H5Rӧ:P+ߏjnkrQ>hd.?d0G).3j__2lT$wg1Œ֝Tj*R?= v"SD:W)xdu/(p(eX*k4.Pq]}ˌUĜ`E${Zzq[Vg-~^ɮCXm~c>g]sh6 ܄Zl:a&nyL}ӡ~=Z"4WI,GrE&Eݠxk7yt>Z+OEw^ eZ;JNfdzDs>BwT(7̰,OR+&gd t+p490|Z s4$`-!Q^[*Od}WS#֐ؾo [/}(ʿ$)oa^D{2 jL_7dsD`mSȓumS6YzT*IdPhr fTJpڟWJ3Iꐩ$T"W D|B!۽HZSG^FGNqS4Dae2'ր}Pʥ%F&/`+a.ZsgbuT]K35QOF]0/Пx[|"uꝜJUPeˡvUc}6?ݼCVp2N[qi#XK1RTXZ<\M SUjp>&T b#Pu?[?+fD5Ug p2 ɑq=?b]3ʺO2&D_q\.LZ剙*9 An;)xd覆h)?P4q4Wu,;jV.>Nx?s>#йY+bsmSUm!?!h/\DhRS)a4ٌ?}n&A2xVF`?ߺQ}uNNuaTߋQ OFfeTJ'Y/I -ס+<ƁK aWiu~Og>/? `!I`.,XL9 3Xd݃!#m :bU=G[c3bVzPҕgY.m8ERnN#!LR@A6UU8V5 *Nxr}Yх}|T#Ń|r @@s~tNUN5G^lTm递 aRwmpou-+%OHRytT8nAcDͦfKVY[9B$۞GL %1IzIR|*Y][w4i \1qpn4][6#UZש@I e_ OKyf:P8m)h x\]R8::_.-Do]w* ҧ+D~#a^6"7kW>=BJsQ^WǩRq61}U6>qO-ߥʢ eb>s<۷9-s|fmH-T~oC+}>hpÞ;xl]raJ7vݮo?Ĺ=9|WzPⰿȣWn;=bOBib7gL 4@?T}&a;w8`51' Ɩ%!`FpsrV^v.FX'vm cU6FSfºTZ>ר)hzBO3tTD7lxVsCx o]7DUW+MgHzNgӢ|56Dy|KYCHCqZ)|Gp1Z@R|aWҵ%9F:[D 4O,z|3h=W S`h.hwt9n#'zĒ}0 @&5_p%BV FNT xu k-#GJQs _*@g}O;f9HN^P/wi6j07{YĿ/6rR4f|`yte/`*8|`NݪJD ;X&}Uӝ J;Ձgw_iΗeS5E'Pw/dW2Ư%Z\NEH>vLk\P5EL w|Nk IGŠz>rjE֊70l0M!tuzCs6vxh)c(' *dhtiheXꒈcz] Xo m߳W;=wT?"Z1)L'0~o(%v'-,^sgr+ JރJ[.T#_;a&6T y00, L<4=N+k*(|/'c?#od??^9绽9ЎX,l1E5NYerآAyS,P͐2XE6/q30AEGvΠQ# lUSp0 ߓ <е{E|'kwZ1 ^ U\pz < 8a +gp0/`Q dd%U݋ls I勖UaZs[-Er$c^FޱT!qhEoge0Di1ULɬ1wQӍfMWtTVthgs%#EGȚ |r8 dFz\;%`G2C4;vμJyx]Q<써Cp9b?O>ؕri)`6GW/OBR3=rXH1C`恬=?xTͥ^m#~ q5WA>G(Fk䀥{C^ yʃ9C Dәmж@4}{B]F9,Qhѹ^?4i+Rr42O:00H[&q](c[)eDҊAΉ>#3G*kxjuߟd$B4n_.Hc*j.*QL柛2pKNwqя5obʕ 2/(/N3=Pas`M)m}xtz:R8\ ;Ik䉃İ$Yv@aU龒|_+TOYbTMqNζZ#,㔖{G/I{䢣h0#HMhy>ynf1cU$soCA?Z5~]ږ"z]=iϴYsCv7qkvTZPNDryҜT;Ns`2748+a$=WvNⲝ2q_+2 dN .-" "@\~Ϸ'l~1/zԦɬ׋Uf8 Z [Y!,6'3pnc*m sIW7 i(%N:>fNY z7(~٪YJ;dG5Ei(zX/lZŐhJ%piȊq- qAPP4 < \c㏒ *u @{"нy39=Q&LJZQhFetڷzuFaG!BwD``u,\wD=xY׆sd+,iEI1ݮHyM 2Aֈˤ O hO:d4| 7j `ڎme-~_$8Ik=0_t2+y;g3=wO/[̍(V[{&ֶAGзmaWN FB3MnR4KY!mn׾kb<IϥZQo8:0(l?X)WvI*h君cPe2q"E6d6Jҫ(=]J>UqOgo݂SVUۡ_*9NНB<iOQ/<gT̏3-x x>Kw*%8#T>QRBz2F_02ȿIdFJ+ 0“Al|T0t[XEg,^R"eezYONΒ#/I=\_/]/eh#>9 )ۇ%}AL*@1uzoP}JyB1#*|D0Jq[Եَ's`|(_t[?զǬ=bq7`cmOT Bºo-|A[9U9VTu!GՍ]Q7^TvNtw/zP OھijIj@TXDSZԙ3AMLO}JyPf\%DӐQW;nndNKX *VdAer(7u-SKA^ºZ{g:.%l*4ȚW p58W)E)>`_J39C%#eXhv1G o~7d=ڄ=z^#ݸ3~[?GҎP. nq?kW,$5#/2~!ȡX IL=ڸxtjh'=`sXcG?*ß:#ZGT՚NLdR__Ěo{NGq}1I+Oog֭Q# s>pe0҄ {3Y+8Nci#Thx#i[Vni65)i٧u-q[t^JnRV mY R,0bɚRaj Fly~NBVޅ^ Ͷ1aPcC3.# /~` -^lTsxTB}iEIqY ፫zR *eyZ׋WOz_&݈EcIsOF8K0}i˞N ߈F0AN ;~='VF>&&M4Vo#x-aCHDOC~g>VMA; 2tTa#Umӥ$Ģޤ"r5I$wj8WN/-cjw}cך#LT-Aq DFJ&;0f!'ZmGVߍCHF_4dZxʀ/-3ө3JGNN vdueh//1OLDuqPhEe]uNk794b> 8#,Q ?,AoA: g*Le!@I䮦7aVr݇:E~L?pJG>a &5.[H]&+,eNXL ~3a)8:0=.@T35{x!@쩇ƎFOb sצgduׄ0#Q'6BVk$Sf iXg^8Y^rII|v0 㫯D)yV=E60au`{ y[# 2ˋMa" r&#W bc9z|j6ظ aچ-zk`x1Gn^Gp q_K{Ẅ́M28빫 2W.A@Eqh'{,VnQOqN1+OgŹïJ)kڐYehW~w3K3Rv0)\t/ v3 > cʕ?i}YZ7qb;g'd0;nߺv*pDŽ>sB t܅ܖH9&xOf k[ {N%O;Wܨs%#MN:c vBN:ŀӲd Drb]kS} ŀ 7+JCa_R}6)9^ nSڕתWf4:}?L; Rwi1+pwGN/dN5 "g@{.% /$X6jTr߳ lν\2 ]&!6V{뤷XJ4*Ƹ=@5lFR}iݔTP &8ߗ5xM`է].̎)j״)03b`x9aύ]׎5_jݫ4ɹlTAfrCeV3$6%_C͆Ϫ3j(Z;V7x?s 'k"}o _hHMԁ:/]q2[d AwH5v{;a5zcK7CCU˦Iq… w.r%KEAм3=o|a* ~K!VftxRf~ޮ⺂]3L;u%7Xџ=UoLbWunRl|F$MC͕|1Cm~}CO:;&b0Nݬ=!cmE->xe_& *Ͽ i+KP}}WQb ./0)YA ʌ&ԻRZ91XP, 3t PIymM' [u tnRnAi>Nmm+70)zʫ_ː0Yٜtkga~{puQjl]/)jtyb[3;dF1i)LBVڸ=`sm\a-ܲKMy_i6g.>l #Mz(bwS?@RVp>&}Bex1IQˑ1)ֆba-ښ\Q3Jb05i\$-[(zd*v yqy'#1C@tS%zpe -I_K3xb"&YߣC~c[^xAʱlQRX %{HI8?IpGO毰l ?Z`]N_,uJTffՄ wPZ$ lՉȭ!SQ ~b"GI:dR)3Ü;O { &ہNkſ$2U5ۧ3Jq d;> /d|~!_$Q, R 2cGrrH3.Gz3!`|dD=)!i ϢYno"jxҝu[I^!_cSKq^L shfw!58#O/52t|OkӜ݌y G|OKyS]On 3lM$r|&ѽL+1 .3;1_gkA-)A ^~Nv*՟1ɪԻӛ !]T@Sm-Cs&~i) xw^uܬH+KUw AD{#E-3mMW=c^RU!.hsEu@=`(M-f[drj]5Z"ޙW wzGt-yVX1:Q >Nk&cZ=qJ9~<` ַL*uCYL;T~m=͔H pgH[ǥ+9>yGXڲB(rٔ /v)~~;1/U Oսbl?ώ:.xqҸe *ZuXflXAv$EAL'x98vPΗ \LSn\:CT2ҟJ;Ċ=L6IEв-;;;Ά49Mf3clg"|iy\p=EK Vq5(Š{ڲPOZ7Ux+~XY7C7+EJ̗Kcr~zBU2̛b|4qgc;.@NSV_DGRF6u< ʹe^L5o)DEu9;o+1fyJ9ӂIEFN "O P]Ϩt#Vmhh,KX3#+:Cg^!nE\_-kk|l+E>7yC \΃U~68rm/ ^"D$ܕ"RD2 I /g87`ڞr*DUǯ@:֙'+vƿET2]1b`%;lf6r70k7<yάwf!W0*sP+ѯ'Di@񘽐PV]u3<[xpJ/M*IƗ/}X@ [8P+2}gpD{T_1(f Ɣ__[UyosU<b~>-վYÈ,? P@x]#c. BxX0V$F'š)m'Vl{C'Rt M2BۂsTE-adwMč]܆zϮ,/;{:IwЬ)ּc['@эN1l~%)euo<+LLi q[ e |, MTCS/{GG{ h藕H޲Pxrju޲oG߫#EEeW\jKVk]Ƥs3p{+iĚ`ZWSG4+2Z۱^lk60|>==L40eʻwΚi8䌒RIɗr!( * [F=KU4- b>U6I#C=b`7Dy=b)^(vRuPri_Z҄tqT}qE #vh0ȉ83o"֙d3woy|c8V'ݖ*_UNLd0cK+Y\Biʫ~>cFF;XApѝm~m,c]ZLBK>[`uX:JF멌<-+~̩+B`*_vBszt%sC Z80βr9>iBF̾hs ]2#>2Ž:RÛ'U~AJ2fPR%ݪX)_%ޡUE/G?, \1 sm{Aȸ}^ܱ/nu=Ŏ/1RWl70!=Vtu(QMꈡJH?;޾֯:>(G_)Cqkȳ8R)4@^?y")dEzG-0Fށӭu}.> [˜\–qnlA<5X-2[:Md4F''w5X[O,kֲڵ;<9G'7ؙ`֏{8)yo(nݬ҇uE#m1  6(LS&AMsU=/Y B D<$_j@?滼,Rt f\hfT I9Z/Hm.ݠY>>ZHS[yҵ(7T)P i5l-hg`*" KxbV+0oM.+s'*Z+䛚$-j{8bar%@j}Op3;!~7kG`$3.+W!ɞIU j3,vTJҨ|톓v|AK^ݻ05g1 FEUE^U +f W?Sf#D(vN}Ig:H(.C4z[<̗3O+Sصy"A% Y9bB npm,.%o)'vf\Sd<^-26bg^`o- E+Q , "ݨ-O9ik0ũPZ?z:\7E[=NGT jtfL`Պ 3) H>36ZMHBΥ_}:U񓈑{yLwr8F8][};k#@Kmy+n=48W:0ip ;i{_fB}z:*9a*,v譒>=m^TRL2z`(W S z.zoo|9CB9H"MU[އN :Sf0}KGk4q-jބXV&7_"->u!k߬} Ҡvw=Im2ENsK3v 22dRbI jE o,'A~6)CDHֺ @)U"4Y2瘢&ܫ6'9cC @N3ala t 7܋ΎYI@ԗBB|3ZN+ XiO-;Q2PTBL2u)%Rz);FqL-eRL"|gzX|Eʏ-7અtuaC}`bHַfP 'O t.^( vYA5qπV-8aJohYҫBo afE2H2ag;&)s)4܊{RFgzlJ^G8]\!6e>P$n0zuC*tRپBMUTce!Qd^PcV3['alvTmoX\7Nl㷍e0ƙtQ3o~A|E,Fgv vUC, U}TKpiD|"Ea1UaQnfuwR+ ;%|9vKE͚G6& BS_+cI`O GXա93a[<9.3--KecT >./XjCjS^+4ezlo_ }wm4LIVbWֿMGL?:}J /p)0cjwe ]t$'ge%[~[[A h-Z^G 1%4cY)L՞ppYqiTΰ W8XH+)n܏@ "TQ/Wl;,KAfQr(he臿M g}EAʹačU 7wRoQۏ1͜1r5Zg*&N^ hMwzzdLzX!+@:+ʏj+ :`IvDjpK<CۖJ-/d>6_uܔ@upH瓯Gn Qdi >z7{,CS]tjCLSdK iJ9+R8AеHw6R-Y'| !<=W\={@^~9w#kudrh[@ ʂ"cR9x(`C}hYǗPgDuW0#RmS` CeL P!-'Ó>7]齬:ϫ-p^v3YSl5]CI$b߷%3^2=o$JNlTqռ&v++ v?x=C}3ɓP\XXQBs;G2>4eC?R"x]kiW!:3Q_\")0ӄ8udOk-6j!OD)(^%n3 v˟olA,$aHI-m*JQ.έyM3S28Gc֖H8mf9L\I6dW8?5{2UB :xv]: K+D&' g=Ag>v|dMH 0T4pe/pVH5*D1c; ?OMfT<¸ʛ#d$9dwTWQ]{z᳔ VFB1%6g=>۹Oj0^}E\Xr'lX.hm\C|hg[vu)yIj|{$dLL>~`CbB8H s3ʏ垍`K3AeXDٸ(0Ob{Ŷ KCV!=$MJ,]ΎP oʰC*6: %=@c0~.|5< ]Z](.21>m)k2?w _}_YwUW V^`O^!b9oXbSAwd_|!:w&\w[2IRôTe *DY_OaiDR@ lu>P#|!4tDX~ 9Q/BSfmgD3mHs_ȡM^;œ5fI4ٕ/kuu\|hzt{D}s;xp?#bbo͇L~\nN4&Av5 A،:%*v;WkD4ά`hT+.fPPê$ثi#MZcw7-4˪'Y| \-cnBC,]4_$1Mb+;ā-W0%ɐy!yktxGǓ  5;78ǹDžhV;Zra rqyc]P/"#@t[W7UX b%+ٖ)h pNҪ~Ѭ?vko3]Z0^d3%`?Wmh[ Cyտ{RFhK8 4xdGL0ZE:4{>TA-ߪ'JoXH\7n$=+ ;XbG(Z;;EޮRcIU,;i;n/=zAS疪Z=ܛ|^&ek`AƘ7aN4O"͉hENQ%-Z=u6wLsYUkB_*3GeFbm2e- ۫Zb ۺs\6HMyJʕ<8zykDYFu, 8LC.043Rek] 7ےZϩzeKS O?8$|)J)BaQ}3d{έ@N/87:YvrU;w=DBy"L9L :r+͓/:ő/b*VҳM5P<> -1n(-jGBO݌$2L-3a 2F+N嚎<لQlTH/}!>[.kOMXtoA۞u%0JGHfLA1y֦2ԥxBr{DnָٙD^iC.V@j9] E8x󠀡GTf>yk|FQ]L-^84ח9nuD(ԑN+z =jO%}ҹAHH{o=PZb.oW 0DUF̐I$t! e H􌚪B`BΪ0 jrMCqYg˛5&(xIDxF^2Fv#̀ &ԆYxCW,.Cmwƃ+Onݮ$_,"&/õ6=o=0Of,"ҫR '0/vA IGk8o})%"z}oiKژJ Tɼìk<\$̖%rb1꬜^.g3kMZ2r.nÑF 7bȖ)LͅH!BRv QrQ<Ä |}>+beՄBH0F= r麠LjR!kF+ЍzJtI` V'&|G]͆@@y,oP. TpM+{^!L *]}ol[󵁊6à 2~89gĊBˏ^ $BG@oq$#ύyS q;9pN ]I\7YBӔe ;=7o!t$WobQot~ay/hƧY>ySؓ:u7}Bn! +ѧW3qM^NL=Us Lm]a5'v$5 C_v\g_OZT\^MIpUJTd; 91E=3Ap WaFjp+բo_iu$)τTy#~4ѓu`#ltKV+jS<΍x̄EmQBkhKRAQK{w;qˍO\v_}!󕿔;*O!yMh|ߧ-$ہ٤]Oq]&f 䤅gG7i/F!L|#゛Ç3@\).G/_d]vH1 a8&`YFܽбAaʢ0D?$K&^1wtwQc<]MCC;DqpN"5Rvo.U,Nh%6ѹ:ml~^*`|4ᶪm!w4 uRbJ/>N@s1aR6~P螢VQqn1{\Pc'}aTF{Ay)5ݸGެalFSy 4 .:?f;Iv'*"TCx8,p58y0Xfp&x+>8 oGS+aQXn_ 3'~ [;r[ OnղC݈Ş!l4@CR2$'O*+|6'W?SH&Bky@11o bW[KZg$"_Lgx'+3 hiBჰdyбLAU~O5SÝQ]cP)d&F%qLݡah3H4ib'?կ:3TReP"~ *l3*QMȻJ_ ]:#FÏñ)r:bۧұl8MA&ghHePCЄ_~&+5h|{7BMtF@fa wqFKBz=u(%xjK.yȆ[MoAEJYAQ4^:K-MK`e_*(5TPGa余wY'I@ϟZjQ6v35!.wJ;*R/),iڈ"87j[P.B `Vg+Ҵg{>NwtƑf2꣰!OM'jj ŖFWk r<ͿYM6s%Vi=9֤h'T~>&åkIm6J``pne~}ІXs HkU+2=/o) 5^xiM&!"m3\HyjJNjDix I Vszx 2C3iw5ml_z" X+F (w@] ۭ"p:k04c2di0)J ȥ4t'I?/ '-*'g&;|8VRԑb!A_%Q>`hޮAF~xMŹH -K@ǘC/bKKG)CV\ r_y[fС# Y/֣<V[88jOZJ7]CBL ?vhLTo>=Oc R[4M]a4dct@gj.8zǨLrPbY릗H4u}PZďV0C;aOQ~ƛd;zV*zr;$Ś>Z&L{dq“*4 U7`3U%3*;|ڃslU)?#Ts <2 qOh.Ejd׳&z#^VJh { AfA;`AפZs!ԞFlGi!8mz5AXCji9F`|1U4*F _ՠ('~QH`t!mF=x@cqgCơM:v/<9ZVıBwTy7IĈ_U_DǝOi[5lsɆNЌ#nkaTG n5l>_-}8 }t;Xl8QK?\D&zC{d,vr8@n4Mdm=).[)ߘF-? RmA:Yz'휣y~"]sB{+=hMd "zM$B>@$Xh(?NM[04?gk}][TxKA a첖ᤎk|׈ _؄)_/:g(a$gz(S˨欞5By=E$=f}uP9tz@(?Y#O*3o , Cq 14*řyQ@nZmD2 %{,I)sh ]2e Q@UF"9l*^Wy*ćDVmsM3{ 'C ܈ܹb\OϽQssQR1#<4+:_l"-nk=ޘbarC\ǕdMoG=$a{G=F5dVq`yrTiZ.v}<,"mPBkYCѕuD,^44~TeݠKW3?.69F@^/ wςpAkARNj( M?6MqK<|Q1*(}Uu;.5+m\668te2qc,&!j:/AO9Ei"QLZzФ8,`1KL%{Mť 1(\p@X._Z7i2~MFq;fT ;fdzFom-`RݳD]%Cxz;qut,nn2KggY1ܷަ)4&|N%tOeƓT֋!]HD瓲58)7QJ흸?[H^5Bl^|yY:To#顱ΤV!M ^7*ڼ:WYVIkyf\"mѕ/ _W:>iK-ʑbɲ*wϵ a [H IhۊƫrV&=^JP!R%v8x@nRcJ ~4L^nCWMTHx3]3T8V>/+ ΁MBtWB7"U)!r sIè a_>;OxHY˷Au,zncd%(b3*)Jjt=ptW<ꖣ讕lѺ)u}Q-Hd8(##3{ M!aNա knJo\4^Ĭ7FoT.7&1k1hn"(MU~ZYrP`IY*~(ELZÍpka}ǔ5[+e+ `^u~vOxO?wPqh!%zdfX%Tf^/x폊ur.{% !'cO~Qɐ8S,~0f.}í&`K;ׂD\iTCBpof`뗦pH o2 19 z湝]E' tfUҬ'x38$ J{m " rHq|k=}opW>9`zsP^;bSe{LH_ރ ZWOt`'I[t3j88raI5 Q{YnՐ^j\x_@ZiPY=-ɖw<*]K#7:4jZ9 eU3jߨ^w4 'g'l rmz-@>2[R$Cjէ>h`?FI\,bb b%8}4"PAW_iev7ݰ>ba4_Q. 0!!'߳7la:]ǽ;KDes,|gCzR='#g}r<95IΕ9:|(Xcocs$ dǖ,O,D<1O򑨒Z( qK"6LaCȅl(M$/"ia<9᪯|mu2R[;r%ENG 5aGz2܉%[;l*Ø6扫pKWH봑A!Gg`%`vqIo'VUBF WTՏVRFRH0j%Gw6ʬDdMn7 =t+Tҷ e|޺N=̄[-h2:SomsA%bM$BL%kLș8biC%h,`"<"Uı+^zBXg3T"Eݢ`R,oIhiT'WHYdŕGSuwPH!+F/Մ^ʒ[B Q'. zT"Nk לڛqWȀOɴ5xAI S*CFr巪Ji@}' G>Qt(z cVCX ƺLa95Z>3Hc\HDq:VTtYdIrVjcKzP(;E- ;l4V&(\ "Loico| h]dv;٧ <v˥S4VZ{2bI/5 8⹋dSY(x 37nS yGy *|O*uylcprω6ʂTɪꮍ{00)!c}[,!r7/imCћ3K, # lM,l95@rEmBI1fDQY9GZMS`L6M!JC 3hf\| D.s-"u[HՓ{Ϸ [ )k}"^wM:3WͦmZGw41x@e fDނDKO@ 'fERb9;[a=! 1UB[u{@21yR¦}Lsw[o2k1.@-L~֏ܓ;+cH IaaG>CjXF/mRJ4IVmtCeUL<ݰ[v|`;7u'sAmqmc(Xod]4rEɘ/[pOi?=fB}kݡ:ߗkzb9qLbnZ!caIAs*9VFx`,D cXڍ豆XDaZzR{h\=\?RpJ%J2< bѪJPόʊX̩D6/-_m40}խZ&L[IjR 1r;y,论~F&nlj(MÿA AwC`WraVNL,&rQkjWwheBNL|[6"d*մۉ!J 8JPF3MH)2f&x(P o,Njܥr2,H\;7YY{$؆KPg#1;>+"7z#7~[hϢy>SE. 2 y`]~G[{b'oጣQ最0L&Y˼3#qf,{Y0zpRɇZp,&o4EqZիY3PDauo#-L )VLu"tZBj\LvlV5!#Wy*s#GrrƲd8N_LK8]N ߃=e:\Ho30$\YM FEvȧm 0dWJS#^8 %LS<^ j$HޭK45-* Zݰ WPO=3Q2Dо&V(q QJaBkΓ{%<`0/asEOK0 )Tk顗;$zD"x(܆R`޴ VYFm*WL[ -=zNI }%nrsG&HߕKQIfh7޾ˆ+g;}rVuvz,!_G^6U΂$X(㏮E8߽TíesXux wenr7kݐgSTm?qf#,:uh/GBd(FV> ;ngZc/ TCA-7jguaXL耥a{a!m4o(AP14Ǫ̢@'4cs K᎙ jN)jFk &1BR}`mF֛bԞdˡ o6Ѿ1>ҩw.sN_iL>TcOK?+ǔE$)MGM&ڷe?"Q+Xrvva7[Yv: "RZ:SoL"Z[$He)eMt%աk:NNeZ*7ie$Τ};BAnE"$?Vnob8ݭV$X+=^qe?Qq71( -oa\LŁhF pٜ50w}JGCm&4i(j#.mc!NNDϰ2*ntQ` z޲Ll iChPԏ+͇)Y%_cQ-ĝcu.}gLv2W8qxtLX̤S w-`lTd.X=Fiz"I޿Yz$R2}>6/`VOёQB4K-ʮ'rAAbj !yrݚx_ۀM`(P^V˕vNwzW+s!JԼU,?/о=b?ŊZ Wf0ZlW–kYfK2mo69:)tӯy0NRPNw6X^cΗ񈿝2@#qpc3I -49& &ܳD364/geHGvg6\TMՀQ&!(r |2[O5cyh~~xCaq6ЏH: W&m{l@T "=%`w%횥 ^lCyATDrj>Q1w?%x:js ?PWڲ;2DɆ5UEhҗ8T_td[QH5R3N ij(2EQ+S=:|X9ҳi+IQqtyڔE5I"L'~b] :"ӈELN6/b\ M΋Up,C=:15TK|L5ngIĹ=E1~+xlAKut/oܠX]195~w0u8 G>i{ nl&: #P+H(gbfs ؙܾU xr/[+' 5LVdo*n,p9.#UG_ vil?qŵSp-l3U^1#g?fg/(?q I": ֧:fwT'$?scɭ Dt9 ٢i)*ng_rNqP:!ULMjq@5ϲ8 {QBNudWcO[wW9jcH=>lI-8gQ /+@](LPz9=c\bZHsV X&QH&(01?AI4D^@j,jyŢ eE(p-сdnnQ7>)& 7bL5ܝ5Z'8G8m4C'݂3[G_,@nj5*Hoa0HIkU{ ݨ"l J \P~1,*dǞ$l$! Rj8Z7Q9<9jN4Gۢr`FDž?D?LF[.CllGT&gܕ&Ak ~lf0eIJĵvBY0~G ^JQ,>f4 y1EUmk틈@ OP+U.&"4әx^$88˾?%c,h?d)>gƮqr9)x:fhDī,q3++YF(hnZÑTH0),HzX7úO ]e0x>;u_/IVoH cن]9ARP??x'YLBB?Cl=5) }UBF(YMҞ\E޷\Վ pʈv́I Y z 'r^sF;EJql fbvXZ?*ͣ,`C )x=w :n ? sCc .F'R{ W&v[|x;Ue@ Υ`c7NzWLnt:V":lӟ/ȿc\nר3!}0O|]äN3ySc<ޛ.λv5( e2,{(V"7ja((Mm/z's,Xl2#rœo!oVd|6$joGp?[*CW Q˥U^<1xĐt "}bE_aFe_5%U<~'OԴmktl-V Jz?̛c z͔ʒZW ݿIB'9ޢ43 ۡNkIj%̗ ȴ)+% iJS{})Ǖ/@kW^bf 3f5zrV|c1qkLf(n8(AsAXQ)cb=PjdԱѢ&^|^Y?iQ|BӏVm/" i ?wb`L41xţjjS9 ف[zG{ʈ$mLd‡rIM:0*n S}n^]IVL&h]e\ћƧ ŀ1㮱]uMn%|[݃RkmLp\QWl.LBUJPԜ?^;Ѯ,&0Ç0 HnGEr+LC:2׷f@DQS8+]` kl-}v0ynˡ jȈ+kfV~iD-=d.P~B>Cwe ߏĊɔ @-o1v4RĿv0t0FT1JG}5G+1:dpUf*~䫞"ZM'/y59T@MɳiYl)튃⯔<භ&H]gOhg_Ekvr60MrLՆL%< Bt5F5_nqDO9R.yxcU$9"EN8LO-W@%[Jp$pDۘUy:q`4 vǖ{ 5)3-DtzpW2Pj4FV+*cu\~$rVb,"]^j$qaIf[S%F萩ooZ0ާVo.SqnqMi_|ԛթqx b+qpcJXqWbq?ThV&s1,4D뾁Dq((h)՜]w .Y-M#DK·9Ήq0-3AO -=crbf)X1gcǛىUf2#Ʈ9~K)U%pB\wm1(WsS"Cۅ`S1saJA?IѬ0 φ ݬԨp߷}>3:3%u+6x -xZTi4P5? BV4Drc; FjA=2]_7^wݠd}ԦH/$I%tZ#^`ʛ{+Fw\\^.\/~jAVů"b?>11,:^τ~_#P Ol:B*Ԗ"hr' Q#X#Y(o!x9.\r$[qǸ{vMPUEY< $.i0 uou\jgi@c\Y@9X ⦶.M'Vʌ?9hbtMm&v1/-,0+}/zӋ5gwg%neb/Dc- &\!fNWiRgdoA7P!C#lwCtOU.e p` >Z38}K~*jO%[?I[?Aw.Vv;&6'U-Ec.)7BF88rҠj{S9db $#e_Y؍ MvE\:9ߍj 7?<>(}_Jڀ-LeG4!;vy-dQy> 4 k7Dprm|RM\\D,5q~ t{QX+!/ { RԦP9Zc|4Wze#}Ch,Z&ARq2rr*{k4htk@\<괏'%- :w2]Җ}zr(<*궿[fgZ39bfoovi3V`#YvկGG@)hy+.uVXi-*B. dBSMl@jNaRŽ~l?~=[efSA,(O!ld,uΊ[j1Q߁6Umm*3K}0F'|hG .n$t=ԉ$DpdoVϝ)'aK& 3}fIwsPpb2o:Fe1&%6?1~Bh cSZbszop:9[R|Yɴ4C#I7Hٻ|WXEWEmiF?_L&qm$Pm'rɄf+ LY"C韀3: YZm v:Xhr4WfOgqbvt^ᑍ"#OCOU 1P >D5̴#E[?Pƣ (FjL}G"9qDƆlRl$[r8O9|Ye##O+"#c:ؕJ㳚]\o>UMMZ59FWװQ×CLR!aZ+BBwm)jɉ~Q"L$Х d^tIRKߧM a&Zb.+nXYQ;$L4o)m/OyOhI`^D`d^ӂSoacb:4:gCJKOV9U".=JvӮzfwkHdF'|@ )( 8qئÒ;s\k2S, GrBW5MB-| 'Ó* BDK&2v@VO#5?_<\NR>$6Ȭ &t&mut4^amv>U{Or1h -AC,IRu~Q8.8xB^$UF1:!,§˘zpQbz0Xgu`pl[8|'ut!'4ڛCY:(uu9"3 0t͟Tф.G{m?4uMs`BrV-6mT"@LE͜DPN7zqȾ60ל#~xuހGx8BvشtQ[RlʋQnM'35~M{OxRwتT .*W`OSzAt6/ Tn/1A\;6`ܴyg =>y>P$uT2y$0$ /Z ^IJJNy sV;0+YOv#)0݁ϩE*nilpx*C@&ғ3hajxE('W|0ᠢ8Lب:+; >PbHf:kMw!A`>$UJi+K2a:/ K)D8?r̷"laycS*5'?y/8BJtVƩGȏRSϧQxe`w~jURWv'D?{~Bs,'v./I.k Vg̗v4-&f|BߕyA L{c$TScUu0HrAIƬ'E(/ UO(1wSxù_e$6EZ^Btӄ \:Z}7T*sMkP{Jg̎bp/\malNQ&l8Qd&3*PZuS_h\&~):Gxbc*Fn`eNglD9lLIa4DR`aښWD_eQ2wZ\7ML1zSrP.]~CRӱ&}J0lTЫwސ`b`"U*|\"]ݚ,wudy̪.ʑqW-YLe:q&~N%1$XKJe.`B5L~tA+a|Z(d\`cux o2fݮ"8~ߎĘa~aǓ̫"Xc_>kvAy!@3#_>*oR?^mE?,#Ԍ>KF|ܜȨ1y U)6%_FrI;8^D/N-1CG5 [q.:b a-d_gTS@Ju=IJ6ïd =:&Scϟ9+2/bW!O^FAcS][`1sL_p\3(߀}rWכ4(Gvrw 2vL h? P+.nΜsmJ&j?g'z;#E ?+A(nK||9/&Cq*ZJwhÝLDOCad\TZn/z}b GegRf=8Û"Pd^Iu'}<nJ+t. 0CVhByIतD*k<궝楋wi8=) s&5Ԫj:ɲ M{|z7ϋD|)۝0bS7yi[*HT1($}h0΍1>WC<<4%|v򢾁q߻ ɋk9j:{i/(i(`|;c3qa>˥.W3vFs|R1r9Dg /D` J%J?@'!i޾K 2R;`dVو|G%܂\LoW<| QGΓ77a&/}dRFphMTTń酖:~'Ma%W*S',,')9! $ ;>V@ậTG֎il[[<0e6q0}OM5%s`1؋ZE!zgpʟ&7IE 6XloӍqBP.ך?a4|GNasːw?j~sob}VC͗vd!]Kdx#y{V)r#9`1IJUZFX@!> [׀FH=!A8ė)nlu r?w_/NTjP"P>"b">W}y"\(U3 {f@lnku$ѲCM KlMޘϜA4צXF5dǸMϠ^S"Y_~QӠY* ̗L umRGOqT)Y{oo\c)CNHT?\P_%;q osfnƳg* X#QVOyF08+lJNFKgɟ=Cz>\6a6(^qSWB,:ꄙ'&T[ Za= ؑc$q&'= X$3ɋ 0vvgEZ5*L#ڳUB?I/D>gp*Axʉϓr/kupq2W[7 AKB=1>630䭺;K_ʴ\ [YG3xErru[ .rA. fT "l]C5Ws JJ_xHmv7 =3 C_?;:qycH%t\B^</R*YeWi!JôDM#fl0మ2⍞'M7'm1V\|KIn|);QN ޭ[U<@ኳ!/+Y*?@I񝆦4뷔 M1s#"k֪0W}XKz&LICKR ƹ]HW9c;׫>n)6XDQƺ4 G{9 p 9WU sAYyNg 47l0LB~N-mƾ}@M8imu$3^Pa!ec/&kϹD cEރJiK= ۚ}uiu}US?C{GgXntwתUڙf'{•~1⹬ \,PVg GÎxLu+/MđxZC _rӴU٩ԮMZ/rQp6$jIaܞ't TX_:5VuJw ߅|JxSo{9po(s] #p-Q9R7N G [#9`JM BZ Z#?ސbQHp'wň YPe z d 8YE,qNXk<۰s^ z#oJںHjA)U3QB횲MT6 ~ny`bZh#n@A  YqmIb eWHK7+>r8V+lM:X l8|h//igrk7M]pLTSXY2;]XN"'_O}DWxT#-X>d:]زaw[]WLk97QH+^6x:Bq7y`~9 lT9^4׊Jtyc"3Vŧ&:Cg}zav <) &v}7򌵚{p؎D=߷3%HMV! W)S+'^klU`AZ.b:h+E8cJR WX!ҡDlP?:ywK $`0c0Ht_p /\FxoO o R>ƍ7{HA!nsd QDݢ%~KOsd,Nj ?HdSXhסZH=R’ D=vg#K-пXrb2o.U HտNjDCX{ ; 4@;XA X.]keP &ܻ?=]IAw/qgnDN6BN&<}~Dzt\Č][ 1Tp]ȥI3)H"'*@Q4XDܪ'SWsAfqku(dZa^ܑiDŽSNHE]c֣~M<E8' 2Ӡerl (CR/CL%EE79 :5|gxjZls'1(v%QgY-ZӱH@u r1Dr`NGT*!XI 2YXc`we=1<[WK+#rܧ5?^d53N) bHlMo<$l$!b|J3-G"I~Y-o2tVWm{_gk-ɕA`- mQu#Di._,xfG Hcݖ3,t ت9zW>YV'L׭| Gg n kiHb pH:l4\9#/9`_[-eIV߾2Gupw"tmo43yAS=["10!Q^-p?s "|0R=^HWE%u-;B%9b:2d5킱B't@WG8ھWN#ͅi5!Pu- z=umu\zr.I vA K=#~|s1NϠVgBv G03а/%'I_SzK0|!"Z|CX9"w!W,fŰ >0ŚKn'bȓsȈuh/&{MuHڒ|N"rQLJJd< y..J(\WhHOdm`{RzKkyqPN8@.ګ |HQd-HfQs }l2פKZtq1aX7l]\=g<۸i`cXO2qU* 3rBӹ2,zrATTx H}B:5(MѶw`*&Or)QS>[aU1UK?>8U&#U,ΈW䊔뗭49lcُ(+% 41 PYp=l~w hٯ$11 & J_>4I^u]S1 feX6BrD@"&bw|KwfG{KRzx6t>dΌcC&0gF6, n&p>K;<mvXVP+ .Je>Iy,'M3lܼppi0εM\y~SW!H/- l)I޺;ry plˏ?H*ZXyʯoC@1S31)-%f޸2?Ӵ˷?#8Sb"2~_ηj!QB2Y? 掩ˮΏIZ^+وk&QInIQcu̡ ʗN}ׇ" cr+XfV`(NErVr8zYBrC528Odj{]ZjM-U S J? I5 b 172E!8"5 7,wW19X,X'@Mr[vڱ,{FrXan7h͔Ulz&%\OAkŠ7f@ O_HK[xdT-+jFyW)E0G1 dZhѬmG/B)FJ<޿3`#Rʎ㦨[Zj8`{B冟Ɠ,iƤˌ4WҪ9O*A G4|Ó2|ߊ qw] 2 9/Ns׬_ qڗ ''(-;˂抢(CO!Dӻ[ɽpUUP"ZԴt`=lk) tQJ8.bTvչݯ\֙3,0Nܱmmd$(LZi>TI(h`U¹X|qQ ~Oɜ]c >|cC3M𷳣I޾̹(?<_+,Nх! <+4Mg|I1}AI ːI\@yf]sjЩZD/)]+t8-#OܣZ&bHܸ cUj+m@b Hn+@"K G^B-1ݔxm3BCZslP $]v O'WoZU+rѯ5iʺCf]JObPU^]H7Ѷ?т9*NњFs6C~6qqnMAzM{+yV*-+_\f#p^nJڼ3KyBL?502r(D0Ga̎i(!9U@KTCckC,HS$v`hʐ^KY\WLBwwz@pI<"qzlLWȟzC ɐ+Vdh3=oiKHNj j*rV'mgoc{d*Tng}k@ȱԡS{ 2 S*&(&Tx.K6V:J2#zĸHDJ>[o\BMD8c5,tjK:{h\ŀglC&D^@0D2^쏋 a%blz~,l'xr_sdڗHJy90떗?ĵ,g d;H; ~|FJ]۽)"ng:'o+6,xdwi"oțÅ~\pPNł̀UH((SЏ ?Вb[!Jn'dJꏟjTBm;8y{67K*j16&IZZ>?AސGV-RHN? ⛴QV6߰y XhO'P@'SM:_ϮK.X=$ƐnUS{ի yBDZ`Fdą c_u2 Gp.2a8xDžֽE7a9..(E.)n;9' kI*W2/W[M=:d{ ci#1f[7&ל ī+\SţGBkbυ`DY9fD]K9c" k?JKGBޏ TAe붼HD\w ^BLv@X{x~H IGZ/H~dLHSӌ"3/E4[LK+s`d~pfeXȾRTe)BfjzJ6蟘.t/R:|iaSx RK[3c0Μ"ܳN`z|<꽸hRN4e24طTMcyxbDůک\h~! f?Gê 7 x ,m4fPU)aG7F3#J x ?ij ?QzP"֧%r[' -BJMv1|WY4)=r{>Y,pF]LcHa95y=k.l4=GAiVk@q-"衅e@)n$T ieI ػ2kK8] lz2o+b9G. 6J ޱd)oQ9E4'v1H[C(#&#ibќRVd06> G,i)"7% gXuNx8TϬ!1Zϋ;iׅ(I9BdU4Q9ٸMe%ڟ"aH>KXmZΰLU460F?PT:Jsm/8޼"K BrmZ3* X!-V,yX}Z{5 rjGǸiZq%fhrs$d6ݥd|9|D٥t {n/M.2k ۗ؉Ajpia-[:blhTEld2J4f`_sgb LYuÛXs&TCV1}/veY.)=iUP3ea?"(& l*\Ly%'#DS򒢳[;)BAn 8j(5tGiv,dTg|oq1s\dYc Jb~HNSԌx9W')s"md1Сl|+*mc#U&p6Gfv 㣟HTLE,OݹQ1%N+u'oNҝغ> "/ 9PtO Gtĝd1^Ó oor~M UX.;1Ad\l Y;Zj #|;1Z+}n"Ҭ sG[9]Utf2- %6\~=ɽrz gV)yvE#8ZUG |hmDri;̫x{xކ;jE GYYړN2m⫥x+j{ ְ‹ Fi=^ y{AZ3Y?9/初Zآ`;n[]wLQ *ikc[JoΒQx'7MFLH[gIaLJ* ݗXMaN"NyO1%icocEp]m;8]R\цTN</V ;v<'Z9~[naVqkjBE gj⧰Mu?&1[+$wL JCX֚507&K/Nj#. T( fyʽZ,F6RBII >s-r}eɧ/ aW1J}9qĩeitӘݮ )yOiP.s(#+E0LMMLW:.9$#n@ 8NdZQ )24Rm^P_=ͤמӒ{d`O&KEmn o·97KV9oy#)~; b"hBh=ٱ߃Kc)(Ly Sxcj`|VR\2!+eSh_[B5S@TeH Ma+EQi$ I^blb償`H?J:P*T`"Nb-DcI`+Э|Ɣry "I˯ >0&c{^AKi AWs jGpP&Ddu껝)(qi`ᏓR@yb{Ͽ9ҥ0Zţ:`Z,䱘q&b8;15lmܞ7'30Z̙;۟Wψxk N2?ZJ/\H&FG[,[f =OLڊMqi%q]ǢnAO#Qjz [dmobfw\C-H5_J=}Tw:#B$Un էYEVdżmYǵzyh1O<1G~y`$ J+2гɉ 5Od~Ha<K r9e`s*^$#D [4nN-ňܕ9Y<SGAp7S~x9͓RoK{2jgGEMC ٣S ; BJhD/$I򫭢mmLW{.tꋒ5xJ6J_^e?vKnVj OUԧ8HqHSʌTި"AN,`OB(RBW ' hwU%=!jbt1p1SjڌNgVWXU,NIXC東[6#[q0{Բؽ[r_+wP)琧S[)^@xIٞ0fp¥tl Е} #s}jSJ S7(@~W ! a Prxgsx4бz*A &rRd'aOe&,-iуǯ_W4Vo^nb)L7Zw vUHOIҊ+ߢVRR0ls JU$agKd"E)oRɒCViXY:F|$ g{4N+ڛͼҾ#oU(~c}(xe Kr+m!J>ĎJd_ L=&k:cq2E腠,D[-s{d GB $8?b:͂-[BZ2fCYɕ˞^a?vnqkPGGN툒X՗ڎ]~ꙃߴ~5?Xi@X́$qaJ*GJEb6p;sa-m5βXƪ妜ǩ,rrZqUƐkdlbM$oB䄄^Be_%P*m$m~3o3>RXBx:J9=5yb~o{ A ^߮08YPN&NliYG|dٹqiIkstfӆ5_xJiI%քwoZU7<=8#hHQpI-ڧ*Zl&LQi94\8:V }/#d;3Af; fk]df`tާ@{kXi% t-[?Z"_JJ,ٍW%uҫH9>G,.|Df=fYJADA w>toGpǔ _5 )sfY mTLA m ]=D տ7!b.҉B]?y j%]qBSs͉ku}v&$%Ư^8?;uz5*[SFYjlճgب>07X5__҅-hCo-PŸ3dv5uSp v"g p1O1( at-E'?҆XC"  4s>x,֬2{z `LG4([ [œ12~M2A5'dL]pyA^f&Lf.(8 փ^g {w@딃crW唐a `-4{ ⸝3ׂMqDZ\XOJhly-Ϙb@;Nxl8$s]}GYNzsS# ԫmt#F-8XdiLN0z1TS`Q5]7ugGFI*o ʍJ0u(IcpMG;ꌹ,VxiNDFZ[4T#6^݅K~ M]pt"ЈA?+r[.aH8Ny-8rͤPb1x~{L>]ԖP[!ͫZ~,W %9Y!o(KE(|H}&qm j UpQ!uZ)s᤟hn&p`ˉ:\ }_ ǨJqiq:rLgAoK^k?1z \%r J N Qm7@?@G2y !CIn^k% XAdE?Z=/p{Ppɏf[!gI$D22Q煙nFiқAa ?!6j>%Mg*B%38L37ZoѢ[.>-uDIWPN𞆡zB\49_J~6X1aHtԃ50cRjom.W)ǿ o6h'HU0mTֆӭU nZ7LM2$m!NM3"ϫ@@}rB"? j=ÁQya5rQHtC%2[djb;ʲr/+_ƋiFKKC9]T2T8i5dڷtBpF953ZؿL݊_58r85D)'Oy1`}CU+(D%*}&")(T'oJ.LFĆ!'tEsК e>Rؼӵ!u be ٰ`3 zHT FZq'\[ǽG;HXwd]ܢO0\,q4 L1 艑|_&>2EGwǠnG=$fⅧ~ꃹ;]d}H{KC@p1|՜Eݤ`wuÙ7a 2Rb/J5iف؟tvϕuQ=b׈MMr:Ҟgc"}i=m2a`Ѷ>a&stRv?Nmg(yY͜zM+&$aHE6hr Jg&SN QW׮Wd2si$2m݋ߢRcX;8'5hwR^cJ*Eb`!8~1k $D=8O:}H[rϺ8fJз6NH$+Q/Sex{4)LN ~!A-h?L=6XyB8(_H6FܵJK՘ƃSz{}TI6;4'-XVFd)I?s{iS߰Sm0WXd=F*:NH·2H >Vbcr0!?Pݍavf3?GM( p)2/TJJQ0}^> t[o:Z//}K!}!jg|+d.t0^ ˏV΍`-anb?MB}LSp~ U:cP3u-:egI%|ILE27UԢwt4QSY|+2|d TI훈kgsc} Cͩ|92jRp 2)ړ2aTmGq=N1fZ!-]+ SkAhe(L!Աx7~e{;ӛ֡Q07JGD-M=И{ ebHGWjM_$97@ L͡.Ow գ8,IhZ m1e##$M#(F[7$7#ZRMNX:7#];&7D'Ҫ";iu5,]Sq ʭ^fUʆ#UQp S{;gCQS`*fXO/.5 .URB![=&וtȞVaޣ,0E s-͍b٨!`4`dcf*UL.dua{ˈpѹ.g )MlɬKr@H..cDCH-%[fT|MBf0 -_\DE9W$K1鼤cATx\rvo% k/4 xQB$oW?V%W%{T>=_V5T{ON[?iG(rb__D׉+ QeBإ^TkǡuГCc 1`ZJ\or59xXz ZjVOqho2B-pⴌM/6'[`m[π0W8osQDc+QgZ@%$-߱3A$e`vw#'}կ4r3sԶc(sѨJ~656%@#U6.f^1#)^伈6blMV{ץ z?! ŨaՑmo"OPfS"u>rD jh<2\#U~|OSQ#Y~{%UQE^xu\_bf7a?PêA$FΏG;R-GJi ɀ*LE;yrb XH"JG* $OV8吂s7-#?d祑>/aN'Z!M}Lc~_N r1j2GS>.Q %e`[w\nP'\Ɣ*ݹ10N@bfפ3()VjH7:yv/B?g<'u7W~Cȋ`I×͊iLQ] (~gp!o9i&=dLD]ZNkWF?̠3/}w(;ƮI6&B{,A:r5_(y_n>{w ,'[Zm]6T-IYKV>YKu%m$5>bGӛW _pE=#UShTFš)q;ֳe)g'd`{jXe.t1}H &&A{UQ MvTD܂휄6VF x'I6S`O.͔O-(tKOFNE$̳m&>@ t3_℞]vZM(T0[yeu܌PmlP~0ڧ<_>gADi è6:{(caKGux> pzn":|ރBEÄ y:þ٨ò`>Hr|l?* 𧈭F^Y ~siT0uÔ;w+23,v1z^= ^xlHc)26 -GŸtpZH.!$#Vȭ<%=Kg~4q&>%C[۴_WD&u64s/[$RBkUI ;I2b8{O7)cc[ꨖĩLY\X.Mѧ (f[W g? 0eAB:MED^A0Sz`8Z)`d6υx\>ެ1 l3A'DS[?wKdz jrP jgڲCN ݝ+B[ܿXdrP q}rUBlK'k]XTdm 6?]~.y|t,_(A rc/`ncXg,P*(sjo)vfOM2QEr>QՙM)Ԥ!+,?7&c49 SO8_) `e۱nɋ,/I&ԖMF01aʣC8]<> 4{l:u,Fʎ\Ig-ceDf" `SpTb0hߥ=teuF>`*UM}E>Uб2q:&FƎ?q^cX|< U6xX.*7  |uD\2jط |?"JN&9@ K뭀 'Eޒe6ө$%~$ +t~gGtp&ٶY)*cHK p=RBމ"s0^5Tuyp@>Q 4cg7&'1xVf ;_l_%|Tos Bd@3#;*dƧ 㔳gkn h= C1$r6Mc-=]"N_Oo.{'J,XwYMق:VvRkZqI79?XRo㒮UWeLoMajNbU9d-^Nu-ȄuSwI8$*-XtK:IZN0DwZ}z*]Hw](K= _,\m_~Eh>CBCЏB˳oUQ S`l^+S{y2D "?Mu3|qj@+ hEb~@6β]39LODcmuu#3o#DퟪΫi&%90ԞלHIpRŮ{] W FxR gԄM)IςtF J4 M_lLG3TkCbi 8xz"uKAEuieE 9LڜBAdZ4ˊ[-Z|,'3 g[ѺY2B&{%6dIxf{.!0.gsf;k,!"Ž+DնJhhb w_|1gD1e^`5cv<>3\|OLܻ4X}D iIrSqMV3ݎ2ƔB&8N~}ϦQ=9WbL e敶{fI({3 C 9+`giK0FhņF.d%R%\xcŸbK4 `2lؼdO?CO9'1V( ԰}ZȖ fw[o"b(lH2Y٥ީ)a%dq-O2GqmjxD 3:,u<0br&niJZ#8#._C kP@ljNBI4#w0霊>MU>v؈΂S;a﹈".(V%eIXA/O!)xN}z>!?}A؀A0&rUU^t;֒bfrO'͔ҠP 2 wf n9rȩɍQ'¿QnjA9L['DŽqR[$ ЋrBZ2yHsC`U(2t{BFD9"g 8s tMd†v` bjœ7y!uf:!TSSG~cB굘C:z0_ < xvwRK܂a.*s8-AGz&d)*LVR99 ԗ~sZj0@,L"ȯsk {dzP>P2q%L,ɮG<7ِ#j - !@^)*A;oxXX󘃱 6xTN_Fٵ¬:.vBIs83K adRb ?mRSdVqh@]T0vgwB! C%mu{Lк c pބ"[bK98(uTakwi%+Xu5ڳ\BX3E(0#mzQp`W.,P-[C%j=׻`T rCQ,vŊ*?)1BqjDczXT3=6/Nn@rVtwă׵Nx6Wˮ)V&D] I>WY(I c5JS膏N9~YAh!S4OcT"^\2hNIO.1!3F))-9C`p_*]I#LmTske+Or6btx qV**v| RyR*x#:w S>Yfd^FVjJUgGW-f xA4T5TzXcm2Fd'%F)zUpp)VG~շD=Kb s?b I13 ς'Im6װaYJ,SŚS~5 8ϵJ?2ܑ4M$^ 4Rs-S>M zHD>&`e=/PVD=r<%A]r <\ 4uĔYbK2OGA&4..:fkhFb:}UZnݞF5OJW3l1rK"G8U­8ͻBa М,xf!%=嵿 Ŵ5lNw˽4ILQIoڧ՗v|&^_,ҡVy,T%B<)=.9:yNgO(un\HxMcB F,EOaszX%& Q}Ix{~"gO38vU*lyQeN8 Qk_$`Z,ӛŧݳ ` SGB ,n196{$=Ck$(K/+oՏHa!1 WۤtrntE16Q! Jj#g8PefEa%G3F<4T\_nybRAe>}(A76~٘E/S uPWc[ 7Z<F1KŸ 7h2ӧ ޗc"{ѮLQTsc~D3 }U@uv]b&X/VfzqtݙTߛK';i)|p7\c{}ٔ:Q9 Z5mA]az7MkU2)[OxKѳlcX|s1c`k&DrwVV/+iQq9N  ;E$0 Wz39. |#hU#W)'cǐ=}]mG{R"c)[|K9aM\fEO?{Џ8.v}f(N?~l 8wZZ>/*^zi,,J0V9~ HQB aju3pO- x%O}I)lͦera֑;D~FJvR_U Q@NӲŲFK{}Ps]2b_PЩ\0)hI yܺxAu h!Ϡ >/@QC\0K4(} AJ('] [=^X-G1{Q>q[xd֊`;LU6V| t}`1{ðuHm@}=+gq;o2_B/N޲F-W^~=*#%썏X[ADڶUPKhqݐɵД4'24i+97L!tfD7jN]8>iD8lfX0DaD!Pv 1rA)>@pf,qe"+eT x;-kB<'EumKI9ʯ;ay&H, OFm~8whup!͏hNcq_r,ώ8@ͭ%C?o I8O/(N>j1Co^Ȭ?C05E \ܓm%T B5@&<8 l2 BjbDX[^ͮ"+3n -7#HD%hrPlAՌQi%0GLaց#1 ]sgh_;bxO)@D-T.;p ͌{ݼGI!ltM9%B0G*WB%Rbs+IG/0 #"29`q}rur!$v7Z%;h0z[)ɈY' aTݴ rۨ;%hw~#ϔo{ š@ DӌjO掎042f9 E;!pMܭ6O 8']tLD8+/s{m3jzg'}E6x)W3F 3."6eC=[#UYSH:|Hrn Ym|[G#ɜ57p;43%-Wb˥cݲ0XnITbg-kR4ZggP'RYU5&iZC+yGȗ[ګ|?4Uwfg\@:+0>>Be7 Hʆ_uN K}vdyvoI6E^ٱv^EwjG N+!fyx>:qxnivWZ1V_iW㋦4q.!$BW숻ՠ k#4RD~KyYLΖ s 9gd2z鼂Ƅq27aGswo!>Y Hah)a -W^lGb%~{m^t_$f Qul}; " t^T}̠Ġ %ě*C~UĴ8%lo+D D~#V'j; R˴TѾWGzOMwFLV݊)U"p'YC34kk`k}]ӕ1h?5e37 8530c"aX6Au/} ֚4)>چ$D?5mNP:\ }EIYCW>?TV} AUeѵ{eOl}LJÃɁ][˗\k0@_]xV3ġ"XSԠ_FnXY F͞jP<jZ@w8mmr7^7 {P,s0IFhucMh+<&ߡaQkZ[9`}unRT&\I.Xl% jҕC>Y9bN2C׌dnVBv³b KFK#q$a 3b[:*Ɇef`K^5[!Ǩ$"7W_!5@ &X*-5 ,_A)yi7J|s0=zUXP4I #ېo)w5f mLHN;=@@~pd۴t0֙VDHGZvhJnhuóP7! {Fkذ;~RxثhF.XY7@ \#SfS-ʖhM>^Kz3r*G Aj $R jv"{i%;`NpT1)1"D JN7pZ b?&UCU5+?WvcuD1C\tJ~\^p#Eup-.MM~-ɕteĚRǗ3c׬ Ֆ'%:&mWuMqhL;~[[DX[q.ѝ675HRp\\NKDS{ν'Kċ%^dzEj:9K& Iq1Uo 䙡AۀAi"0.zbVOKc+5|tY-6彪Zҩ +͠ ʯ/TYS[ICdo ݞߢ`'֢3|ϝF&J5 E񚱢}Wz?OC"9LfY:6D3>EGi~R=/Vٻ*SќqPh鄘)w)0`+ưH!AF5orNEgܔ{ؔ&b8p|]O T2Ў)iU.R~h{XG Ŗ JW๺:`=?; $,nseņr'HZ|AH;;U :-Mxuآ̗A"hׇ51/D);lL==)' BuÁ%:J꺯N=sҙt [ē+:5}> SUjfaUݲ f'ϝo/RBTPX9!Whmo/~ *᮸dЏժ/M̞C&# w9Tc*'SšFnƱ¸p:!ygǏ~>ωSyhL3Z3In-Г N5$c`oc}?OvΫǂDLiNDoE] ,\P3FHك\$[@G=x5e*%d4Ui*/"WbLsKMHXD̓u0XF^Lo(#l6ZeRXBt! =wM5ب:a^ qVHͯ{Gd,S(ѭu|gf7Y`F4 5+XoɄ%uTz퓊lj_h6 ~wz8I󛪡j%Ir9kuoϻ{@zityNa",za>ZZb>J7!oĤݡA<ڒ4պ1sje@l%__&GuG')oG[u'sbFx&Sܚ\}HFгt4=oDFTU3EDF}t#v4WI" qz?j/d$êDS{VECE_=cЩQ 7zy=y+3{#-NF?%d{v_~8Xct.Q$ًQ<=˒6X%ҭbrҭO?6g[ WqX0 __~b7 Jky4Y1mmRro6[̴4#^J&_^=r=y n7VTO@`VӸ>j6%bƦP_#%S#KZ>hf_t<1Q}wY=R0nǒoi|c8/ӠA@`#ȗÆQ9 yrs z=@(~AY SۼkHX i Hh pN\Rǡ՝Ol(>dwk;ҁ|ŃmL6+DFl}ӊ3}*iqIQ.I|b,݊j7\xj *񵷼7ZW:{ F-rO_] ȮAxr.leٯ'@ێ?V$p7(…+:KZG#{%0J0I'@0EgnϾ % bJHOzd[# ~F@r,Et4 Uo(sQ'[E3r5DeFgVo2pEd*J7j? I<~ss7]s+r'w@Qa׳ö1Wϓ7]w %jv(ÀXxY)EۍsOCo (![XG4'&-1Uэ'.4O8*ċx%mAdylϨД'*0q5lߠFRaRf^?1(oBKc 8;j_;l^פHnAZj{BXqeƔRᄅΦ\wpFqgV\BZӊs b9Ԝ,gQ#Et8}KHM0C:\Á]Ӓ pܱXE\ "KQ udA5S@% d&-|kʪ ީO=Xwx [ 93tN"il\*Dup_.^q~hR Y"_$~q }w~$d@p.E68+nHIq{n:N{_ ,RNtPa=jjF\ c{G`F}R} VtZS= 1jʠ5ol, ȪSn9tlڄ@{:.MaoiKQOEY{^2~O V!V+0Мb:>'{X~tx2KE v-]8fdqܹ/D.B(C/({`?g}ϨJ ?X%W u)&}B6<=^ab, +Tl;zthXYr&;0ko'(b;qR t '2{3PD}X>y/>V;([Ҷ5>_()+Xl҅WB{SIJ^A8AED&D3H|9oYa'9MW߽K`ɖkA榹![^#b2\b$av-Hl9(M@OUާv*C[WөS!1 YL[}Y6~4_n_q/Orq}7N$~oYG.2=M|%9H =sF!f9l䜢h'=eVw :"od:mB>o *Pm9)FnJDf:' D*sV?\vFjP_In%ka -vJ%s)gr0,6j^x`%(4/CGZ'+./;+M~48 Ť?տ6)s&{]lإ>@<hx-+؟\ˋj0S2B6',JDG$V/^%$]":" 5Hax0a>c \:͑Vg2FH|_$v3)vt#Z_>aΖhu^EDs Σ5bA'}+2TV:,H;3*R^Hۻ|CQmDʉ>Jh]'qUa<S6q7KvY6@|7)Fx&x-[cJ[NjMKa:p`Щ&(#gbh:Ͽ3LoF*{TyAZ` ,SA|o*Dd4X1R*Glf𓾊%00R,.GPplQLSX*Ub-9ƕ@+uST=`L!D[mi9n0)3 0 +hl|߳JU; u`Ờ6Г~ał$3SN!,!Lҫŷ6f]H|> : ?݃ׄ(1̬L$ǻۀ2YSYً1 ?C&f pPuJoKLۏ%py0Ac+/5Is:Ѽ2Zh˱wLsW_yPX61-?,whEQD_Y-.Wz[uh.J)%c,2W3z(>EDMv29+AF!Z1ޯ|{ǞtGv%d QNv;ُK Tl)k /7y;È>)-4p"u?9x,.7/p[-EĚw޶zeLD峒H V$Rvȸ]K=: Jw^KdL*880#sH /)8Y~SpsT)^bޱe*C:PsKK$Cw1'NdIVU|:cKMq3K8^4)ᓂayN  l-#w\Ft],Qu> %˂ +>Xe;g*v>aR]I NAn2)zO;C 6ny(IOU1C}=+*a?PzttFC^Q3|D M_=pͺf1áqkIx UO)61 e4\ =+LE^ZيFPIL )? L(aN|P({ Nk$_b)9C%Ts*jHFH|%Yj)c7mǸ*%W1V( .ڲ ,(!"l;KT2T!3(Խ!yLpKԥxc~_$rrӧ ke2C2FkZE5ē&)U'hڠcRs$4®2amGq՛/d}w"QV! (dt-]C|@lcr2;2Os1fZB ^u\],em:cQ8` Cz>>A^??^B9e!&>Oo] R~١ҁ1 [3ᝌ"/'LKཉZ_9 c9b5\QBDfX}`,á:<Y!p,{Pj38r0CIg生R[%p>m TR'K|ɄWځYB*?tڔVX*14Ag$$d)1KJ5|#S.)Y1>b1Dg_JIN3x@ ɰbwW3IJP$lɵ-@كm.qxkP!6,\1zʴfK)e?m( f \""%iZ dFu+zaK6$g"y_Vtԩ^^b? ڀ~% Vծ 0%YP ܢS%gF_J vn^e??6v|lE 1V ˣlـ%ELF}TS-,lyW,C\ aON( BG$4MM+۰|pĔI/€`%@Ueqi@t%Z[J5Ԓg^ S".\f;v.!UCh2"y'D||6pEV8)2O OGDFV MzG RvmmdAhbY*@4_uEO7QFq7-OvRĠ$'!5(G:p}C;f Zd۟18RwPϖ`jPx[NfqST ]9aصwذkcfi90B9!jMnϓ㌵kJXV4ܦ0 X3!Z~>X`RSOc|a (,9Qmq/8|NtUⴢ p3pgE వU>Rd%ލ𣪻oM\ǯRB*GP\3|Hk6?Tf'ۤԶ09F>ctl;TfUR.WM=5Yқ?G%L14^c][Jw6Rdp];pZIe'|J>';€曜B dc; xrP Q>mDYAS* *Wm_+U:   #] %R?autoradio-autoradio-3.6-4/anoggplayer/wiki/000077500000000000000000000000001454362722700207665ustar00rootroot00000000000000autoradio-autoradio-3.6-4/anoggplayer/wiki/UsingTestPlayer.wiki000066400000000000000000000020171454362722700247550ustar00rootroot00000000000000#summary testing the player locally. = Introduction = This page explains how to use the player locally. = Details = Here's how to proceed * Make sure you have installed the latest Flash plugin (ver. 10 or later) * Download and unpack the [http://anoggplayer.googlecode.com/files/AnOggV2_test%20suite.7z TestSuite] to a new local directory(you may need to install [http://www.7-zip.org 7zip]) * Go to Adobe's [http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html security manager] * Add the directory with test suite files to trusted files list * Open the !TestPlayer.html in your web browser (Firefox and IE were tested to work) You can change the !TestPlayer.html to load any web stream or local ogg file. Only files at 128 Kbps or less will work properly. Click the volume button to turn the player on or off. Press and drag the button to increase/decrease volume. Song's tags (artist, title, etc) are displayed above the image Player's status is displayed below that line in green.autoradio-autoradio-3.6-4/autoplayerd000077500000000000000000000057051454362722700200010ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. # Authors: Paolo Patruno # Based on : # mpDris2 from Jean-Philippe Braun , # Mantas Mikulėnas # mpDris from: Erik Karlsson # Some bits taken from quodlibet mpris plugin by import os,autoradio.daemon as daemon from autoradio import _version_ import autoradio.autoradio_config import autoradio.settings from autoradio import _version_ playerd = daemon.Daemon( stdin="/dev/null", stdout=autoradio.settings.logfileplayer, stderr=autoradio.settings.errfileplayer, pidfile=autoradio.settings.lockfileplayer, user=autoradio.settings.userplayer, group=autoradio.settings.groupplayer ) def main (): import logging,logging.handlers formatter=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S") handler = logging.handlers.RotatingFileHandler(autoradio.settings.logfileplayer, maxBytes=5000000, backupCount=10) handler.setFormatter(formatter) # Add the log message handler to the root logger logging.getLogger().addHandler(handler) logging.getLogger().setLevel(logging.INFO) logging.info('Starting up autoplayerd version '+_version_) # # Use logging for ouput at different *levels*. # # # logging.getLogger().setLevel(logging.INFO) # log = logging.getLogger("autoplayer") # handler = logging.StreamHandler(sys.stderr) # log.addHandler(handler) try: from autoradio.autoplayer import player except: logging.info('gstreamer1 import error') logging.info('try to use old gstreamer0') from autoradio.autoplayer import player_gstreamer0 as player player.main(autoradio.settings.busaddressplayer,autoradio.settings.audiosinkplayer) if __name__ == '__main__': # main()# (this code was run as script) import sys, os # this is a triky for ubuntu and debian that remove /var/run every boot # ATTENTION, this should be a security problem path=os.path.dirname(autoradio.settings.lockfileplayer) if (not os.path.lexists(path) and path == "/var/run/autoradio" ): os.mkdir(path) if (os.getuid() == 0): user=autoradio.settings.userplayer group=autoradio.settings.groupplayer if user is not None and group is not None: from pwd import getpwnam from grp import getgrnam uid = getpwnam<(user)[2] gid = getgrnam(group)[2] os.chown(path,uid,gid) if playerd.service(noptions=1000): sys.stdout.write("Playerd version "+_version_+"\n") sys.stdout.write("Daemon started with pid %d\n" % os.getpid()) sys.stdout.write("Daemon stdout output\n") sys.stderr.write("Daemon stderr output\n") sys.exit(main()) # (this code was run as script) autoradio-autoradio-3.6-4/autoplayergui000077500000000000000000000246441454362722700203450ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. from autoradio.mpris2.mediaplayer2 import MediaPlayer2 from autoradio.mpris2.player import Player from autoradio.mpris2.tracklist import TrackList from autoradio.mpris2.interfaces import Interfaces from autoradio.mpris2.some_players import Some_Players from autoradio.mpris2.utils import get_players_uri from autoradio.mpris2.utils import get_session from dbus.mainloop.glib import DBusGMainLoop #import pygtk try: from gi import pygtkcompat except ImportError: pygtkcompat = None if pygtkcompat is not None: pygtkcompat.enable() pygtkcompat.enable_gtk(version='3.0') import gtk import os,stat,time,urllib.parse,urllib.request,urllib.parse,urllib.error,optparse,sys import gobject import dbus import autoradio.settings import urllib.parse import traceback busaddress=autoradio.settings.busaddressplayer def convert_ns(t): s,ns = divmod(t, 1000000) m,s = divmod(s, 60) if m < 60: return "%02i:%02i" %(m,s) else: h,m = divmod(m, 60) return "%i:%02i:%02i" %(h,m,s) class Main(object): def delete_event(self, widget, event, data=None): gtk.main_quit() return False def playhandler(self, *args, **kw): playbackstatus = args[1].get("PlaybackStatus",None) position = args[1].get("Position",None) if playbackstatus is not None: print("PlaybackStatus",playbackstatus) if playbackstatus == "Stopped": self.play_button.set_sensitive(True) self.pause_button.set_sensitive(False) self.stop_button.set_sensitive(False) elif playbackstatus == "Playing": self.play_button.set_sensitive(True) self.pause_button.set_sensitive(True) self.stop_button.set_sensitive(True) elif playbackstatus == "Paused": self.play_button.set_sensitive(True) self.pause_button.set_sensitive(True) self.stop_button.set_sensitive(True) if position is not None: try: id = self.play.Metadata.get(u'mpris:trackid',None) except: id = None if id is not None: length=self.tl.GetTracksMetadata((id,))[0].get(u'mpris:length',None) if position <= length and length != 0: frac = float(position)/float(length) else: frac = 0 else: frac = 0 self.pbar.set_fraction(frac) else: self.pbar.pulse() def __init__(self): self.connected=False #Connect to player DBusGMainLoop(set_as_default=True) uris = list(get_players_uri(pattern=".",busaddress=busaddress)) if len(uris) >0 : uri=uris[0] if busaddress is None: bus = dbus.SessionBus() else: bus = dbus.bus.BusConnection(busaddress) self.mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) self.play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) else: print("No players availables") return try: if hasattr (self.mp2, 'HasTrackList'): if self.mp2.HasTrackList: self.tl = TrackList(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) #self.tl.PropertiesChanged = self.update self.tl.TrackListReplaced = self.update self.tl.TrackAdded = self.update self.tl.TrackRemoved = self.update self.tl.TrackMetadataChanged = self.update else: self.tl = None else: self.tl = None except dbus.exceptions.DBusException: self.tl = None self.play.PropertiesChanged = self.playhandler self.connected = True # Create the GUI self.win = gtk.Window(type=gtk.WINDOW_TOPLEVEL) self.win.set_size_request(400, 600) self.win.set_title("AutoPlayer gui") self.win.connect("delete_event", self.delete_event) vbox = gtk.VBox(homogeneous=False,spacing=0) hbox = gtk.HBox(homogeneous=False,spacing=0) self.load_file = gtk.FileChooserButton(homogeneous="Choose Audio File") self.play_button = gtk.ToolButton( stock_id=gtk.STOCK_MEDIA_PLAY) self.pause_button = gtk.ToolButton( stock_id=gtk.STOCK_MEDIA_PAUSE) self.stop_button = gtk.ToolButton( stock_id=gtk.STOCK_MEDIA_STOP) self.delete_button = gtk.Button(label='Delete') self.delete_button.connect('clicked', self.on_delete_button_clicked) self.load_file.connect("selection-changed",self.on_file_selected) self.play_button.connect("clicked", self.on_play_clicked) self.pause_button.connect("clicked", self.on_pause_clicked) self.stop_button.connect("clicked", self.on_stop_clicked) hbox.pack_start(self.play_button, False, True, 0) hbox.pack_start(self.pause_button, False, True, 0) hbox.pack_start(self.stop_button, False, True, 0) hbox.pack_start(self.delete_button, False, False, 1) # # Create a centering alignment object # align = gtk.Alignment(0.5, 0.5, 0, 0) # vbox.pack_start(align, False, False, 5) # align.show() # Create the ProgressBar self.pbar = gtk.ProgressBar() self.pbar.set_inverted(False) self.pbar.set_fraction(.5) hbox.pack_start(self.pbar) self.pbar.show() vbox.pack_start(self.load_file, False, True, 0) vbox.pack_start(hbox, False, True, 0) # vbox.pack_start(self.pbar) # self.pbar.show() # self.pbar.pulse() #separator = gtk.HSeparator() #vbox.pack_start(separator, False, False, 0) # create the TreeView column_names = ['ID', 'Len', 'Artist', 'Title'] cell_data_funcs = (self.id, self.Len, self.Artist,self.Title) self.treeview = gtk.TreeView() # create the TreeViewColumns to display the data self.tvcolumn = [None] * len(column_names) listmodel = self.make_list() for n in range(0, len(column_names)): cell = gtk.CellRendererText() self.tvcolumn[n] = gtk.TreeViewColumn(column_names[n], cell) if n == 1: cell.set_property('xalign', 1.0) self.tvcolumn[n].set_cell_data_func(cell, cell_data_funcs[n]) self.treeview.append_column(self.tvcolumn[n]) self.treeview.connect('row-activated', self.open_file) self.scrolledwindow = gtk.ScrolledWindow() self.scrolledwindow.add(self.treeview) vbox.pack_start(self.scrolledwindow, True, True, 0) self.treeview.set_model(listmodel) self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.win.add(vbox) self.win.show_all() #gobject.timeout_add(6000,self.update) def update(self, *args, **kw): print("update gtktree") try: new_model = self.make_list() self.treeview.set_model(new_model) while gtk.events_pending(): gtk.main_iteration_do(True) return True except: gtk.main_quit() return False def on_delete_button_clicked(self, button): # Get the TreeView selected row(s) selection = self.treeview.get_selection() # get_selected_rows() returns a tuple # The first element is a ListStore # The second element is a list of tree paths # of all selected rows model, paths = selection.get_selected_rows() # Get the TreeIter instance for each path for path in paths: iter = model.get_iter(path) # Remove the ListStore row referenced by iter print("remove: ",model.get_value(iter, 0)) self.tl.RemoveTrack(model.get_value(iter, 0)) #model.remove(iter) def on_file_selected(self, widget): multimedia_file = self.load_file.get_filename() url=urllib.parse.urlsplit(multimedia_file) uri=urllib.parse.urljoin("file://",urllib.parse.unquote(url.path)) new_model = self.make_list() self.treeview.set_model(new_model) self.tl.AddTrack(uri, self.play.Metadata.get(u'mpris:trackid',""), False) def on_play_clicked(self, widget): self.play.Play() def on_pause_clicked(self, widget): self.play.PlayPause() def on_stop_clicked(self, widget): self.play.Stop() def open_file(self, treeview, path, column): model = treeview.get_model() iter = model.get_iter(path) print("goto: ",model.get_value(iter, 0)) self.tl.GoTo(model.get_value(iter, 0)) new_model = self.make_list() self.treeview.set_model(new_model) def make_list(self): listmodel = gtk.ListStore(object) try: if self.tl is not None: if len(self.tl.Tracks) > 0: # attributes and methods together for track in self.tl.GetTracksMetadata( self.tl.Tracks): listmodel.append([track.get(u'mpris:trackid',"")]) except: print(traceback.format_exc()) print("Error getting player playlist") gtk.main_quit() return listmodel def id(self, column, cell, model, iter, data=None): cell.set_property('text', model.get_value(iter, 0)) if model.get_value(iter, 0) == self.play.Metadata.get(u'mpris:trackid',None): cell.set_property('cell-background',"red") else: cell.set_property('cell-background',"green") return def Len(self, column, cell, model, iter, data=None): track=self.tl.GetTracksMetadata((model.get_value(iter, 0),)) cell.set_property('text', convert_ns(track[0].get(u'mpris:length',""))) return def Artist(self, column, cell, model, iter, data=None): track=self.tl.GetTracksMetadata((model.get_value(iter, 0),)) dir=os.path.dirname(urllib.parse.urlparse(track[0].get(u'xesam:url',"")).path).split('/')[-1] cell.set_property('text', track[0].get(u'xesam:artist', dir)) return def Title(self, column, cell, model, iter, data=None): track=self.tl.GetTracksMetadata((model.get_value(iter, 0),)) file=os.path.basename(urllib.parse.urlparse(track[0].get(u'xesam:url',"")).path) cell.set_property('text', track[0].get(u'xesam:title',file)) return if __name__ == "__main__": from autoradio import _version_ p = optparse.OptionParser(usage="usage: %prog", description="%prog graphic user interface for autoradio player",version="%prog "+_version_) args = sys.argv if args is not None: p.parse_args(args) if len(args) > 1: sys.exit(1) try: if Main().connected: gtk.main() except KeyboardInterrupt : # Clean up print('Keyboard Exiting') gtk.main_quit() autoradio-autoradio-3.6-4/autoradio-site.cfg000066400000000000000000000125731454362722700211350ustar00rootroot00000000000000[autoradiod] #player to use (AutoPlayer, xmms, audacious) player="AutoPlayer" #directory where write new playlists generated by autoradiod playlistdir="/usr/share/autoradio/django/media/spots" # path to working file logfile="/var/log/autoradio/autoradiod.log" errfile = "/var/log/autoradio/autoradiod.err" lockfile = "/var/run/autoradio/autoradiod.lock" timestampfile = "/var/run/autoradio/autoradiod.timestamp" # host xmms is running on xmms_host="localhost" #backward and forward time intervat to check for schedule conflict minelab=180 # tollerance time interval to recovery schedule not done ( backward time when start autoradiod ) # to adjust the programming you have to make changes minsched minutes before minsched=5 locale="C.UTF-8" user = autoradio group = autoradio [[ env ]] DISPLAY=':0.0' LANG=$locale [autoradioweb] logfile = '/var/log/autoradio/autoradioweb.log' errfile = '/var/log/autoradio/autoradioweb.err' lockfile = '/var/run/autoradio/autoradioweb.lock' user = autoradio group = autoradio #port = '8888' # the web player can only manage ogg vorbis files at 44100Hz: enable or disable check on uploads permit_no_playable_files = False # tags help in the web view: enable or disable check on uploads # if file do not have tags will be rejected # this enable or disable check for 44100Hz sample rate compatibility for enclosure require_tags_in_enclosure = True [django] DEBUG = True TEMPLATE_DEBUG = True FILE_UPLOAD_PERMISSIONS = 420 # Make this unique, and don't share it with anybody. SECRET_KEY = random-string-of-ascii #SESSION_COOKIE_DOMAIN = autoradio # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'Europe/Rome' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' #LANGUAGE_CODE = 'it-it' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # directories where Django looks for translation files. LOCALE_PATHS='/usr/share/autoradio/locale', ADMINS=Your Name your_email@domain.com, MANAGERS=Your Name your_email@domain.com, # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = '/usr/share/autoradio/media/' #URL that handles the media served from MEDIA_ROOT, used for managing #stored files. It must end in a slash if set to a non-empty value. You #will need to configure these files to be served in both development #and production environments. MEDIA_URL="/media/" # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. TEMPLATE_DIRS = "/usr/share/autoradio/templates", #The absolute path to the directory where collectstatic will collect static files for deployment STATIC_ROOT = "/usr/share/autoradio/static" #URL to use when referring to static files located in STATIC_ROOT. STATIC_URL = '/static/' # set to true if django have to serve static file # set to false if you use other web server like apache SERVE_STATIC=True # The URL where requests are redirected for login, especially when # using the login_required() decorator. LOGIN_URL='/login/' [database] DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = '/usr/share/autoradio/autoradio.sqlite3' # Or path to database file if using sqlite3. #DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. #DATABASE_NAME = 'autoradio' # Or path to database file if using sqlite3. #DATABASE_USER = 'autoradio' # Not used with sqlite3. #DATABASE_PASSWORD = 'autoradio' # Not used with sqlite3. #DATABASE_HOST = 'autoradio' # Set to empty string for localhost. Not used with sqlite3. #DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. [autoplayer] user = autoradio group = autoradio logfile = '/var/log/autoradio/autoplayer.log' errfile = '/var/log/autoradio/autoplayer.err' lockfile = '/var/run/autoradio/autoplayer.lock' # Add an address that the dbus-daemon should listen on. The address is in the # standard D-Bus format that contains a transport name plus possible # parameters/options. # Example: unix:path=/tmp/foo # Example: tcp:host=localhost,port=1234 # http://stackoverflow.com/questions/10158684/connecting-to-dbus-over-tcp #busaddress='tcp:host=localhost,port=1234' #audiosink = jackaudiosink # set to autoaudiosink / jackaudiosink [autoradiodbus] user = autoradio group = autoradio logfile = '/var/log/autoradio/autoradiodbus.log' errfile = '/var/log/autoradio/autoradiodbus.err' lockfile = '/var/run/autoradio/autoradiodbus.lock' conffile = '/etc/autoradio/dbus-autoradio.conf' [jackdaemon] user = autoradio group = audio logfile = '/var/log/autoradio/jackdaemon.log' errfile = '/var/log/autoradio/jackdaemon.err' lockfile = '/var/run/autoradio/jackdaemon.lock' autoradio-autoradio-3.6-4/autoradio-tmpfiles.conf000066400000000000000000000000601454362722700221660ustar00rootroot00000000000000D /var/run/autoradio 0710 autoradio autoradio - autoradio-autoradio-3.6-4/autoradio.cfg000066400000000000000000000120441454362722700201640ustar00rootroot00000000000000[autoradiod] #player to use (AutoPlayer, xmms, audacious) player="AutoPlayer" #directory where write new playlists generated by autoradiod playlistdir="spots" # path to working file logfile="/tmp/autoradiod.log" errfile = '/tmp/autoradiod.err' lockfile = "/tmp/autoradiod.lock" timestampfile = "/tmp/autoradiod.timestamp" # host xmms is running on xmms_host="localhost" #backward and forward time intervat to check for schedule conflict minelab=180 # tollerance time interval to recovery schedule not done ( backward time when start autoradiod ) # to adjust the programming you have to make changes minsched minutes before minsched=5 locale="C.UTF-8" #user = pat1 #group = pat1 # # [[ env ]] # DISPLAY=':0.0' # LANG=$locale [autoradioweb] logfile = '/tmp/autoradioweb.log' errfile = '/tmp/autoradioweb.err' lockfile = '/tmp/autoradioweb.lock' #user = myuser #group = mygroup #port = '8888' # the web player can only manage ogg vorbis files at 44100Hz: enable or disable check on uploads permit_no_playable_files = False # tags help in the web view: enable or disable check on uploads # if file do not have tags will be rejected # this enable or disable check for 44100Hz sample rate compatibility for enclosure require_tags_in_enclosure = True [django] DEBUG = True TEMPLATE_DEBUG = True FILE_UPLOAD_PERMISSIONS = 420 # Make this unique, and don't share it with anybody. SECRET_KEY = random-string-of-ascii #SESSION_COOKIE_DOMAIN = autoradio # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'Europe/Rome' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' #LANGUAGE_CODE = 'it-it' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # directories where Django looks for translation files. LOCALE_PATHS='locale', ADMINS=Your Name your_email@domain.com, MANAGERS=Your Name your_email@domain.com, # Absolute filesystem path to the directory that will hold user-uploaded files. # set to "%s" special value to insert current directory MEDIA_ROOT ="%s/media/" #URL that handles the media served from MEDIA_ROOT, used for managing #stored files. It must end in a slash if set to a non-empty value. You #will need to configure these files to be served in both development #and production environments. MEDIA_URL="/media/" # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. TEMPLATE_DIRS = "%s/templates", #The absolute path to the directory where collectstatic will collect static files for deployment STATIC_ROOT = "%s/static" #URL to use when referring to static files located in STATIC_ROOT. STATIC_URL = '/static/' # set to true if django have to serve static file # set to false if you use other web server like apache SERVE_STATIC=True # The URL where requests are redirected for login, especially when # using the login_required() decorator. LOGIN_URL='/login/' [database] DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = 'autoradio.sqlite3' # Or path to database file if using sqlite3. #DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. #DATABASE_NAME = 'autoradio' # Or path to database file if using sqlite3. #DATABASE_USER = 'autoradio' # Not used with sqlite3. #DATABASE_PASSWORD = 'autoradio' # Not used with sqlite3. #DATABASE_HOST = 'autoradio' # Set to empty string for localhost. Not used with sqlite3. #DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. [autoplayer] #user = myuser #group = mygroup logfile = '/tmp/autoplayer.log' errfile = '/tmp/autoplayer.err' lockfile = '/tmp/autoplayer.lock' # Add an address that the dbus-daemon should listen on. The address is in the # standard D-Bus format that contains a transport name plus possible # parameters/options. # Example: unix:path=/tmp/foo # Example: tcp:host=localhost,port=1234 # http://stackoverflow.com/questions/10158684/connecting-to-dbus-over-tcp #busaddress='tcp:host=localhost,port=1234' #audiosink = autoaudiosink # set to autoaudiosink / jackaudiosink [autoradiodbus] #user = myuser #group = mygroup logfile = '/tmp/autoradiodbus.log' errfile = '/tmp/autoradiodbus.err' lockfile = '/tmp/autoradiodbus.lock' conffile = 'dbus-autoradio.conf' [jackdaemon] user = autoradio group = audio logfile = '/tmp/jackdaemon.log' errfile = '/tmp/jackdaemon.err' lockfile = '/tmp/jackdaemon.lock' autoradio-autoradio-3.6-4/autoradio.spec000066400000000000000000000275021454362722700203640ustar00rootroot00000000000000Summary: radio automation software Name: autoradio Version: 3.6 Release: 4 Source0: %{name}-%{version}.tar.gz # tmpfiles.d configuration for the /var/run directory #Source1: %%{name}-tmpfiles.conf License: GNU GPL v2 Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot Prefix: %{_prefix} BuildArch: noarch Vendor: Paolo Patruno Url: https://github.com/pat1/autoradio BuildRequires: python3-devel, python3-setuptools, gettext, python3-configobj, python3-magic, python3-django >= 2.2 , help2man, python3-setuptools Requires:python3-mutagen >= 1.17 , python3-django >= 2.2, python3-configobj, python3-cherrypy, python3-reportlab >= 2.0, python3-docutils, sqlite >= 3.6.22, speex-tools, python3-magic, python3-pillow #, python-django-extensions #Requires: initscripts #%if 0%%{?fedora} < 10 #Requires: pyxmms, xmms #%else ## Requires: dbus-python, audacious >= 1.5 Requires: python3-dbus, python3-gstreamer1, gstreamer1-plugins-base, gstreamer1-plugins-good #, gstreamer-plugins-bad, gstreamer-plugins-bad-free, gstreamer-plugins-bad-free-extras #%endif %description \ Radio automation software. Simple to use, starting from digital audio files, manage on-air broadcasting over a radio-station or web-radio. The main components are: * Player integrated (gstreamer) or external (Xmms/Audacious): plays all your media files and send digital sound to an audio device or audio server * Scheduler: real time manager for emission of special audio files like jingles, spots, playlist and programs; interact with player like supervisor User * inteface: WEB interface to monitor the player and scheduler and admin the schedules for the complete control over your station format. The web interface allows you to easily publish podcasts that conform to the RSS 2.0 and iTunes RSS podcast specifications The web interface provide a "full compatible" ogg player. Developed with Python, Django, Dbus it works in an production enviroment %prep %setup -n %{name}-%{version} -n %{name}-%{version} %build %py3_build %install %py3_install ##%{__install} -d -m 0710 %{buildroot}%{_var}/{run/autoradio,log/autoradio} mkdir -p %{buildroot}%{_localstatedir}/run/ mkdir -p %{buildroot}%{_localstatedir}/log/ %{__install} -d -m 0710 %{buildroot}%{_localstatedir}/{run/autoradio,log/autoradio} mkdir -p %{buildroot}%{_sysconfdir}/tmpfiles.d %{__install} -m 0644 %{name}-tmpfiles.conf %{buildroot}%{_sysconfdir}/tmpfiles.d/%{name}.conf %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc COPYING README doc/* %config(noreplace) %{_sysconfdir}/%{name}/autoradio-site.cfg %config(noreplace) %{_sysconfdir}/%{name}/dbus-autoradio.conf %dir %{python3_sitelib}/%{name} %{python3_sitelib}/%{name}/* %{python3_sitelib}/%{name}-* %{_mandir}/man1/* %config(noreplace) %{_sysconfdir}/tmpfiles.d/%{name}.conf #%%{_datadir}/autoradio/* %{_bindir}/autoradiod %{_bindir}/autoradioweb %{_bindir}/autoradioctrl %{_bindir}/autoplayerd %{_bindir}/autoplayergui %{_bindir}/autoradiodbusd %{_bindir}/jackdaemon %attr(-,autoradio,autoradio) %dir %{_datadir}/autoradio %attr(-,autoradio,autoradio) %{_datadir}/%{name}/* %attr(-,autoradio,autoradio) %dir %{_var}/log/%{name}/ %attr(-,autoradio,autoradio) %dir %{_var}/run/%{name}/ %pre /usr/bin/getent group autoradio >/dev/null || /usr/sbin/groupadd autoradio /usr/bin/getent passwd autoradio >/dev/null || \ /usr/sbin/useradd -g autoradio -d %{_datadir}/autoradio -M \ -c "autoradio user for radio automation software" autoradio #/usr/bin/getent group autoradio >/dev/null || /usr/sbin/groupadd -r autoradio #/usr/bin/getent passwd autoradio >/dev/null || \ # /usr/sbin/useradd -r -s /sbin/nologin -d %{_datadir}/autoradio -g autoradio \ # -c "autoradio user for radio automation software" autoradio ## Fix homedir for upgrades #/usr/sbin/usermod --home %{_datadir}/autoradio autoradio &>/dev/null ##exit 0 #%post # ## set some useful variables #AUTORADIO="autoradio" #CHOWN="/bin/chown" #ADDUSER="/usr/sbin/adduser" #USERDEL="/usr/sbin/userdel" #USERADD="/usr/sbin/useradd" #GROUPDEL="/usr/sbin/groupdel" #GROUPMOD="/usr/sbin/groupmod" #ID="/usr/bin/id" # #set -e # #### ## 1. get current autoradio uid and gid if user exists. #if $ID $AUTORADIO > /dev/null 2>&1; then # IUID=`$ID --user $AUTORADIO` # IGID=`$ID --group $AUTORADIO` #else # IUID="NONE" # IGID="NONE" #fi # ##### ### 2. Ensure that no standard account or group will remain before adding the ### new user ##if [ "$IUID" = "NONE" ] || [ $IUID -ge 1000 ]; then # we must do sth :) ## if ! [ "$IUID" = "NONE" ] && [ $IUID -ge 1000 ]; then ## # autoradio user exists but isn't a system user... delete it. ## $USERDEL $PEERCAST ## $GROUPDEL $PEERCAST ## fi ## ##### # ## 3. Add the system account. ## Issue a debconf warning if it fails. # if $GROUPMOD $AUTORADIO > /dev/null 2>&1; then # # peercast group already exists, use --ingroup # if ! $ADDUSER --system --disabled-password --disabled-login --home /usr/share/autoradio --no-create-home --ingroup $AUTORADIO $AUTORADIO; then # echo "The adduser command failed." # fi # else # if ! $ADDUSER --system --disabled-password --disabled-login --home /usr/share/peercast --no-create-home --group $AUTORADIO; then # echo "The adduser command failed." # fi # fi #fi #set +e # #### ## 4. change ownership of directory #$CHOWN -R $AUTORADIO:$AUTORADIO /usr/share/autoradio/ #$CHOWN -R $AUTORADIO:$AUTORADIO /var/log/autoradio/ #$CHOWN -R $AUTORADIO:$AUTORADIO /etc/autoradio/ #$CHOWN -R $AUTORADIO:$AUTORADIO /var/run/autoradio/ %changelog * Fri Dec 29 2023 Paolo Patruno 3.6-4 - sintax error (p.patruno@iperbole.bologna.it) * Fri Dec 29 2023 Paolo Patruno 3.6-3 - remove python3-future dependency (p.patruno@iperbole.bologna.it) * Fri Dec 29 2023 Paolo Patruno 3.6-2 - bugs on string codec (p.patruno@iperbole.bologna.it) * Fri Dec 29 2023 Paolo Patruno 3.6-1 - drop extraneous imports of part of stdlib (alexandre.detiste@gmail.com) - remove Python2 support (alexandre.detiste@gmail.com) - remove SIX crumbs (alexandre.detiste@gmail.com) - minor improvements (p.patruno@iperbole.bologna.it) * Wed Sep 29 2021 Paolo Patruno 3.5-1 - changed securesec (the time to have to play in current position in playlist when we insert track in playlist) from 10 to 20 sec (p.patruno@iperbole.bologna.it) - revert busaddress patch and limit the number of districa call to solve infinite loop, ported the web interface (p.patruno@iperbole.bologna.it) - migrate to the last mpris2 python interface (p.patruno@iperbole.bologna.it) - close #30 (p.patruno@iperbole.bologna.it) - bug loading playlist; generator in python 3 do not work if used more time (p.patruno@iperbole.bologna.it) - more documentation (p.patruno@iperbole.bologna.it) - new release for debian new convenction with matainer (p.patruno@iperbole.bologna.it) - new README (p.patruno@iperbole.bologna.it) * Thu Jan 23 2020 Paolo Patruno 3.3-4 - exception with player without track list (p.patruno@iperbole.bologna.it) * Wed Jan 15 2020 Paolo Patruno 3.3-3 - working on spec file (p.patruno@iperbole.bologna.it) - little update in documentation (p.patruno@iperbole.bologna.it) * Wed Jan 15 2020 Paolo Patruno 3.3-2 - working on spec file (p.patruno@iperbole.bologna.it) - working on spec file (p.patruno@iperbole.bologna.it) - working on spec file (p.patruno@iperbole.bologna.it) - working on spec file (p.patruno@iperbole.bologna.it) - new sper release (p.patruno@iperbole.bologna.it) * Wed Jan 15 2020 Paolo Patruno 3.3-1 - added shebang for python3 ; release 3.3 (p.patruno@iperbole.bologna.it) - release 3.2 for Debian (p.patruno@iperbole.bologna.it) - migrate to django 2.2 and python3 bugs (p.patruno@iperbole.bologna.it) - bug on debian install (default locale) and python3 refinements (root@localhost.localdomain) - ready for release 3.0 (p.patruno@iperbole.bologna.it) - ported player to python 3 (p.patruno@iperbole.bologna.it) - new migration for python3 (p.patruno@iperbole.bologna.it) - porting to python3 with futurize (p.patruno@iperbole.bologna.it) - sure you specify the proper version support in your setup.py file (p.patruno@iperbole.bologna.it) - new stable release for Debian (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno 2.8.9-1 - * Wed Feb 01 2017 Paolo Patruno 2.8.8-1 - standard spec file (ppatruno@arpa.emr.it) - bug in spec (ppatruno@arpa.emr.it) - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - bug in spec (ppatruno@arpa.emr.it) - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - removed SOURCE1 fron spec file (ppatruno@arpa.emr.it) - better monit example (ppatruno@arpa.emr.it) - new package built with tito (ppatruno@arpa.emr.it) - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno - lost autoradio-tmpfiles.conf (ppatruno@arpa.emr.it) * Wed Feb 01 2017 Paolo Patruno 2.8.7-8 - new package built with tito * Sat Aug 10 2013 Paolo Patruno - 2.8.0-1%{?dist} - bumped to version 2.8 * Mon Feb 18 2013 Paolo Patruno - 2.7.0-1%{?dist} - autoradio 2.7 with pygst * Sat Apr 14 2012 Paolo Patruno - 2.3-2%{?dist} - tmpfiles.d is a service provided by both systemd and upstart in Fedora 15 and later for managing temporary files and directories for daemons https://fedoraproject.org/wiki/Packaging:Tmpfiles.d * Sat Apr 14 2012 Paolo Patruno - 2.3-1%{?dist} - updated to 2.3 * Fri Aug 12 2011 Paolo Patruno - 2.1beta-1%{?dist} - upstream version 2.1beta autoradio-autoradio-3.6-4/autoradio.wsgi000066400000000000000000000012041454362722700203720ustar00rootroot00000000000000# remenber to set those in envvars in debian or /etc/sysconfig/httpd in centos #LANG='en_US.UTF-8' #LC_ALL='en_US.UTF-8' import os import autoradio.settings import autoradio.autoradio_config #os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' #import django.core.handlers.wsgi #application = django.core.handlers.wsgi.WSGIHandler() ## from django 1.4 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "autoradio.settings") ## This application object is used by the development server ## as well as any WSGI server configured to use this file. from django.core.wsgi import get_wsgi_application application = get_wsgi_application() autoradio-autoradio-3.6-4/autoradio/000077500000000000000000000000001454362722700175025ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/__init__.py000066400000000000000000000000201454362722700216030ustar00rootroot00000000000000_version_="3.6" autoradio-autoradio-3.6-4/autoradio/audaciousweb.py000066400000000000000000000176351454362722700225430ustar00rootroot00000000000000#!/usr/bin/env python # coding=utf-8 """ Show audacious playlist on a simple web server. """ maxplele=100 # max number of elements in playlist port=8888 # server port #try: # import sys,glob # from distutils.sysconfig import get_python_lib # compatCherryPyPath = glob.glob( get_python_lib()+"/CherryPy-2.*").pop() # sys.path.insert(0, compatCherryPyPath) #finally: import cherrypy import os cpversion3=cherrypy.__version__.startswith("3") import datetime # ------- dbus interface --------- import dbus bus = dbus.SessionBus() head=''' AUDACIOUS monitor | ''' tail=''' ''' class HomePage(object): # def Main(self): # # Let's link to another method here. # htmlresponse='Goto audacious status for autoradio!
' # htmlresponse+='Goto audacious playlist for autoradio!
' # return htmlresponse # Main.exposed = True def __init__(self,iht): self.iht=iht def test(self): "return test page" return "Test Page" test.exposed = True def status(self): "return audacious status" try: # --------------------------------- org_obj = bus.get_object("org.atheme.audacious", '/org/atheme/audacious') org = dbus.Interface(org_obj, dbus_interface='org.atheme.audacious') # --------------------------------- except: return "error intializing dbus" if (org.Playing()): return "audacious is playing" else: return "audacious is stopped" status.exposed = True def index(self): "return audacious playlist" if (self.iht) : htmlresponse=head else: htmlresponse="" try: # ----------------------------------------------------------- root_obj = bus.get_object("org.atheme.audacious", '/') player_obj = bus.get_object("org.atheme.audacious", '/Player') tracklist_obj = bus.get_object("org.atheme.audacious", '/TrackList') org_obj = bus.get_object("org.atheme.audacious", '/org/atheme/audacious') root = dbus.Interface(root_obj, dbus_interface='org.freedesktop.MediaPlayer') player = dbus.Interface(player_obj, dbus_interface='org.freedesktop.MediaPlayer') tracklist = dbus.Interface(tracklist_obj, dbus_interface='org.freedesktop.MediaPlayer') org = dbus.Interface(org_obj, dbus_interface='org.atheme.audacious') # ----------------------------------------------------------- except: return "error intializing dbus" try: cpos=int(tracklist.GetCurrentTrack()) except: return "error tracklist.GetCurentTrack()" try: isplaying= org.Playing() except: return "error org.Playing()" try: len=tracklist.GetLength() htmlresponse+='

audacious ha %i brani in playlist // selezionato brano numero %i

' % (len,cpos+1) htmlresponse+='' htmlresponse+='' for pos in range(0,min(len,maxplele)): htmlresponse+='' metadata=tracklist.GetMetadata(pos) try: file=metadata["location"] except: file=None try: title=metadata["title"] if title=="": title=None except: title=None try: artist=metadata["artist"] if artist=="": artist=None except: artist=None try: mtimelength=metadata["mtime"] except: mtimelength=0 try: mtimeposition=player.PositionGet() except: mtimeposition=0 timelength=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimelength).seconds) timeposition=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimeposition).seconds) if pos == cpos and isplaying: col="#FF0000" toend=timelength-timeposition elif pos < cpos : col="#0000FF" toend="" else: col="#00FF00" toend="" print(artist,title) if (artist is not None) or (title is not None): htmlresponse+='' % \ (col,pos+1,str(timelength),str(toend),file,artist,title) else: purefilename=os.path.splitext(file)[0] htmlresponse+='' % \ (col,pos+1,str(timelength),str(toend),file,os.path.basename(purefilename)) htmlresponse+='' except: htmlresponse+='error get audacious information' raise htmlresponse+='
posizioneduratabrano
%i %s // %s %s // %s%i %s // %s %s
' if len > maxplele : htmlresponse+="

ATTENZIONE: ci sono molti elementi nella playlist e gli ultimi non sono visualizzati

" if (self.iht) : htmlresponse+=tail return htmlresponse index.exposed = True def start_http_server(iht=False): """ start web server to monitor audacious iht=False # do not emit header e tail """ #import os #pid = os.fork() settings = { 'global': { 'server.socket_port' : port, 'server.socket_host': "0.0.0.0", 'server.socket_file': "", 'server.socket_queue_size': 5, 'server.protocol_version': "HTTP/1.0", 'server.log_to_screen': False, 'server.log_file': "/tmp/audaciousweb.log", 'server.reverse_dns': False, 'server.thread_pool': 10, 'server.environment': "development", #'server.environment': "production", 'tools.encode.on':True, # 'tools.encode.encoding':'utf8', }, } # CherryPy always starts with cherrypy.root when trying to map request URIs # to objects, so we need to mount a request handler object here. A request # to '/' will be mapped to cherrypy.root.index(). if (cpversion3): cherrypy.quickstart(HomePage(iht),config=settings) else: cherrypy.config.update(settings) cherrypy.root = HomePage(iht) cherrypy.server.start() if __name__ == '__main__': # Set the signal handler #import signal #signal.signal(signal.SIGINT, signal.SIG_IGN) # Start the CherryPy server. try: start_http_server(iht=True) except: print("Error") raise finally: print("Terminated") autoradio-autoradio-3.6-4/autoradio/autoaudacious.py000066400000000000000000000132031454362722700227210ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. import time import datetime import os # ------- dbus interface --------- import dbus class audacious: def __init__(self,session=0): try: self.bus = dbus.SessionBus() # ----------------------------------------------------------- root_obj = self.bus.get_object("org.mpris.audacious", '/') player_obj = self.bus.get_object("org.mpris.audacious", '/Player') tracklist_obj = self.bus.get_object("org.mpris.audacious", '/TrackList') org_obj = self.bus.get_object("org.mpris.audacious", '/org/atheme/audacious') self.root = dbus.Interface(root_obj, dbus_interface='org.freedesktop.MediaPlayer') self.player = dbus.Interface(player_obj, dbus_interface='org.freedesktop.MediaPlayer') self.tracklist = dbus.Interface(tracklist_obj, dbus_interface='org.freedesktop.MediaPlayer') self.org = dbus.Interface(org_obj, dbus_interface='org.atheme.audacious') # ----------------------------------------------------------- except: raise def __str__(self): return "org.atheme.audacious" def play_ifnot(self): ''' start playng if not. ''' # I check if audacious is playng .... otherside I try to play isplaying= self.org.Playing() if (not isplaying): self.player.Play() def get_playlist_securepos(self,securesec=10): ''' Try to secure that there are some time (securesec) to complete all operations in time: if audacious change song during operation will be a big problem ''' try: self.play_ifnot() #force to play mintimed=datetime.timedelta(seconds=securesec) toend=datetime.timedelta(seconds=0) volte=0 while ( toend < mintimed ): # take the current position pos=self.tracklist.GetCurrentTrack() metadata=self.tracklist.GetMetadata(pos) #print metadata mtimelength=metadata["mtime"] mtimeposition=self.player.PositionGet() timed=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimelength).seconds) toend=timed-datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimeposition).seconds) newpos=self.tracklist.GetCurrentTrack() if (pos != newpos): #inconsistenza: retry toend=datetime.timedelta(seconds=0) if ( toend < mintimed ): volte +=1 if volte > 10 : break # timeout , I have to play time.sleep(securesec+1) return pos except : return None def playlist_clear_up(self,atlast=10): ''' clear playlist starting from current position up. "atlast" numer of song are retained ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False # delete the old ones if pos > atlast : for prm in range(0,pos-atlast): self.tracklist.DelTrack(0) return True except: return False def playlist_clear_down(self,atlast=500): ''' clear playlist starting from current position + atlast doen. "atlast" numer of song are retained for future play ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False length=self.tracklist.GetLength() #elimino il troppo if length-pos > atlast : for prm in range(length,pos+atlast,-1): self.tracklist.DelTrack(prm) return True except: return False def get_playlist_posauto(self,autopath,securesec=10): ''' get playlist position skipping file with path equal to autopath. Try to secure that there are some time (securesec) to complete all operations in time: if xmms change song during operation will be a big problem ''' try: pos=self.get_playlist_securepos(securesec=securesec) if pos is None: return pos pos+=1 metadata=self.tracklist.GetMetadata(pos) try: file=metadata["URI"] except: return pos filepath=os.path.dirname(file) # ora controllo se ci sono gia dei file accodati nella playlist da autoradio # l'unica possibilita di saperlo e verificare il path del file while ( os.path.commonprefix ((filepath,"file://"+autopath)) == "file://"+autopath ): pos+=1 metadata=self.tracklist.GetMetadata(pos) try: file=metadata["URI"] except: return pos filepath=os.path.dirname(file) # here I have found the first file added by autoradio return pos except : return None def get_playlist_pos(self): "get current position" return self.tracklist.GetCurrentTrack() autoradio-autoradio-3.6-4/autoradio/autoepris.py000066400000000000000000000131501454362722700220670ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. import dbus import time import datetime import os # ------- dbus epris player interface --------- import dbus class mediaplayer: def __init__(self,session=0): try: self.bus = dbus.SessionBus() # ----------------------------------------------------------- mediaplayer_obj = self.bus.get_object("org.mpris.epris", '/org/mpris/epris') current_obj = self.bus.get_object("org.mpris.epris", '/org/mpris/epris/lists/current') self.player = dbus.Interface(mediaplayer_obj, dbus_interface='org.mpris.EprisPlayer') self.tracklist = dbus.Interface(current_obj, dbus_interface='org.mpris.EprisTrackList') # ----------------------------------------------------------- except: raise def __str__(self): return self.player.Identity def play_ifnot(self): ''' start playing if not. ''' # I check if mediaplayer is playing .... otherside I try to play print(self.tracklist.ListTracks()) print(self.tracklist.Current) # if (not self.player.PlaybackStatus == "Playing"): # self.player.Play() def get_playlist_securepos(self,securesec=10): # DO NOT WORK ''' Try to secure that there are some time (securesec) to complete all operations in time: if mediaplayer change song during operation will be a big problem ''' try: self.play_ifnot() #force to play mintimed=datetime.timedelta(seconds=securesec) toend=datetime.timedelta(seconds=0) volte=0 while ( toend < mintimed ): # take the current position pos=self.tracklist.GetCurrentTrack() metadata=self.tracklist.GetMetadata(pos) #print metadata mtimelength=metadata["mtime"] mtimeposition=self.player.PositionGet() timed=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimelength).seconds) toend=timed-datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimeposition).seconds) newpos=self.tracklist.GetCurrentTrack() if (pos != newpos): #inconsistenza: retry toend=datetime.timedelta(seconds=0) if ( toend < mintimed ): volte +=1 if volte > 10 : break # timeout , I have to play time.sleep(securesec+1) return pos except : return None def playlist_clear_up(self,atlast=10): # DO NOT WORK ''' clear playlist starting from current position up. "atlast" numer of song are retained ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False # delete the old ones if pos > atlast : for prm in range(0,pos-atlast): self.tracklist.DelTrack(0) return True except: return False def playlist_clear_down(self,atlast=500): # DO NOT WORK ''' clear playlist starting from current position + atlast doen. "atlast" numer of song are retained for future play ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False length=self.tracklist.GetLength() #elimino il troppo if length-pos > atlast : for prm in range(length,pos+atlast,-1): self.tracklist.DelTrack(prm) return True except: return False def get_playlist_posauto(self,autopath,securesec=10): # DO NOT WORK ''' get playlist position skipping file with path equal to autopath. Try to secure that there are some time (securesec) to complete all operations in time: if xmms change song during operation will be a big problem ''' try: pos=self.get_playlist_securepos(securesec=securesec) if pos is None: return pos pos+=1 metadata=self.tracklist.GetMetadata(pos) try: file=metadata["URI"] except: return pos filepath=os.path.dirname(file) # ora controllo se ci sono gia dei file accodati nella playlist da autoradio # l'unica possibilita di saperlo e verificare il path del file while ( os.path.commonprefix ((filepath,"file://"+autopath)) == "file://"+autopath ): pos+=1 metadata=self.tracklist.GetMetadata(pos) try: file=metadata["URI"] except: return pos filepath=os.path.dirname(file) # here I have found the first file added by autoradio return pos except : return None def get_playlist_pos(self): # DO NOT WORK "get current position" return self.tracklist.GetCurrentTrack() def main(): mp=mediaplayer() print(mp) mp.play_ifnot() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autompris.py000066400000000000000000000231111454362722700220750ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. # ------- dbus mpris 1 interface --------- # note that this work for audacious only # mpris version 1 do not provide interface to insert media # at specified position in playlist # so we have to wait players to implement mpris2 specification to generalize this interface. # Audacious provide non standard interface to do this # ---------------------------------------- import dbus import time import datetime import os import logging import dbus class mediaplayer: def __init__(self,player="audacious",session=0): self.mediaplayer=player self.session=session try: self.bus = dbus.SessionBus() # ----------------------------------------------------------- root_obj = self.bus.get_object("org.mpris."+player, '/') player_obj = self.bus.get_object("org.mpris."+player, '/Player') tracklist_obj = self.bus.get_object("org.mpris."+player, '/TrackList') self.root = dbus.Interface(root_obj, dbus_interface='org.freedesktop.MediaPlayer') self.player = dbus.Interface(player_obj, dbus_interface='org.freedesktop.MediaPlayer') self.tracklist = dbus.Interface(tracklist_obj, dbus_interface='org.freedesktop.MediaPlayer') if player == "audacious": org_obj = self.bus.get_object("org.mpris.audacious", '/org/atheme/audacious') self.org = dbus.Interface(org_obj, dbus_interface='org.atheme.audacious') # ----------------------------------------------------------- except: raise if player == "audacious": from distutils.version import LooseVersion reqversion=LooseVersion("1.5") version=LooseVersion("0.0") try: # aud.root.Identity() version=LooseVersion(self.org.Version()) logging.info("mediaplayer: audacious version: %s" % str(version)) except: logging.error("mediaplayer: eror gettin audacious version") if ( version < reqversion ): logging.error("mediaplayer: audacious %s version is wrong (>=1.5) " % version ) raise Exception def __str__(self): return "mpris 1 interface" def play_ifnot(self): ''' start playng if not. GetStatus Return the status of "Media Player" as a struct of 4 ints: First integer: 0 = Playing, 1 = Paused, 2 = Stopped. Second interger: 0 = Playing linearly , 1 = Playing randomly. Third integer: 0 = Go to the next element once the current has finished playing , 1 = Repeat the current element Fourth integer: 0 = Stop playing once the last element has been played, 1 = Never give up playing ''' status=self.player.GetStatus() if status[0] == 0 : pass elif status[0] == 1 : self.player.Pause() elif status[0] == 2 : self.player.Play() def isplaying(self): ''' return true if is playing. ''' status=self.player.GetStatus() return status[0] == 0 def get_playlist_securepos(self,securesec=10): ''' Try to secure that there are some time (securesec) to complete all operations in time: if audacious change song during operation will be a big problem ''' try: self.play_ifnot() #force to play mintimed=datetime.timedelta(seconds=securesec) toend=datetime.timedelta(seconds=0) volte=0 while ( toend < mintimed ): # take the current position pos=self.tracklist.GetCurrentTrack() metadata=self.tracklist.GetMetadata(pos) #print metadata mtimelength=metadata["mtime"] mtimeposition=self.player.PositionGet() timed=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimelength).seconds) toend=timed-datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimeposition).seconds) newpos=self.tracklist.GetCurrentTrack() if (pos != newpos): #inconsistenza: retry toend=datetime.timedelta(seconds=0) if ( toend < mintimed ): volte +=1 if volte > 10 : break # timeout , I have to play time.sleep(securesec+1) return pos except : return None def playlist_clear_up(self,atlast=10): ''' clear playlist starting from current position up. "atlast" numer of song are retained ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False # delete the old ones if pos > atlast : for prm in range(0,pos-atlast): self.tracklist.DelTrack(0) return True except: return False def playlist_clear_down(self,atlast=500): ''' clear playlist starting from current position + atlast doen. "atlast" numer of song are retained for future play ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False length=self.tracklist.GetLength() #elimino il troppo if length-pos > atlast : for prm in range(length,pos+atlast,-1): self.tracklist.DelTrack(prm) return True except: return False def get_playlist_posauto(self,autopath,securesec=10): ''' get playlist position skipping file with path equal to autopath. Try to secure that there are some time (securesec) to complete all operations in time: if xmms change song during operation will be a big problem ''' try: pos=self.get_playlist_securepos(securesec=securesec) if pos is None: return pos pos+=1 metadata=self.tracklist.GetMetadata(pos) try: #Fix how older versions of Audacious misreport the URI of the song. if metadata is not None: if "URI" in metadata and "location" not in metadata: metadata["location"] = metadata["URI"] file=metadata["location"] except: return pos filepath=os.path.dirname(file) #print "file://"+autopath #print os.path.commonprefix ((filepath,"file://"+autopath)) # ora controllo se ci sono gia dei file accodati nella playlist da autoradio # l'unica possibilita di saperlo e verificare il path del file while ( os.path.commonprefix ((filepath,"file://"+autopath)) == "file://"+autopath ): pos+=1 metadata=self.tracklist.GetMetadata(pos) try: #Fix how older versions of Audacious misreport the URI of the song. if metadata is not None: if "URI" in metadata and "location" not in metadata: metadata["location"] = metadata["URI"] file=metadata["location"] except: return pos filepath=os.path.dirname(file) # here I have found the first file added by autoradio return pos except : return None def get_playlist_len(self): "get playlist lenght" return self.tracklist.GetLength() def get_playlist_pos(self): "get current position" return self.tracklist.GetCurrentTrack() def get_metadata(self,pos): "get metadata for position" metadata=self.tracklist.GetMetadata(pos) try: file=metadata["location"] except: file=None try: title=metadata["title"] if title=="": title=None except: title=None try: artist=metadata["artist"] if artist=="": artist=None except: artist=None try: mtimelength=metadata["mtime"] except: mtimelength=0 try: mtimeposition=self.player.PositionGet() except: mtimeposition=0 mymeta={ "file": file, "title": title, "artist": artist, "mtimelength": mtimelength, "mtimeposition": mtimeposition } return mymeta def playlist_add_atpos(self,media,pos): "add media at pos postion in the playlist" if self.mediaplayer == "audacious": self.org.PlaylistInsUrlString(media,pos) return None else: logging.error("playlist_add_atpos: mpris interface cannot add media where I want for player "+self.mediaplayer ) raise Exception def main(): mp=mediaplayer(player="audacious") mp.play_ifnot() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autompris2.py000066400000000000000000000302221454362722700221600ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2012 Paolo Patruno. import dbus import time import datetime import os,sys from gi.repository import GObject as gobject from . import settings from dbus.mainloop.glib import DBusGMainLoop from .mpris2.mediaplayer2 import MediaPlayer2 from .mpris2.player import Player from .mpris2.tracklist import TrackList from .mpris2.interfaces import Interfaces from .mpris2.some_players import Some_Players from .mpris2.utils import get_players_uri from .mpris2.utils import get_session # ------- dbus mpris2 interface --------- # http://specifications.freedesktop.org/mpris-spec/latest/index.html # this is only a draft becouse when I try in fedora 16 # audacious do not have mpris2 interface # audacious 3.2.2 have mpris2 plugin but do not implement the optional # org.mpris.MediaPlayer2.TrackList and org.mpris.MediaPlayer2.Playlists interfaces # amarok 2.5.0 have mpris2 interface but do not implement the optional # org.mpris.MediaPlayer2.TrackList and org.mpris.MediaPlayer2.Playlists interfaces # vlc-1.1.13 do not have mpris2 interface; we need vlc >= 2.0 (http://wiki.videolan.org/Twoflower) # that is available from pat1 repo for Fedora 16 # About mpris2 and audacious: #Issue #106 has been updated by John Lindgren. # #Status changed from New to Rejected # #These interfaces require a different type of playlist structure than that used in Audacious, so they will not be implemented. #---------------------------------------- #Feature #106: mpris2 plugin do not implement optional org.mpris.MediaPlayer2.TrackList interface and org.mpris.MediaPlayer2.Playlists interface #http://redmine.audacious-media-player.org/issues/106#change-309 # #Author: Paolo Patruno #Status: Rejected #Priority: Minor #Assignee: #Category: plugins/mpris2 #Target version: #Affects version: 3.2.2 # # #at http://specifications.freedesktop.org/mpris-spec/latest/index.html # #Interface MediaPlayer2.Playlists #Provides access to the media player's playlists. # #Interface MediaPlayer2.TrackList #Provides access to a short list of tracks which were recently played or will be played shortly. This is intended to provide context to the #currently-playing track, rather than giving complete access to the media player's playlist. # #Those interfaces, if I am right, are not implemented in mpris2 plugin. #----------------------------------------------------------------------- class mediaplayer(object): def __init__(self,player="AutoPlayer",session=0, busaddress=settings.busaddressplayer): #qdbus --literal org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.TrackList Tracks # import gobject # gobject.threads_init() # # from dbus import glib # glib.init_threads() DBusGMainLoop(set_as_default=True) uris = list(get_players_uri(pattern=".*"+player+"$",busaddress=busaddress)) if len(uris) >0 : uri=uris[0] if busaddress is None: self.bus = dbus.SessionBus() else: self.bus = dbus.bus.BusConnection(busaddress) self.mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':self.bus}) self.play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':self.bus}) else: print("No players availables") return if self.mp2.HasTrackList: self.tl = TrackList(dbus_interface_info={'dbus_uri': uri,'dbus_session':self.bus}) else: self.tl = None def __str__(self): return self.play.PlaybackStatus def play_ifnot(self): ''' start playing if not. ''' # I check if mediaplayer is playing .... otherside I try to play if (not self.isplaying()): self.play.Play() def isplaying(self): ''' return true if is playing. ''' return self.play.PlaybackStatus == "Playing" def get_playlist_securepos(self,securesec=20): ''' Try to secure that there are some time (securesec) to complete all operations in time: if the player change song during operation will be a big problem ''' try: self.play_ifnot() #force to play mintimed=datetime.timedelta(seconds=securesec) toend=datetime.timedelta(seconds=0) volte=0 while ( toend < mintimed ): # take the current position pos=self.get_playlist_pos() metadata=self.get_metadata(pos) mtimelength=metadata["mtimelength"] mtimeposition=metadata["mtimeposition"] timed=datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimelength).seconds) toend=timed-datetime.timedelta(seconds=datetime.timedelta(milliseconds=mtimeposition).seconds) newpos=self.get_playlist_pos() if (pos != newpos): #inconsistenza: retry #print "retry" toend=datetime.timedelta(seconds=0) if ( toend < mintimed ): volte +=1 if volte > 10 : break # timeout , I have to play time.sleep(securesec+1) return pos except : return None def playlist_clear_up(self,atlast=10): ''' clear playlist starting from current position up. "atlast" numer of song are retained ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False # delete the old ones if pos > atlast : op=self.get_playlist() for prm in range(0,pos-atlast): #print "remove up: ",op[prm] self.tl.RemoveTrack( str(op[prm])) time.sleep(1) return True except: return False def playlist_clear_down(self,atlast=500): ''' clear playlist starting from current position + atlast doen. "atlast" numer of song are retained for future play ''' try: self.play_ifnot() #force to play # take the current position (if error set pos=0) pos=self.get_playlist_securepos() if pos is None: return False length=self.get_playlist_len() #elimino il troppo if length-pos > atlast : op=self.get_playlist() for prm in range(length-1,pos+atlast,-1): #print "remove down: ",op[prm] self.tl.RemoveTrack( str(op[prm]) ) time.sleep(1) return True except: return False def get_playlist_posauto(self,autopath,securesec=10): ''' get playlist position skipping file with path equal to autopath. Try to secure that there are some time (securesec) to complete all operations in time: if player change song during operation will be a big problem ''' try: pos=self.get_playlist_securepos(securesec=securesec) if pos is None or pos+1 == self.get_playlist_len(): return pos pos+=1 metadata=self.get_metadata(pos) try: file=metadata["file"] except: return pos filepath=os.path.dirname(file) #print "file://"+autopath #print os.path.commonprefix ((filepath,"file://"+autopath)) # ora controllo se ci sono gia dei file accodati nella playlist da autoradio # l'unica possibilita di saperlo e verificare il path del file while ( os.path.commonprefix ((filepath,"file://"+autopath)) == "file://"+autopath and pos+1 < self.get_playlist_len()): pos+=1 metadata=self.get_metadata(pos) try: file=metadata["file"] except: return pos filepath=os.path.dirname(file) # here I have found the first file added by autoradio return pos-1 except : return None def get_playlist(self): "get playlist" if self.tl is not None: return self.tl.Tracks else: raise Error def get_playlist_len(self): "get playlist lenght" if self.tl is not None: return len(self.tl.Tracks) else: return None def get_playlist_pos(self): "get current position" try: current=self.play.Metadata["mpris:trackid"] except: return None metadatas=self.tl.GetTracksMetadata(self.get_playlist()) id=0 for metadata in metadatas: if metadata["mpris:trackid"] == current: return id id +=1 return None def get_metadata(self,pos=None): "get metadata for position" if pos is None: return None metadatas=self.tl.GetTracksMetadata(self.get_playlist()) metadata=metadatas[pos] try: file=metadata["xesam:url"] except: file=None try: title=metadata["xesam:title"] if title=="": title=None except: title=None try: artist=metadata["xesam:artist"] if artist=="": artist=None except: artist=None try: mtimelength=metadata["mpris:length"] except: mtimelength=0 try: # get current truck current=self.play.Metadata["mpris:trackid"] if metadata["mpris:trackid"] == current : mtimeposition=self.play.Position else: mtimeposition=0 except: mtimeposition=0 mymeta={ "file": file, "title": title, "artist": artist, "mtimelength": int(round(mtimelength/1000.)), "mtimeposition": int(round(mtimeposition/1000.)) } return mymeta def playlist_add_atpos(self,media,pos): "add media at pos postion in the playlist" if pos is not None: self.tl.AddTrack(media,self.get_playlist()[pos],False) else: # the playlist is empty self.tl.AddTrack(media,"/org/mpris/MediaPlayer2/TrackList/NoTrack",False) time.sleep(1) return None # old style syntax: # # def trackremoved_callback(self,op): # print "removed:",op # # def trackadded_callback(self,diz,op): # print "added:",diz # print "added:",op # # def connect(self): # self.tracklist.connect_to_signal('TrackRemoved', self.trackremoved_callback) # self.tracklist.connect_to_signal('TrackAdded', self.trackadded_callback) def loop(self): '''start the main loop''' mainloop = gobject.MainLoop() mainloop.run() def main(): # must be done before connecting to DBus # DBusGMainLoop(set_as_default=True, mp=mediaplayer(player="AutoPlayer") print("status",mp) # mp.play_ifnot() # print mp # for id in xrange(mp.get_playlist_len()): # print mp.get_metadata(id) #mp.connect() #print "connected" #mp.loop() print("pos",mp.get_playlist_pos()) print("securepos") print(mp.get_playlist_securepos()) print("clear_up") print(mp.playlist_clear_up(atlast=2)) print("clear_down") print(mp.playlist_clear_down(atlast=3)) print("playlist") print(mp.get_playlist()) posauto=mp.get_playlist_posauto(autopath="/casa") print("posauto",posauto) print("add_atpos") mp.playlist_add_atpos("file:///home",posauto) ##mp.playlist_add_atpos("file:///home",3) if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autoplayer/000077500000000000000000000000001454362722700216675ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/autoplayer/__init__.py000066400000000000000000000000011454362722700237670ustar00rootroot00000000000000 autoradio-autoradio-3.6-4/autoradio/autoplayer/player.py000066400000000000000000001071561454362722700235470ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. # Authors: Paolo Patruno # Based on : # mpDris2 from Jean-Philippe Braun , # Mantas Mikulėnas # mpDris from: Erik Karlsson # Some bits taken from quodlibet mpris plugin by #TODO # manage signal # Interface MediaPlayer2.Player # Signals # Seeked (x: Position) # # Interface MediaPlayer2.TrackList # Signals # TrackListReplaced (ao: Tracks, o: CurrentTrack) # TrackAdded (a{sv}: Metadata, o: AfterTrack) # TrackRemoved (o: TrackId) # TrackMetadataChanged (o: TrackId, a{sv}: Metadata) # attentions! # for now we use TrackListReplaced with a empty and wrong signature # everywhere we change the tracklist # we use this in autoplayergui to update the tracklist import sys, time, _thread import tempfile,os #import pygst #pygst.require("0.10") #import gobject #import gst import gi gi.require_version('Gst', '1.0') from gi.repository import GObject, Gst from . import playlist import dbus import dbus.service import dbus.mainloop.glib import logging import signal IDENTITY = "Auto Player" STATUS_PLAYLIST="autoplayer.xspf" # python dbus bindings don't include annotations and properties MPRIS2_INTROSPECTION = """ """ PLAYER_IFACE="org.mpris.MediaPlayer2.Player" TRACKLIST_IFACE="org.mpris.MediaPlayer2.TrackList" IFACE="org.mpris.MediaPlayer2" class NotSupportedException(dbus.DBusException): _dbus_error_name = 'org.mpris.MediaPlayer2.Player.NotSupported' class AutoPlayer(dbus.service.Object): ''' The base object of an MPRIS player ''' __name = "org.mpris.MediaPlayer2.AutoPlayer" __path = "/org/mpris/MediaPlayer2" __introspect_interface = "org.freedesktop.DBus.Introspectable" __prop_interface = dbus.PROPERTIES_IFACE def __init__(self,busaddress=None): if busaddress is None: self._bus = dbus.SessionBus() else: self._bus =dbus.bus.BusConnection(busaddress) dbus.service.Object.__init__(self, self._bus, AutoPlayer.__path) self._uname = self._bus.get_unique_name() self._dbus_obj = self._bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") self._dbus_obj.connect_to_signal("NameOwnerChanged", self._name_owner_changed_callback, arg0=self.__name) self.acquire_name() def _name_owner_changed_callback(self, name, old_owner, new_owner): if name == self.__name and old_owner == self._uname and new_owner != "": try: pid = self._dbus_obj.GetConnectionUnixProcessID(new_owner) except: pid = None logging.info("Replaced by %s (PID %s)" % (new_owner, pid or "unknown")) self.player.loop.quit() def acquire_name(self): self._bus_name = dbus.service.BusName(AutoPlayer.__name, bus=self._bus, allow_replacement=True, replace_existing=True) def release_name(self): if hasattr(self, "_bus_name"): del self._bus_name def __PlaybackStatus(self): return self.player.playmode def __Metadata(self): meta=self.GetTracksMetadata((self.player.playlist.current,)) if len(meta) > 0: return dbus.Dictionary(meta[0], signature='sv') else: return dbus.Dictionary({}, signature='sv') #return {"mpris:trackid":self.player.playlist.current,} def __Position(self): position = self.player.position() if position is None: return dbus.UInt64(0) else: return dbus.UInt64(position) def __CanPlay(self): if self.player.playlist.current is None : return False else: return True def __Tracks(self): tracks=dbus.Array([], signature='s') for track in self.player.playlist: tracks.append(track) return tracks __root_interface = IFACE __root_props = { "CanQuit": (True, None), "CanRaise": (False, None), "DesktopEntry": ("AutoPlayer", None), "HasTrackList": (True, None), "Identity": (IDENTITY, None), "SupportedUriSchemes": (dbus.Array(signature="s"), None), "SupportedMimeTypes": (dbus.Array(signature="s"), None), "CanSetFullscreen": (False, None), } __player_interface = PLAYER_IFACE __player_props = { "PlaybackStatus": (__PlaybackStatus, None), "LoopStatus": (False, None), "Rate": (1.0, None), "Shuffle": (False, None), "Metadata": (__Metadata, None), "Volume": (1.0, None), "Position": (__Position, None), "MinimumRate": (1.0, None), "MaximumRate": (1.0, None), "CanGoNext": (True, None), "CanGoPrevious": (True, None), "CanPlay": (__CanPlay, None), "CanPause": (True, None), "CanSeek": (True, None), "CanControl": (True, None), } __tracklist_interface = TRACKLIST_IFACE __tracklist_props = { "CanEditTracks": (True, None), "Tracks": (__Tracks, None), } __prop_mapping = { __player_interface: __player_props, __root_interface: __root_props, __tracklist_interface: __tracklist_props, } @dbus.service.method(__introspect_interface) def Introspect(self): return MPRIS2_INTROSPECTION @dbus.service.signal(__prop_interface, signature="sa{sv}as") def PropertiesChanged(self, interface, changed_properties, invalidated_properties): pass @dbus.service.method(__prop_interface, in_signature="ss", out_signature="v") def Get(self, interface, prop): getter, setter = self.__prop_mapping[interface][prop] if callable(getter): return getter(self) return getter @dbus.service.method(__prop_interface, in_signature="ssv", out_signature="") def Set(self, interface, prop, value): getter, setter = self.__prop_mapping[interface][prop] if setter is not None: setter(self,value) @dbus.service.method(__prop_interface, in_signature="s", out_signature="a{sv}") def GetAll(self, interface): read_props = {} props = self.__prop_mapping[interface] for key, (getter, setter) in props.items(): if callable(getter): getter = getter(self) read_props[key] = getter return read_props def update_property(self, interface, prop): getter, setter = self.__prop_mapping[interface][prop] if callable(getter): value = getter(self) else: value = getter logging.debug('Updated property: %s = %s' % (prop, value)) self.PropertiesChanged(interface, {prop: value}, []) return value def attach_player(self,player): self.player=player @dbus.service.signal(PLAYER_IFACE,signature='x') def Seeked(self, position): logging.debug("Seeked to %i" % position) return float(position) # TrackListReplaced (ao: Tracks, o: CurrentTrack) @dbus.service.signal(TRACKLIST_IFACE,signature='') def TrackListReplaced(self): logging.debug("TrackListReplaced") # TrackAdded (a{sv}: Metadata, o: AfterTrack) @dbus.service.signal(TRACKLIST_IFACE,signature='a{sv}o') def TrackAdded(self, metadata=[],aftertrack=""): logging.debug("TrackAdded to %s" % aftertrack) # TrackRemoved (o: TrackId) @dbus.service.signal(TRACKLIST_IFACE,signature='o') def TrackRemoved(self,trackid): # here seem pydbus bug # disabled for now #process 22558: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_path (*string_p)" failed in file dbus-message.c line 2531. #This is normally a bug in some application using the D-Bus library. # D-Bus not built with -rdynamic so unable to print a backtrace #Annullato (core dumped) try: obp=dbus.ObjectPath("/org/mpris/MediaPlayer2/TrackList/"+trackid) except: logging.error("building ObjectPath to return in TrackRemoved %s" % trackid) obp=dbus.ObjectPath("/org/mpris/MediaPlayer2/TrackList/NoTrack") return obp @dbus.service.method(IFACE) def Raise(self): pass @dbus.service.method(IFACE) def Quit(self): self.player.exit() self.release_name() @dbus.service.method(PLAYER_IFACE) def Next(self): next(self.player) @dbus.service.method(PLAYER_IFACE) def Previous(self): self.player.previous() @dbus.service.method(PLAYER_IFACE) def Pause(self): self.player.pause() @dbus.service.method(PLAYER_IFACE) def PlayPause(self): self.player.playpause() @dbus.service.method(PLAYER_IFACE) def Stop(self): self.player.stop() @dbus.service.method(PLAYER_IFACE) def Play(self): logging.info( "Play") self.player.loaduri() self.player.play() @dbus.service.method(PLAYER_IFACE,in_signature='x') def Seek(self,offset): position=self.player.seek(offset) if position is not None: self.Seeked(position) @dbus.service.method(PLAYER_IFACE,in_signature='sx') def SetPosition(self,trackid,position): self.player.setposition(trackid,position) self.Seeked(position) @dbus.service.method(PLAYER_IFACE,in_signature='s') def OpenUri(self,uri): self.player.addtrack(uri,setascurrent=True) self.Stop() self.Play() self.TrackListReplaced() #TODO #self.TrackAdded(uri,"0") #self.update_property(TRACKLIST_IFACE,'TrackListReplaced') # If the media player implements the TrackList interface, then the opened # track should be made part of the tracklist, the # org.mpris.MediaPlayer2.TrackList.TrackAdded # or # org.mpris.MediaPlayer2.TrackList.TrackListReplaced # signal should be fired, as well as the # org.freedesktop.DBus.Properties.PropertiesChanged # signal on the tracklist interface. #tracklist @dbus.service.method(TRACKLIST_IFACE,in_signature='ssb', out_signature='') def AddTrack(self,uri, aftertrack, setascurrent): self.player.addtrack(uri, aftertrack, setascurrent) self.TrackListReplaced() @dbus.service.method(TRACKLIST_IFACE,in_signature='s', out_signature='') def RemoveTrack(self, trackid): if self.player.playlist.current == trackid: self.Next() self.player.removetrack(trackid) #disable for a bug in pydbus ?? logging.debug("TrackRemoved %s" % trackid) #TODO #self.TrackRemoved(trackid) self.TrackListReplaced() @dbus.service.method(TRACKLIST_IFACE,in_signature='s', out_signature='') def GoTo(self, trackid): self.player.goto(trackid) self.TrackListReplaced() @dbus.service.method(TRACKLIST_IFACE,in_signature='as', out_signature='aa{sv}') def GetTracksMetadata(self,trackids): metadata=dbus.Array([], signature='aa{sv}') for id in trackids: if id is not None: meta={} for key,attr in ("mpris:trackid","id"),("mpris:length","time"),("xesam:title","title"),("xesam:artist","artist"),("xesam:url","path"): try: myattr= getattr(self.player.playlist.get(id,None),attr,None) except: #very very strange to go here but it happen myattr=None if myattr is not None: if key == "mpris:length": myattr=dbus.UInt64(round(myattr/1000.)) meta[key]=myattr metadata.append(dbus.Dictionary(meta, signature='sv')) return metadata def updateinfo(self): if self.player.statuschanged: self.update_property(PLAYER_IFACE,"PlaybackStatus") self.player.statuschanged=False self.update_property(PLAYER_IFACE,"Position") return True # Handle signals more gracefully def handle_sigint(self,signum, frame): logging.debug('Caught SIGINT, exiting.') self.Quit() class Player(object): def __init__(self,myplaylist=None,loop=None,starttoplay=False,myaudiosink=None): self.playlist=myplaylist #self.player = gst.element_factory_make("playbin2", "playbin2") Gst.init(None) self.player = Gst.ElementFactory.make("playbin", None) try: self.rgvolume = Gst.ElementFactory.make("rgvolume", "rgvolume") self.player.set_property('audio-filter', self.rgvolume) except: logging.error( "setting replaygain player plugin") self.playmode = "Stopped" self.recoverplaymode = "Stopped" self.statuschanged = False self.starttoplay=starttoplay self.loop=loop if self.player is None: logging.error( "creating player") raise Exception("cannot create player!") #fakesink = gst.element_factory_make("fakesink", "fakesink") fakesink = Gst.ElementFactory.make("fakesink", None) self.player.set_property("video-sink", fakesink) ##icecast #print "Icecast selected" #bin = gst.Bin("my-bin") #audioconvert = gst.element_factory_make("audioconvert") #bin.add(audioconvert) #pad = audioconvert.get_pad("sink") #ghostpad = gst.GhostPad("sink", pad) #bin.add_pad(ghostpad) #audioresample = gst.element_factory_make("audioresample") #audioresample.set_property("quality", 0) #bin.add(audioresample) #capsfilter = gst.element_factory_make('capsfilter') #capsfilter.set_property('caps', gst.caps_from_string('audio/x-raw,rate=44100,channels=2')) ##bin.add(capsfilter) #vorbisenc = gst.element_factory_make("vorbisenc") #vorbisenc.set_property("quality", 0) #bin.add(vorbisenc) #oggmux = gst.element_factory_make("oggmux") #bin.add(oggmux) #streamsink = gst.element_factory_make("shout2send", "streamsink") #streamsink.set_property("ip", "localhost") ##streamsink.set_property("username", "source") #streamsink.set_property("password", "ackme") #streamsink.set_property("port", 8000) #streamsink.set_property("mount", "/myradio.ogg") #bin.add(streamsink) ### Link the elements #queue = gst.element_factory_make("queue", "queue") ##queue.link(audioresample, capsfilter) #bin.add(queue) #gst.element_link_many(audioconvert,audioresample,queue,vorbisenc,oggmux,streamsink) #self.player.set_property("audio-sink", bin) #audiosink = gst.element_factory_make("autoaudiosink") #audiosink = gst.element_factory_make("jackaudiosink") # ReplayGain #if (Gst.ElementFactory.find('rgvolume') and # Gst.ElementFactory.find('rglimiter')): # self.audioconvert = Gst.ElementFactory.make('audioconvert',None) # # self.rgvolume = Gst.ElementFactory.make('rgvolume',None) # self.rgvolume.set_property('album-mode', False) # self.rgvolume.set_property('pre-amp', 0) # self.rgvolume.set_property('fallback-gain', 0) # # self.rgvolume.set_property('headroom',0) # self.rgvolume.set_property('pre-amp',0) # # self.rglimiter = Gst.ElementFactory.make('rglimiter',None) # self.rglimiter.set_property('enabled', True) # # self.rgfilter = Gst.Bin() # self.rgfilter.add(self.rgvolume) # self.rgfilter.add(self.rglimiter) # self.rgvolume.link(self.rglimiter) # self.rgfilter.add_pad(Gst.GhostPad.new('sink', # self.rgvolume.get_static_pad('sink'))) # self.rgfilter.add_pad(Gst.GhostPad.new('src', # self.rglimiter.get_static_pad('src'))) # try: # self.player.set_property('audio-filter', self.rgfilter) # except: # logging.error( "setting replaygain player") # #raise Exception("cannot manage replaygain!") # TODO replaygain #+++++++ # #Example 40 # #From project rhythmbox-multiple-libraries, under directory plugins/replaygain/replaygain, in source file player.py. # #def setup_playbin2_mode(self): # print "using output filter for rgvolume and rglimiter" # self.rgvolume = gst.element_factory_make("rgvolume") # self.rgvolume.connect("notify::target-gain", self.playbin2_target_gain_cb) # self.rglimiter = gst.element_factory_make("rglimiter") # # # on track changes, we need to reset the rgvolume state, otherwise it # # carries over the tags from the previous track # self.pec_id = self.shell_player.connect('playing-song-changed', self.playing_entry_changed) # # # watch playbin2's uri property to see when a new track is opened # playbin = self.player.props.playbin # if playbin is None: # self.player.connect("notify::playbin", self.playbin2_notify_cb) # else: # playbin.connect("notify::uri", self.playbin2_uri_notify_cb) # # self.rgfilter = gst.Bin() # self.rgfilter.add(self.rgvolume, self.rglimiter) # self.rgvolume.link(self.rglimiter) # self.rgfilter.add_pad(gst.GhostPad("sink", self.rgvolume.get_static_pad("sink"))) # self.rgfilter.add_pad(gst.GhostPad("src", self.rglimiter.get_static_pad("src"))) # self.player.add_filter(self.rgfilter) # #+++++++++ if myaudiosink is None: myaudiosink = "autoaudiosink" audiosink = Gst.ElementFactory.make(myaudiosink,None) self.player.set_property("audio-sink", audiosink) # # self.player.set_property("audio-sink", streamsink) bus = self.player.get_bus() bus.add_signal_watch() # bus.connect("message", self.on_message) bus.connect('message::eos', self.on_message_eos) bus.connect('message::error', self.on_message_error) bus.connect("message::state-changed", self.on_message_state_changed) # def on_message(self,bus, message): # logging.debug('gst-bus: %s' % str(message)) # # log all error messages # if message.type == gst.MESSAGE_ERROR: # error, debug = map(str, message.parse_error()) # logging.error('gstreamer_autoplayer: %s'%error) # logging.debug('gstreamer_autoplayer: %s'%debug) def on_message_eos(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) logging.info( "fine file") #self.player.set_state(Gst.State.NULL) #self.playmode = "Stopped" #self.statuschanged = True next(self) def on_message_error(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) self.player.set_state(Gst.State.NULL) err, debug = message.parse_error() logging.error( " %s: %s " % (err, debug)) logging.warning("restart to play after an ERROR skipping current media") currenturi = self.playlist.get_current().path logging.warning("current media: %s" % currenturi) self.playmode= self.recoverplaymode next(self) # if err.domain == gst.RESOURCE_ERROR : # logging.warning("restart to play after an RESOURCE_ERROR") # self.playmode= self.recoverplaymode # self.next() # else: # logging.warning("stop to play after an ERROR") # self.stop() # self.playmode = "Stopped" # self.statuschanged = True def on_message_state_changed(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) #if isinstance(message.src, gst.Pipeline): if isinstance(message.src, Gst.Pipeline): old_state, new_state, pending_state = message.parse_state_changed() # Gst.State.NULL the NULL state or initial state of an element # Gst.State.PAUSED the element is PAUSED # Gst.State.PLAYING the element is PLAYING # Gst.State.READY the element is ready to go to PAUSED # Gst.State.VOID_PENDING no pending state if pending_state == Gst.State.VOID_PENDING: logging.debug("Pipeline state changed from %s to %s. Pendig: %s"% (Gst.Element.state_get_name(old_state), Gst.Element.state_get_name (new_state), Gst.Element.state_get_name (pending_state))) if new_state == Gst.State.READY : self.playmode = "Stopped" self.statuschanged = True elif new_state == Gst.State.PAUSED: self.playmode = "Paused" self.statuschanged = True elif new_state == Gst.State.PLAYING : self.playmode = "Playing" self.statuschanged = True def __next__(self): logging.info( "next") next(self.playlist) if self.playlist.current is None: logging.info( "end playlist") self.stop() else: playmode=self.playmode self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def previous(self): logging.info( "previous") self.playlist.previous() if self.playlist.current is None: logging.info( "head playlist") self.stop() else: playmode=self.playmode self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def convert_ns(self, t): s,ns = divmod(t, 1000000000) m,s = divmod(s, 60) if m < 60: return "%02i:%02i" %(m,s) else: h,m = divmod(m, 60) return "%i:%02i:%02i" %(h,m,s) def seek(self,t): """ t in microseconds """ logging.info("seek") try: pos_int = self.player.query_position(Gst.Format.TIME)[1] pos_int =int(pos_int/1000) + t logging.info("seek %s" % str(pos_int)) self.setposition(self.playlist.current,pos_int) return pos_int except: logging.error( "in seek") return None def setposition(self,trackid,t): """ t in microseconds """ if trackid != self.playlist.current: logging.warning( "setposition trackid is not current trackid") try: logging.info("set position") pos_int = self.player.query_duration(Gst.Format.TIME)[1] tnano=t*1000 if tnano >= 0 and tnano <= pos_int : logging.debug("set position to: %s; len: %s" % (str(t),str(pos_int))) #if wait: self.playbin.get_state(timeout=50*gst.MSECOND) event = Gst.Event.new_seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH|Gst.SeekFlags.ACCURATE, Gst.SeekType.SET, tnano, Gst.SeekType.NONE, 0) res = self.player.send_event(event) if res: #self.player.set_new_stream_time(0L) self.player.set_start_time(0) #if wait: self.playbin.get_state(timeout=50*gst.MSECOND) # this cause a doble seek with playbin2 #self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, t) except: logging.error( "in setposition") def loaduri(self): logging.info( "loaduri") if self.playlist.current is None: if len(list(self.playlist.keys())) > 0: self.playlist.set_current(list(self.playlist.keys())[0]) uri = self.playlist.get_current().path if uri is not None: self.player.set_property("uri", uri) ret = self.player.set_state(Gst.State.READY) #if ret == Gst.State.CHANGE_FAILURE: if ret == Gst.StateChangeReturn.FAILURE: logging.error( "Unable to set the pipeline to the READY state.") def play(self): logging.info( "play") self.recoverplaymode = "Playing" ret = self.player.set_state(Gst.State.PLAYING) #if ret == Gst.State.CHANGE_FAILURE: if ret == Gst.StateChangeReturn.FAILURE: logging.error( "Unable to set the pipeline to the PLAYING state.") #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def pause(self): logging.info( "pause") self.recoverplaymode = "Paused" ret = self.player.set_state(Gst.State.PAUSED) #if ret == Gst.State.CHANGE_FAILURE: if ret == Gst.StateChangeReturn.FAILURE: logging.error( "Unable to set the pipeline to the PAUSED state.") #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def playpause(self): if self.playmode == "Playing": self.pause() elif self.playmode == "Stopped": self.loaduri() self.play() elif self.playmode == "Paused": self.play() def stop(self): logging.info( "stop") self.recoverplaymode = "Stopped" #self.loaduri() ret = self.player.set_state(Gst.State.READY) #if ret == Gst.State.CHANGE_FAILURE: if ret == Gst.StateChangeReturn.FAILURE: logging.error( "Unable to set the pipeline to the READY state.") #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def position(self): """ return microseconds """ try: pos_int = self.player.query_position(Gst.Format.TIME)[1] # this should be better but how have we to do in gstreamer 1 ? #except(Gst.QueryError): except Exception as e: logging.warning( "in query_position:"+str(e) ) return None return int(round(pos_int/1000.)) def printinfo(self): try: pos_int = self.player.query_position(Gst.Format.TIME)[1] dur_int = self.player.query_duration(Gst.Format.TIME)[1] # if dur_int == -1: # print "bho" print(self.playmode,self.convert_ns(pos_int)+"//"+self.convert_ns(dur_int)) except(Gst.QueryError): #print "error printinfo" pass return True def save_playlist(self,path): position=self.position() if position is None: self.playlist.position=position else: self.playlist.position=self.position()*1000 try: fd,tmpfile=tempfile.mkstemp(dir=os.path.dirname(os.path.abspath(path))) self.playlist.write(tmpfile) os.close(fd) #see at https://www.logilab.org/blogentry/17873 #if os.path.exists(path): # os.unlink(path) os.rename(tmpfile, path) except: logging.error( "error saving playlist") raise finally: if os.path.exists(tmpfile): os.unlink(tmpfile) logging.info ( "playlist saved %s" % path) return True def initialize(self): self.loaduri() self.pause() return False def recoverstatus(self): if self.playmode != "Paused": logging.info ( "wait for player going paused: %s" % self.playmode) return True time.sleep(1) logging.info ( "recover last status from disk: position %s" % self.playlist.position) if self.playlist.position is not None: logging.info ( "set current %s and position %s " % (self.playlist.current,int(round(self.playlist.position/1000.)))) self.setposition(self.playlist.current,int(round(self.playlist.position/1000.))) if self.starttoplay: time.sleep(1) self.play() return False def addtrack(self,uri, aftertrack=None, setascurrent=False): if aftertrack == "/org/mpris/MediaPlayer2/TrackList/NoTrack": aftertrack=None current = self.playlist.current self.playlist=self.playlist.addtrack(uri,aftertrack,setascurrent) if setascurrent: playmode=self.playmode if self.playlist.current != current: self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def removetrack(self,trackid): self.playlist=self.playlist.removetrack(trackid) #print "indice: ",str(self.playlist.keys().index(trackid)) #for id,track in enumerate(self.playlist): # print id,track def goto(self,trackid): self.playlist.set_current(trackid) self.stop() self.loaduri() self.play() def exit(self): logging.info("save playlist: %s" % STATUS_PLAYLIST ) self.save_playlist(STATUS_PLAYLIST) self.stop() self.loop.quit() def main(busaddress=None,myaudiosink=None): # Use logging for ouput at different *levels*. # logging.getLogger().setLevel(logging.INFO) log = logging.getLogger("autoplayer") handler = logging.StreamHandler(sys.stderr) log.addHandler(handler) # logging.basicConfig(level=logging.INFO,) # try: # os.chdir(cwd) # except: # pass pl=playlist.Playlist() pl.read(STATUS_PLAYLIST) #plmpris=playlist.Playlist_mpris2(pl,pl.current,pl.position) plmpris=playlist.Playlist_mpris2(pl) #save to update playlist to make monit happy pl.write(STATUS_PLAYLIST) if len(sys.argv) >= 2: #if you come from autoplayerd argv[1] is run/start/stop ... for media in sys.argv[2:]: logging.info( "add media: %s" %media) # mmm here seems not work ... the new plmpris is not good !!! plmpris=plmpris.addtrack(media,setascurrent=True) try: dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) #loop = gobject.MainLoop() loop=GObject.MainLoop() mp = Player(plmpris,loop=loop,starttoplay=True,myaudiosink=myaudiosink) # Export our DBUS service #if not dbus_service: #dbus_service = MPRIS2Interface() #else: # Add our service to the session bus # dbus_service.acquire_name() ap = AutoPlayer(busaddress=busaddress) ap.attach_player(mp) #gobject.timeout_add( 100,ap.player.initialize) #gobject.timeout_add( 200,ap.player.recoverstatus) #gobject.timeout_add( 500,ap.updateinfo) #gobject.timeout_add(60000,ap.player.save_playlist,"autoplayer.xspf") ##gobject.timeout_add( 1000,ap.player.printinfo) GObject.timeout_add( 100,ap.player.initialize) GObject.timeout_add( 200,ap.player.recoverstatus) GObject.timeout_add( 500,ap.updateinfo) GObject.timeout_add(60000,ap.player.save_playlist,STATUS_PLAYLIST) #GObject.timeout_add( 1000,ap.player.printinfo) signal.signal(signal.SIGINT, ap.handle_sigint) loop.run() # Clean up logging.debug('Exiting') except KeyboardInterrupt : # Clean up logging.debug('Keyboard Exiting') ap.Quit() # thread.start_new_thread(mp.loop, ()) # object.threads_init() # context = loop.get_context() # gobject.MainLoop().run() # while True: # context.iteration(True) if __name__ == '__main__': main()# (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autoplayer/player_gstreamer0.py000066400000000000000000000757751454362722700257130ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. # Authors: Paolo Patruno # Based on : # mpDris2 from Jean-Philippe Braun , # Mantas Mikulėnas # mpDris from: Erik Karlsson # Some bits taken from quodlibet mpris plugin by #TODO # manage signal # Interface MediaPlayer2.Player # Signals # Seeked (x: Position) # # Interface MediaPlayer2.TrackList # Signals # TrackListReplaced (ao: Tracks, o: CurrentTrack) # TrackAdded (a{sv}: Metadata, o: AfterTrack) # TrackRemoved (o: TrackId) # TrackMetadataChanged (o: TrackId, a{sv}: Metadata) import sys, time, _thread from gi.repository import GObject as gobject import pygst pygst.require("0.10") import gst from . import playlist import dbus import dbus.service import dbus.mainloop.glib import logging import signal IDENTITY = "Auto Player" STATUS_PLAYLIST="autoplayer.xspf" # python dbus bindings don't include annotations and properties MPRIS2_INTROSPECTION = """ """ PLAYER_IFACE="org.mpris.MediaPlayer2.Player" TRACKLIST_IFACE="org.mpris.MediaPlayer2.TrackList" IFACE="org.mpris.MediaPlayer2" class NotSupportedException(dbus.DBusException): _dbus_error_name = 'org.mpris.MediaPlayer2.Player.NotSupported' class AutoPlayer(dbus.service.Object): ''' The base object of an MPRIS player ''' __name = "org.mpris.MediaPlayer2.AutoPlayer" __path = "/org/mpris/MediaPlayer2" __introspect_interface = "org.freedesktop.DBus.Introspectable" __prop_interface = dbus.PROPERTIES_IFACE def __init__(self,busaddress=None): if busaddress is None: self._bus = dbus.SessionBus() else: self._bus =dbus.bus.BusConnection(busaddress) dbus.service.Object.__init__(self, self._bus, AutoPlayer.__path) self._uname = self._bus.get_unique_name() self._dbus_obj = self._bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") self._dbus_obj.connect_to_signal("NameOwnerChanged", self._name_owner_changed_callback, arg0=self.__name) self.acquire_name() def _name_owner_changed_callback(self, name, old_owner, new_owner): if name == self.__name and old_owner == self._uname and new_owner != "": try: pid = self._dbus_obj.GetConnectionUnixProcessID(new_owner) except: pid = None logging.info("Replaced by %s (PID %s)" % (new_owner, pid or "unknown")) self.player.loop.quit() def acquire_name(self): self._bus_name = dbus.service.BusName(AutoPlayer.__name, bus=self._bus, allow_replacement=True, replace_existing=True) def release_name(self): if hasattr(self, "_bus_name"): del self._bus_name def __PlaybackStatus(self): return self.player.playmode def __Metadata(self): meta=self.GetTracksMetadata((self.player.playlist.current,)) if len(meta) > 0: return dbus.Dictionary(meta[0], signature='sv') else: return dbus.Dictionary({}, signature='sv') #return {"mpris:trackid":self.player.playlist.current,} def __Position(self): position = self.player.position() if position is None: return dbus.Int64(0) else: return dbus.Int64(position) def __CanPlay(self): if self.player.playlist.current is None : return False else: return True def __Tracks(self): tracks=dbus.Array([], signature='s') for track in self.player.playlist: tracks.append(track) return tracks __root_interface = IFACE __root_props = { "CanQuit": (True, None), "CanRaise": (False, None), "DesktopEntry": ("AutoPlayer", None), "HasTrackList": (True, None), "Identity": (IDENTITY, None), "SupportedUriSchemes": (dbus.Array(signature="s"), None), "SupportedMimeTypes": (dbus.Array(signature="s"), None), "CanSetFullscreen": (False, None), } __player_interface = PLAYER_IFACE __player_props = { "PlaybackStatus": (__PlaybackStatus, None), "LoopStatus": (False, None), "Rate": (1.0, None), "Shuffle": (False, None), "Metadata": (__Metadata, None), "Volume": (1.0, None), "Position": (__Position, None), "MinimumRate": (1.0, None), "MaximumRate": (1.0, None), "CanGoNext": (True, None), "CanGoPrevious": (True, None), "CanPlay": (__CanPlay, None), "CanPause": (True, None), "CanSeek": (True, None), "CanControl": (True, None), } __tracklist_interface = TRACKLIST_IFACE __tracklist_props = { "CanEditTracks": (True, None), "Tracks": (__Tracks, None), } __prop_mapping = { __player_interface: __player_props, __root_interface: __root_props, __tracklist_interface: __tracklist_props, } @dbus.service.method(__introspect_interface) def Introspect(self): return MPRIS2_INTROSPECTION @dbus.service.signal(__prop_interface, signature="sa{sv}as") def PropertiesChanged(self, interface, changed_properties, invalidated_properties): pass @dbus.service.method(__prop_interface, in_signature="ss", out_signature="v") def Get(self, interface, prop): getter, setter = self.__prop_mapping[interface][prop] if callable(getter): return getter(self) return getter @dbus.service.method(__prop_interface, in_signature="ssv", out_signature="") def Set(self, interface, prop, value): getter, setter = self.__prop_mapping[interface][prop] if setter is not None: setter(self,value) @dbus.service.method(__prop_interface, in_signature="s", out_signature="a{sv}") def GetAll(self, interface): read_props = {} props = self.__prop_mapping[interface] for key, (getter, setter) in props.items(): if callable(getter): getter = getter(self) read_props[key] = getter return read_props def update_property(self, interface, prop): getter, setter = self.__prop_mapping[interface][prop] if callable(getter): value = getter(self) else: value = getter logging.debug('Updated property: %s = %s' % (prop, value)) self.PropertiesChanged(interface, {prop: value}, []) return value def attach_player(self,player): self.player=player @dbus.service.signal(PLAYER_IFACE,signature='x') def Seeked(self, position): logging.debug("Seeked to %i" % position) return float(position) # TrackAdded (a{sv}: Metadata, o: AfterTrack) @dbus.service.signal(TRACKLIST_IFACE,signature='a{sv}o') def TrackAdded(self, metadata,aftertrack): logging.debug("TrackAdded to %s" % aftertrack) pass # TrackRemoved (o: TrackId) @dbus.service.signal(TRACKLIST_IFACE,signature='o') def TrackRemoved(self,trackid): logging.debug("TrackRemoved %s" % trackid) # here seem pydbus bug # disabled for now #process 22558: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_path (*string_p)" failed in file dbus-message.c line 2531. #This is normally a bug in some application using the D-Bus library. # D-Bus not built with -rdynamic so unable to print a backtrace #Annullato (core dumped) try: obp=dbus.ObjectPath("/org/mpris/MediaPlayer2/TrackList/"+trackid) except: logging.error("building ObjectPath to return in TrackRemoved %s" % trackid) obp=dbus.ObjectPath("/org/mpris/MediaPlayer2/TrackList/NoTrack") return obp @dbus.service.method(IFACE) def Raise(self): pass @dbus.service.method(IFACE) def Quit(self): self.player.exit() self.release_name() @dbus.service.method(PLAYER_IFACE) def Next(self): next(self.player) @dbus.service.method(PLAYER_IFACE) def Previous(self): self.player.previous() @dbus.service.method(PLAYER_IFACE) def Pause(self): self.player.pause() @dbus.service.method(PLAYER_IFACE) def PlayPause(self): self.player.playpause() @dbus.service.method(PLAYER_IFACE) def Stop(self): self.player.stop() @dbus.service.method(PLAYER_IFACE) def Play(self): logging.info( "Play") self.player.loaduri() self.player.play() @dbus.service.method(PLAYER_IFACE,in_signature='x') def Seek(self,offset): position=self.player.seek(offset) if position is not None: self.Seeked(position) @dbus.service.method(PLAYER_IFACE,in_signature='sx') def SetPosition(self,trackid,position): self.player.setposition(trackid,position) self.Seeked(position) @dbus.service.method(PLAYER_IFACE,in_signature='s') def OpenUri(self,uri): self.player.addtrack(uri,setascurrent=True) self.Stop() self.Play() #TODO #self.TrackAdded() #self.update_property(TRACKLIST_IFACE,'TrackListReplaced') # If the media player implements the TrackList interface, then the opened # track should be made part of the tracklist, the # org.mpris.MediaPlayer2.TrackList.TrackAdded # or # org.mpris.MediaPlayer2.TrackList.TrackListReplaced # signal should be fired, as well as the # org.freedesktop.DBus.Properties.PropertiesChanged # signal on the tracklist interface. #tracklist @dbus.service.method(TRACKLIST_IFACE,in_signature='ssb', out_signature='') def AddTrack(self,uri, aftertrack, setascurrent): self.player.addtrack(uri, aftertrack, setascurrent) @dbus.service.method(TRACKLIST_IFACE,in_signature='s', out_signature='') def RemoveTrack(self, trackid): if self.player.playlist.current == trackid: self.Next() self.player.removetrack(trackid) #disable for a bug in pydbus ?? #self.TrackRemoved(trackid) @dbus.service.method(TRACKLIST_IFACE,in_signature='s', out_signature='') def GoTo(self, trackid): self.player.goto(trackid) @dbus.service.method(TRACKLIST_IFACE,in_signature='as', out_signature='aa{sv}') def GetTracksMetadata(self,trackids): metadata=dbus.Array([], signature='aa{sv}') for id in trackids: if id is not None: meta={} for key,attr in ("mpris:trackid","id"),("mpris:length","time"),("xesam:title","title"),("xesam:artist","artist"),("xesam:url","path"): myattr= getattr(self.player.playlist[id],attr,None) if myattr is not None: if key == "mpris:length": myattr=int(round(myattr/1000.)) meta[key]=myattr metadata.append(dbus.Dictionary(meta, signature='sv')) return metadata def updateinfo(self): if self.player.statuschanged: self.update_property(PLAYER_IFACE,"PlaybackStatus") self.player.statuschanged=False self.update_property(PLAYER_IFACE,"Position") return True # Handle signals more gracefully def handle_sigint(self,signum, frame): logging.debug('Caught SIGINT, exiting.') self.Quit() class Player(object): def __init__(self,myplaylist=None,loop=None,starttoplay=False,myaudiosink=None): self.playlist=myplaylist self.player = gst.element_factory_make("playbin2", "playbin2") self.playmode = "Stopped" self.recoverplaymode = "Stopped" self.statuschanged = False self.starttoplay=starttoplay self.loop=loop if self.player is None: logging.error( "creating player") fakesink = gst.element_factory_make("fakesink", "fakesink") self.player.set_property("video-sink", fakesink) ##icecast #print "Icecast selected" #bin = gst.Bin("my-bin") #audioconvert = gst.element_factory_make("audioconvert") #bin.add(audioconvert) #pad = audioconvert.get_pad("sink") #ghostpad = gst.GhostPad("sink", pad) #bin.add_pad(ghostpad) #audioresample = gst.element_factory_make("audioresample") #audioresample.set_property("quality", 0) #bin.add(audioresample) #capsfilter = gst.element_factory_make('capsfilter') #capsfilter.set_property('caps', gst.caps_from_string('audio/x-raw,rate=44100,channels=2')) ##bin.add(capsfilter) #vorbisenc = gst.element_factory_make("vorbisenc") #vorbisenc.set_property("quality", 0) #bin.add(vorbisenc) #oggmux = gst.element_factory_make("oggmux") #bin.add(oggmux) #streamsink = gst.element_factory_make("shout2send", "streamsink") #streamsink.set_property("ip", "localhost") ##streamsink.set_property("username", "source") #streamsink.set_property("password", "ackme") #streamsink.set_property("port", 8000) #streamsink.set_property("mount", "/myradio.ogg") #bin.add(streamsink) ### Link the elements #queue = gst.element_factory_make("queue", "queue") ##queue.link(audioresample, capsfilter) #bin.add(queue) #gst.element_link_many(audioconvert,audioresample,queue,vorbisenc,oggmux,streamsink) #self.player.set_property("audio-sink", bin) #audiosink = gst.element_factory_make("autoaudiosink") #audiosink = gst.element_factory_make("jackaudiosink") if myaudiosink is None: myaudiosink = "autoaudiosink" audiosink = gst.element_factory_make(myaudiosink) self.player.set_property("audio-sink", audiosink) # # self.player.set_property("audio-sink", streamsink) bus = self.player.get_bus() bus.add_signal_watch() # bus.connect("message", self.on_message) bus.connect('message::eos', self.on_message_eos) bus.connect('message::error', self.on_message_error) bus.connect("message::state-changed", self.on_message_state_changed) # def on_message(self,bus, message): # logging.debug('gst-bus: %s' % str(message)) # # log all error messages # if message.type == gst.MESSAGE_ERROR: # error, debug = map(str, message.parse_error()) # logging.error('gstreamer_autoplayer: %s'%error) # logging.debug('gstreamer_autoplayer: %s'%debug) def on_message_eos(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) logging.info( "fine file") #self.player.set_state(gst.STATE_NULL) #self.playmode = "Stopped" #self.statuschanged = True next(self) def on_message_error(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) self.player.set_state(gst.STATE_NULL) err, debug = message.parse_error() logging.error( " %s: %s " % (err, debug)) logging.warning("restart to play after an ERROR skipping current media") self.playmode= self.recoverplaymode next(self) # if err.domain == gst.RESOURCE_ERROR : # logging.warning("restart to play after an RESOURCE_ERROR") # self.playmode= self.recoverplaymode # self.next() # else: # logging.warning("stop to play after an ERROR") # self.stop() # self.playmode = "Stopped" # self.statuschanged = True def on_message_state_changed(self, bus, message): t = message.type logging.debug("Message type %s received; source %s" % (t,type(message.src))) if isinstance(message.src, gst.Pipeline): old_state, new_state, pending_state = message.parse_state_changed() # gst.STATE_NULL the NULL state or initial state of an element # gst.STATE_PAUSED the element is PAUSED # gst.STATE_PLAYING the element is PLAYING # gst.STATE_READY the element is ready to go to PAUSED # gst.STATE_VOID_PENDING no pending state if pending_state == gst.STATE_VOID_PENDING: logging.debug("Pipeline state changed from %s to %s. Pendig: %s"% (gst.element_state_get_name(old_state), gst.element_state_get_name (new_state), gst.element_state_get_name (pending_state))) if new_state == gst.STATE_READY : self.playmode = "Stopped" self.statuschanged = True elif new_state == gst.STATE_PAUSED: self.playmode = "Paused" self.statuschanged = True elif new_state == gst.STATE_PLAYING : self.playmode = "Playing" self.statuschanged = True def __next__(self): logging.info( "next") next(self.playlist) if self.playlist.current is None: logging.info( "end playlist") self.stop() else: playmode=self.playmode self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def previous(self): logging.info( "previous") self.playlist.previous() if self.playlist.current is None: logging.info( "head playlist") self.stop() else: playmode=self.playmode self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def convert_ns(self, t): s,ns = divmod(t, 1000000000) m,s = divmod(s, 60) if m < 60: return "%02i:%02i" %(m,s) else: h,m = divmod(m, 60) return "%i:%02i:%02i" %(h,m,s) def seek(self,t): """ t in microseconds """ logging.info("seek") try: pos_int = self.player.query_position(gst.FORMAT_TIME, None)[0] pos_int =int(pos_int/1000) + t logging.info("seek %s" % str(pos_int)) self.setposition(self.playlist.current,pos_int) return pos_int except: logging.error( "in seek") return None def setposition(self,trackid,t): """ t in microseconds """ if trackid != self.playlist.current: logging.warning( "setposition trackid is not current trackid") try: logging.info("set position") pos_int = self.player.query_duration(gst.FORMAT_TIME, None)[0] tnano=t*1000 if tnano >= 0 and tnano <= pos_int : logging.debug("set position to: %s; len: %s" % (str(t),str(pos_int))) #if wait: self.playbin.get_state(timeout=50*gst.MSECOND) event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH|gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, tnano, gst.SEEK_TYPE_NONE, 0) res = self.player.send_event(event) if res: self.player.set_new_stream_time(0) #if wait: self.playbin.get_state(timeout=50*gst.MSECOND) # this cause a doble seek with playbin2 #self.player.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, t) except: logging.error( "in setposition") def loaduri(self): logging.info( "loaduri") if self.playlist.current is None: if len(list(self.playlist.keys())) > 0: self.playlist.set_current(list(self.playlist.keys())[0]) uri = self.playlist.get_current().path if uri is not None: self.player.set_property("uri", uri) ret = self.player.set_state(gst.STATE_READY) if ret == gst.STATE_CHANGE_FAILURE: logging.error( "Unable to set the pipeline to the READY state.") def play(self): logging.info( "play") ret = self.player.set_state(gst.STATE_PLAYING) if ret == gst.STATE_CHANGE_FAILURE: logging.error( "Unable to set the pipeline to the PLAYING state.") self.recoverplaymode = "Playing" #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def pause(self): logging.info( "pause") ret = self.player.set_state(gst.STATE_PAUSED) if ret == gst.STATE_CHANGE_FAILURE: logging.error( "Unable to set the pipeline to the PAUSED state.") self.recoverplaymode = "Paused" #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def playpause(self): if self.playmode == "Playing": self.pause() elif self.playmode == "Stopped": self.loaduri() self.play() elif self.playmode == "Paused": self.play() def stop(self): logging.info( "stop") #self.loaduri() ret = self.player.set_state(gst.STATE_READY) if ret == gst.STATE_CHANGE_FAILURE: logging.error( "Unable to set the pipeline to the READY state.") self.recoverplaymode = "Stopped" #else: # print self.player.get_state(timeout=gst.CLOCK_TIME_NONE) def position(self): """ return microseconds """ try: pos_int = self.player.query_position(gst.FORMAT_TIME, None)[0] except(gst.QueryError): logging.warning( "gst.QueryError in query_position" ) return None return int(round(pos_int/1000.)) def printinfo(self): try: pos_int = self.player.query_position(gst.FORMAT_TIME, None)[0] dur_int = self.player.query_duration(gst.FORMAT_TIME, None)[0] # if dur_int == -1: # print "bho" print(self.playmode,self.convert_ns(pos_int)+"//"+self.convert_ns(dur_int)) except(gst.QueryError): #print "error printinfo" pass return True def save_playlist(self,path): position=self.position() if position is None: self.playlist.position=position else: self.playlist.position=self.position()*1000 try: self.playlist.write(path) except: logging.error( "error saving playlist") raise logging.info ( "playlist saved %s" % path) return True def initialize(self): self.loaduri() self.pause() return False def recoverstatus(self): if self.playmode != "Paused": logging.info ( "wait for player going paused: %s" % self.playmode) return True time.sleep(1) logging.info ( "recover last status from disk: position %s" % self.playlist.position) if self.playlist.position is not None: logging.info ( "set current %s and position %s " % (self.playlist.current,int(round(self.playlist.position/1000.)))) self.setposition(self.playlist.current,int(round(self.playlist.position/1000.))) if self.starttoplay: time.sleep(1) self.play() return False def addtrack(self,uri, aftertrack=None, setascurrent=False): if aftertrack == "/org/mpris/MediaPlayer2/TrackList/NoTrack": aftertrack=None current = self.playlist.current self.playlist=self.playlist.addtrack(uri,aftertrack,setascurrent) if setascurrent: playmode=self.playmode if self.playlist.current != current: self.stop() self.loaduri() if playmode == "Playing": self.play() elif playmode == "Paused": self.pause() def removetrack(self,trackid): self.playlist=self.playlist.removetrack(trackid) #print "indice: ",str(self.playlist.keys().index(trackid)) #for id,track in enumerate(self.playlist): # print id,track def goto(self,trackid): self.playlist.set_current(trackid) self.stop() self.loaduri() self.play() def exit(self): logging.info("save playlist: %s" % STATUS_PLAYLIST ) self.save_playlist(STATUS_PLAYLIST) self.stop() self.loop.quit() def main(busaddress=None,myaudiosink=None): # Use logging for ouput at different *levels*. # logging.getLogger().setLevel(logging.INFO) log = logging.getLogger("autoplayer") handler = logging.StreamHandler(sys.stderr) log.addHandler(handler) # logging.basicConfig(level=logging.INFO,) # try: # os.chdir(cwd) # except: # pass pl=playlist.Playlist() pl.read("autoplayer.xspf") #plmpris=playlist.Playlist_mpris2(pl,pl.current,pl.position) plmpris=playlist.Playlist_mpris2(pl) if len(sys.argv) >= 2: #if you come from autoplayerd argv[1] is run/start/stop ... for media in sys.argv[2:]: logging.info( "add media: %s" %media) # mmm here seems not work ... the new plmpris is not good !!! plmpris=plmpris.addtrack(media,setascurrent=True) try: dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) loop = gobject.MainLoop() mp = Player(plmpris,loop=loop,starttoplay=True,myaudiosink=myaudiosink) # Export our DBUS service #if not dbus_service: #dbus_service = MPRIS2Interface() #else: # Add our service to the session bus # dbus_service.acquire_name() ap = AutoPlayer(busaddress=busaddress) ap.attach_player(mp) gobject.timeout_add( 100,ap.player.initialize) gobject.timeout_add( 200,ap.player.recoverstatus) gobject.timeout_add( 500,ap.updateinfo) gobject.timeout_add(60000,ap.player.save_playlist,"autoplayer.xspf") #gobject.timeout_add( 1000,ap.player.printinfo) signal.signal(signal.SIGINT, ap.handle_sigint) loop.run() # Clean up logging.debug('Exiting') except KeyboardInterrupt : # Clean up logging.debug('Keyboard Exiting') ap.Quit() # thread.start_new_thread(mp.loop, ()) # object.threads_init() # context = loop.get_context() # gobject.MainLoop().run() # while True: # context.iteration(True) if __name__ == '__main__': main()# (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autoplayer/playlist.py000066400000000000000000000376111454362722700241120ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. import logging import collections import mutagen import sys from xml.sax import make_parser, handler, SAXParseException from xml.dom.minidom import Document import urllib.request, urllib.parse, urllib.error, urllib.parse class Track(collections.namedtuple('Track',("path","time","artist","album","title","id"))): __slots__ = () def get_metadata(self): metadata=collections.OrderedDict() metadata["path"] =self.path metadata["time"] = 0 metadata["artist"]=None metadata["album"]=None metadata["title"]=None metadata["id"]=self.id try: # m=mutagen.File(self.path[7:].encode(sys.getfilesystemencoding()),easy=True) m=mutagen.File(self.path[7:],easy=True) # in seconds (type float). metadata["time"] = int(m.info.length*1000000000) value = m.get("artist") if value: metadata["artist"]=value[0]#.encode("UTF-8") value = m.get("album") if value: metadata["album"]=value[0]#.encode("UTF-8") value = m.get("title") if value: metadata["title"]=value[0]#.encode("UTF-8") except: logging.error("Could not read info from file: %s ",self.path) return metadata def parse_pls(lines): # titles = {} songs = {} for line in lines: spl = line.split( '=', 1) if len(spl) == 2: name, value = spl if name.lower().startswith('file'): num = name[4:] try: n = int(num) except: pass else: songs["%05d" % n] = value #elif name.lower().startswith('title'): # num = name[4:] # try: # n = int(num) # except: # pass # else: # titles["%05d" % n] = value else: logging.debug( "PLAYLIST: skip this line from pls playlist: %s",line) ret = [] for k in sorted(songs.keys()): # ret.append( (songs[k], titles.get(k, None) ) ) ret.append(songs[k]) return ret def parse_xspf2(data): handler = XSPFParser2() parser = make_parser() parser.setContentHandler(handler) parser.feed(data) return handler class XSPFParser2(handler.ContentHandler): def __init__(s): s.path = u"" s.tracks = [] s.current=None s.position=None s.extensionapplication=None def parseFile(s, fileName): try: parser = make_parser() parser.setContentHandler(s) parser.parse(fileName) return True except SAXParseException: return False def startElement(s, name, attrs): s.path += "/%s" % name s.content = "" if s.path == "/playlist/trackList/track": s.track = {} elif s.path == "/playlist/extension": #if name == 'extension': s.extensionapplication= attrs.get('application',None) def characters(s, content): s.content += content def endElement(s, name): if s.path == "/playlist/title": s.title = s.content elif s.path == "/playlist/extension/current": if s.extensionapplication == "autoplayer": s.current = str(s.content) elif s.path == "/playlist/extension/position": if s.extensionapplication == "autoplayer": s.position = int(s.content) elif s.path == "/playlist/trackList/track/location": # mmmm this is for audacious but I think is wrong ##s.track['location'] = urllib.unquote(s.content) #s.track['location'] = urllib.unquote(s.content.encode("UTF-8")) url=urllib.parse.urlsplit(s.content) if (url.scheme == "http"): s.track['location']=url.geturl() else: s.track['location']=urllib.parse.urljoin(u"file://",urllib.parse.unquote(url.path)) elif s.path == "/playlist/trackList/track/title": s.track['title'] = s.content elif s.path == "/playlist/trackList/track/creator": s.track['creator'] = s.content elif s.path == "/playlist/trackList/track/album": s.track['album'] = s.content elif s.path == "/playlist/trackList/track/extension/id": s.track['id'] = s.content elif s.path == "/playlist/trackList/track": if s.track.get('location'): s.tracks.append(s.track) del s.track s.path = s.path.rsplit("/", 1)[0] class Playlist(list): def __init__(self,media=None,tracks=None,current=None,position=None): super( Playlist, self ).__init__([]) self.current=current self.position=position if media is not None: for ele in media: if ele.lower().endswith(".xspf") or \ ele.lower().endswith(".m3u") or \ ele.lower().endswith(".pls") : self.read(ele) else: track_meta=Track(ele,None,None,None,None,None) #print track_meta.get_metadata().values() tr=Track._make(list(track_meta.get_metadata().values())) self.append(tr) if tracks is not None: for ele in tracks: self.append(ele) def read(s, path): try: with open(urllib.parse.urlsplit(path).path, "r") as f: data = f.read() except IOError : logging.warning( "PLAYLIST: error opening file %s" % path) return if data.strip() == "": #empty logging.info( "PLAYLIST: empty") return logging.debug( "PLAYLIST: parse") parser = make_parser () try: parser.feed(data) except: li = data.split('\n') lin = map(lambda line: line.strip().rstrip(), li) lines=[] for line in filter(lambda line: line if line != "" and line[0] != '#' else None, lin): lines.append(line) if lines == []: return #detect type of playlist if '[playlist]' in lines: logging.debug( "PLAYLIST: is PLS") lines = parse_pls(lines) for location in lines: url=urllib.parse.urlsplit(location) # mmmmmm encode / decode every time do not work ! #location=urlparse.urljoin("file://",urllib.unquote(url.path.encode("UTF-8"))) if (url.scheme == "http"): location=url.geturl() else: location=urllib.parse.urljoin(u"file://",urllib.parse.unquote(url.path)) track=Track._make(list(Track(location,None,None,None,None,None).get_metadata().values())) s.append(track) else: logging.debug( "PLAYLIST: is XML") p = parse_xspf2(data) logging.debug( "PLAYLIST: xspf parsed") for ele in p.tracks: track=Track._make(list(Track(ele.get('location',None),ele.get('time',None),ele.get('creator',None), ele.get('album',None),ele.get('title',None),ele.get('id',None)).get_metadata().values())) s.append(track) #TODO read from file !!!! #s.current=s[2][5] #s.position=0 s.current=p.current s.position=p.position #s.current="1" #s.position=180000000000 logging.info ( "read from xspf current: %s" % s.current) logging.info ( "read from xspf position: %s" % s.position) def write(s,path): doc = Document() xspf_vlc_compatibility=False xspf_audacious_compatibility=False xspf_qmmp_compatibility=False with open(path, "w") as f: #head f.write('\n') if xspf_vlc_compatibility: f.write('\n' % VLC_NS) else: f.write('\n') logging.info ( "writing to xspf current: %s" % s.current) logging.info ( "writing to xspf position: %s" % s.position) if s.current is not None or s.position is not None: f.write('\t\n') if s.current is not None : k="current" t="int" v = doc.createTextNode(str(s.current)).toxml() f.write(u"\t\t<%s type='%s'>%s\n" % (k, t, v, k)) if s.position is not None: k="position" t="int" v = doc.createTextNode(str(s.position)).toxml() f.write(u"\t\t<%s type='%s'>%s\n" % (k, t, v, k)) f.write('\t\n') f.write('\n') for track in s: track=track._asdict() f.write('\t\n') if track.get('title') not in ['', None]: f.write( '\t\t%s\n' \ % doc.createTextNode(track['title']).toxml() ) if track.get('artist') not in ['', None]: f.write('\t\t%s\n' \ % doc.createTextNode(track['artist']).toxml() ) if track.get('album') not in ['', None]: f.write( '\t\t%s\n' \ % doc.createTextNode(track['album']).toxml() ) if track.get('tracknum') not in ['', None]: if type(track['tracknum']) == int: no = track['tracknum'] elif type(track['tracknum']) in [str, str]: cnum=track['tracknum'].split("/")[0].lstrip('0') if cnum != "": no = int( track['tracknum'].split("/")[0].lstrip('0') ) else: no=0 else: no = 0 if no > 0: f.write( '\t\t%i\n' % no ) #if float are seconds; if integer nanosec # out should be millisec if type(track.get('time')) == float: tm = track['time']*1000000 elif type(track.get('time')) == int: tm = track['time']/1000000. else: tm= None if tm is not None: tm = int(round(tm)) f.write('\t\t%i\n' % tm ) #write location #make valid quoted location location = track['path'] url=urllib.parse.urlsplit(location) if (url.scheme == "http"): location=url.geturl() else: #here problem when file name come from gtk or command line try: location=urllib.parse.urljoin(u"file://",urllib.parse.quote(url.path)) except: raise ##location = location.encode("utf-8") #if not 'http://' in location.lower() and \ # not 'file://' in location.lower(): # location = 'file://' + location #location = urllib.quote( location ) #write the location f.write( '\t\t%s\n' \ % doc.createTextNode(location).toxml() ) #write other info: keys = set(track.keys()) keys.discard('title') keys.discard('artist') keys.discard('album') keys.discard('tracknum') keys.discard('time') keys.discard('path') if len(keys) > 0: f.write('\t\t\n') for k in sorted(keys): if track[k] != None: v = track[k] t = type(v) if t in [str, str]: t = "str" v = str(v) elif t == bool: t = "bool" v = '1' if v else '0' elif t in [int, int]: t = "int" v = str(v) elif t == float: t = "float" v = repr(v) else: continue v = doc.createTextNode(v).toxml() f.write(u"\t\t\t<%s type='%s'>%s\n" % (k, t, v, k)) f.write('\t\t\n') f.write('\t\n') #tail f.write('\n') f.write('\n') class Playlist_mpris2(collections.OrderedDict): def __init__(self,playlist=Playlist([]),current=None,position=None): super( Playlist_mpris2, self ).__init__(collections.OrderedDict()) remakeid=False for track in playlist: if (track.id is None): remakeid=True break for id,track in enumerate(playlist): if (remakeid): self[str(id)]=Track._make((track.path,track.time,track.artist,track.album,track.title,str(id))) else: self[track.id]=track if current is None: if playlist.current is None: if len (self) == 0 : self.current = None else: self.current = list(self.keys())[0] else: self.current=playlist.current else: self.current=current if position is None: self.position=playlist.position else: self.position=position def get_current(self): if self.current is not None: return self[self.current] else: return Track(None,None,None,None,None,None) def set_current(self,id): if id in list(self.keys()): self.current=id else: logging.warning ("set_current: invalid id") def __next__(self): self.current = self.nextid(self.current) logging.info ( "current: %s" % self.current) def nextid(self,id): if id is None: return None keys=list(self.keys()) ind = keys.index(id) if len(keys)-1 <= ind : return None ind += 1 return keys[ind] def previous(self): self.current = self.previousid(self.current) logging.info ( "current: %s" % self.current) def previousid(self,id): if id is None: return None keys=list(self.keys()) ind = keys.index(id) if ind == 0 : return None ind -= 1 return keys[ind] def addtrack(self,uri,aftertrack=None,setascurrent=False): keys=list(self.keys()) if aftertrack is None: ind = max(len(keys)-1,0) else: try: ind = keys.index(aftertrack) except: logging.warning ("invalid aftertrack in addtrack") ind = max(len(keys)-1,0) # found id as index of position after we have to insert if len(keys) > 0: startnewid=max([int(x) for x in keys]) + 1 newself=Playlist_mpris2() aftertrack=keys[ind] else: return Playlist_mpris2(Playlist([uri])) # here we have empty new list were copy old and new for id,track in self.items(): newself[id]=track if id == aftertrack: p=Playlist([uri]) for id,track in enumerate(p,startnewid): newself[str(id)]=Track._make((track.path,track.time,track.artist,track.album,track.title,str(id))) # newself[str(newid)]=Track._make(track.get_metadata().values()) newself.current=self.current if setascurrent: if len(newself) >=0: newself.current=str(startnewid) return newself def removetrack(self,trackid): newself=self if trackid == newself.current: #newself.previous() newself.current=None newself.pop(trackid,None) return newself def write(self,path): Playlist(tracks=list(self.values()),current=self.current,position=self.position).write(path) def main(): import logging logging.basicConfig(level=logging.DEBUG,) media=( u"file:///home/pat1/Musica/Paolo Benvegnù/Piccoli fragilissimi film/3 - Io e te.flac", u"file:///home/pat1/Musica/Paolo Benvegnù/Piccoli fragilissimi film/5 - Fiamme.flac", u"file:///home/pat1/Musica/Paolo Benvegnù/Piccoli fragilissimi film/9 - Only for You.flac", ) uri=u"file:///home/pat1/Musica/Paolo Benvegnù/Piccoli fragilissimi film/2 - Cerchi nell'acqua.flac" print("-------------- playlist ------------------") p=Playlist(media) print("--------- playlist ord dict -----------------------") op=Playlist_mpris2(p) op.write("/tmp/tmp.xspf") print("--------- playlist from file -----------------------") p=Playlist(["/tmp/tmp.xspf"]) print("--------- playlist from file ord dict -----------------------") op=Playlist_mpris2(p) op=op.addtrack(uri,aftertrack="1") op=op.addtrack(uri,aftertrack="1",setascurrent=True) print(op) op.write("/tmp/tmpout.xspf") print("--------- reread playlist from file ord dict -----------------------") p=Playlist(["/tmp/tmpout.xspf"]) op=Playlist_mpris2(p) print("remove ",op.current) op=op.removetrack("0") print(op) op.write("/tmp/tmpout2.xspf") if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autoradio_config.py000066400000000000000000000054501454362722700233740ustar00rootroot00000000000000#!/usr/bin/python # GPL. (C) 2007-2009 Paolo Patruno. import os from configobj import ConfigObj,flatten_errors from validate import Validator configspec={} configspec['autoradiod']={} configspec['autoradiod']['player'] = "string(default='xmms')" configspec['autoradiod']['playlistdir'] = "string(default='spots')" configspec['autoradiod']['logfile'] = "string(default='/tmp/autoradiod.log')" configspec['autoradiod']['errfile'] = "string(default='/tmp/autoradiod.err')" configspec['autoradiod']['lockfile'] = "string(default='/tmp/autoradiod.lock')" configspec['autoradiod']['timestampfile'] = "string(default='/tmp/autoradiod.timestamp')" configspec['autoradiod']['xmms_host'] = "string(default='localhost')" configspec['autoradiod']['minelab'] = "integer(60,360,default=180)" configspec['autoradiod']['minsched'] = "integer(3,20,default=5)" configspec['autoradiod']['locale'] = "string(default='it_IT.UTF-8')" configspec['autoradiod']['user'] = "string(default=None)" configspec['autoradiod']['group'] = "string(default=None)" configspec['autoradiod']['env']={} #configspec['autoradiod']['env']['display'] = "string(default=':0.0')" config = ConfigObj ('/etc/autoradio/autoradio-site.cfg',file_error=False,configspec=configspec,interpolation="Template") usrconfig = ConfigObj (os.path.expanduser('~/.autoradio.cfg'),file_error=False,interpolation="Template") config.merge(usrconfig) usrconfig = ConfigObj ('autoradio.cfg',file_error=False,interpolation="Template") config.merge(usrconfig) val = Validator() test = config.validate(val,preserve_errors=True) for entry in flatten_errors(config, test): # each entry is a tuple section_list, key, error = entry if key is not None: section_list.append(key) else: section_list.append('[missing section]') section_string = ', '.join(section_list) if error == False: error = 'Missing value or section.' print(section_string, ' = ', error) raise error # section autoradiod # to use the amarok player (obsolete) #player="amarok" #this work on old systems #player="xmms" #on last distributions #player="audacious" player = config['autoradiod']['player'] playlistdir = config['autoradiod']['playlistdir'] logfile = config['autoradiod']['logfile'] errfile = config['autoradiod']['errfile'] lockfile = config['autoradiod']['lockfile'] timestampfile = config['autoradiod']['timestampfile'] XMMSHOST = config['autoradiod']['xmms_host'] minelab = config['autoradiod']['minelab'] minsched = config['autoradiod']['minsched'] user = config['autoradiod']['user'] group = config['autoradiod']['group'] env = config['autoradiod']['env'] import locale locale.setlocale(locale.LC_ALL, config['autoradiod']['locale']) autoradio-autoradio-3.6-4/autoradio/autoradio_core.py000066400000000000000000000601551454362722700230620ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # GPL. (C) 2007-2009 Paolo Patruno. from .autoradio_config import * from .gest_program import * from .gest_spot import * from .gest_jingle import * from .gest_playlist import * from .gest_palimpsest import * class schedule: """ Single schedule object attributes: djobj : dajngo retrive object scheduledatetime : datetime of schedule media : url of media filename : path of media length=None : time length in seconds type=None : "spot"/""playlist"/"jingle"/"programma" emission_done=None shuffle=False title=None): """ def __init__ (self,djobj,scheduledatetime,media,filename,length=None,type=None,emission_done=None,\ shuffle=False,maxlength=None,title=None): """ init of schedule object: """ self.mydjobj=djobj self.scheduledatetime=scheduledatetime self.mymedia=media self.filename=filename #self.mediaweb = self.media[len(settings.MEDIA_URL)+1:] self.length=length self.type=type self.emission_done=emission_done self.shuffle=shuffle self.maxlength=maxlength self.mytitle=title def __eq__(self, other): if (self.scheduledatetime is None and other.scheduledatetime is None or self.scheduledatetime == other.scheduledatetime) : return True def __ne__(self, other): return not self.__eq__(self, other) def __lt__(self, other): return self.scheduledatetime < other.scheduledatetime def __le__(self, other): return self.scheduledatetime <= other.scheduledatetime def __gt__(self, other): return self.scheduledatetime > other.scheduledatetime def __ge__(self, other): return self.scheduledatetime >= other.scheduledatetime def future (self,now=None): return self.scheduledatetime > now def filter (self): if self.scheduledatetime is None : return False return True def __repr__ (self): return self.type+" "+self.mymedia # def __iter__(self,now=None): # self.index=0 # self.now=now # if self.now is None : self.now=datetime.now() # return self # # def __next__(self): # self.index+=1 # if (self.index==1): # return self.mydjobj # if (self.index==2): # return self.mytitle # if (self.index==3): # return self.scheduledatetime # if (self.index==4): # return self.mymedia # if (self.index==5): # return str((datetime(2000,1,1)+timedelta(seconds=int(self.length))).time()) # if (self.index==6): # return self.type # if (self.index==7): # return self.emission_done # if (self.index==8): # return self.future(self.now) # raise StopIteration def get_djobj(self): return self.mydjobj def get_title(self): return self.mytitle def get_datet(self): return self.scheduledatetime def get_media(self): return self.mymedia def get_length_s(self): return str((datetime(2000,1,1)+timedelta(seconds=int(self.length))).time()) def get_tipo(self): return self.type def get_datetdone(self): return self.emission_done def get_isfuture(self): return self.future(datetime.now()) djobj=property(get_djobj) title=property(get_title) datet=property(get_datet) media=property(get_media) length_s=property(get_length_s) tipo=property(get_tipo) datetdone=property(get_datetdone) isfuture=property(get_isfuture) class schedules(list): """ multiple schedule object """ def __init__(self, *args, **kwargs): super(schedules, self).__init__(*args, **kwargs) self.districatimes=0 def districa(self): ''' english: try to extricate from an schedules ensemble the more easy operation is to delete jingles inside programs and spots italiano: cerca di districarsi tra un insieme di schedule la prima operazione da fare e' togliere i jingle che coincidono con programmi e pubblicita' return True if need other call to self to manage new modification ''' logging.debug("execute districa") needrecompute=False recomputedtimes=0 self.districatimes += 0 #Spots #v=0 for v,schedulej in enumerate(self): # add the default adjustedlength !!! Attention schedulej.adjustedlength= schedulej.length scheduledatetimej=schedulej.scheduledatetime if ( scheduledatetimej == None ): continue lengthj=schedulej.length typej=schedulej.type endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) #print "elaborate ",typej,scheduledatetimej,endscheduledatetimej if (typej == "spot"): for schedule in self: scheduledatetime=schedule.scheduledatetime if ( scheduledatetime== None ): continue length=schedule.length type=schedule.type endscheduledatetime=scheduledatetime+timedelta(seconds=length) halfscheduledatetime=scheduledatetime+timedelta(seconds=int(length/2)) if (type == "spot" or type == "playlist" or type == "jingle" ): continue # here we have spot versus programs #starting in the firth half of program if ( scheduledatetime < scheduledatetimej and scheduledatetimej < halfscheduledatetime ): logging.debug( "anticipate this spot overlapped start time in the firth half %s", str(self[v])) ##we have to anticipate a epsilon to be shure to go before #self[v].scheduledatetime=scheduledatetime-timedelta(seconds=30) #we have to anticipate start program - spot length self[v].scheduledatetime=scheduledatetime-timedelta(seconds=lengthj) #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) #ending in the firth half of program if ( endscheduledatetimej > scheduledatetime and endscheduledatetimej < halfscheduledatetime ): logging.debug( "anticipate this spot overlapped end time in the firth half %s", str(self[v])) #we have to anticipate start program - spot length self[v].scheduledatetime=scheduledatetime-timedelta(seconds=lengthj) #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) #start in the second half of program if ( scheduledatetimej >= halfscheduledatetime and scheduledatetimej < endscheduledatetime ): logging.debug( "postpone this spot overlapped in the second half %s", str(self[v])) #we have to postpone start program - spot length self[v].scheduledatetime=endscheduledatetime #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) # this case is not so simple # after moving spots we have spots overlapped # this is possible when we have programs without time interval for spots like more enclosure in one episode # here is more simple to simulate one enclosure more long to include spots length # recompute programs length overlapped with spots if ( scheduledatetime < scheduledatetimej and scheduledatetimej < endscheduledatetime ): logging.debug( "adding time to program; this spot overlapped %s", str(self[v])) schedule.adjustedlength=schedule.length+lengthj needrecompute=True #v += 1 #now we can have programs overlapped bt programs for v,schedulej in enumerate(self): scheduledatetimej=schedulej.scheduledatetime if ( scheduledatetimej == None ): continue lengthj=schedulej.adjustedlength typej=schedulej.type endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) #print "elaborate ",typej,scheduledatetimej,endscheduledatetimej if (typej == "program"): for vv,schedule in enumerate(self): #do not compare with itself if schedule == schedulej and str(schedule) == str(schedulej): continue scheduledatetime=schedule.scheduledatetime if ( scheduledatetime== None ): continue length=schedule.adjustedlength type=schedule.type endscheduledatetime=scheduledatetime+timedelta(seconds=length) halfscheduledatetime=scheduledatetime+timedelta(seconds=int(length/2)) if (type == "spot" or type == "playlist" or type == "jingle" ): continue # here we have program versus programs #starting in the firth half of program if ( scheduledatetime <= scheduledatetimej and scheduledatetimej < halfscheduledatetime ): logging.debug( "postpone this program overlapped start time in the firth half") logging.debug( "postpone %s, over %s", str(self[v]),str(self[vv])) #we have to postpone start program - spot length self[v].scheduledatetime=endscheduledatetime #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) needrecompute=True #ending in the firth half of program if ( endscheduledatetimej > scheduledatetime and endscheduledatetimej < halfscheduledatetime ): logging.debug( "anticipate this program overlapped end time in the firth half") logging.debug( "anticipate %s, over %s", str(self[v]),str(self[vv])) #we have to anticipate start program - spot length self[v].scheduledatetime=scheduledatetime-timedelta(seconds=lengthj) #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) needrecompute=True #start in the second half of program if ( scheduledatetimej >= halfscheduledatetime and scheduledatetimej < endscheduledatetime ): logging.debug( "postpone this program overlapped in the second half") logging.debug( "postpone %s, over %s", str(self[v]),str(self[vv])) #we have to postpone self[v].scheduledatetime=endscheduledatetime #recompute scheduledatetimej=self[v].scheduledatetime endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) needrecompute=True #Jingles # remove jingles overlapped with programs and spots #v=0 for v,schedulej in enumerate(self): scheduledatetimej=schedulej.scheduledatetime if ( scheduledatetimej == None ): continue lengthj=schedulej.length typej=schedulej.type endscheduledatetimej=scheduledatetimej+timedelta(seconds=lengthj) #print "elaboro ",typej,scheduledatetimej,endscheduledatetimej if (typej == "jingle"): for schedule in self: scheduledatetime=schedule.scheduledatetime if ( scheduledatetime== None ): continue length=schedule.length type=schedule.type endscheduledatetime=scheduledatetime+timedelta(seconds=length) if (type == "jingle" or type == "playlist"): continue # here we have jingle versus programs and spot if (( scheduledatetime < scheduledatetimej and scheduledatetimej < endscheduledatetime )\ or \ ( scheduledatetime < endscheduledatetimej and endscheduledatetimej < endscheduledatetime )): logging.debug( "remove this jingle overlapped %s", str(self[v])) self[v].scheduledatetime=None #v += 1 return needrecompute def purge(self): reverse_enumerate = lambda l: zip(range(len(l)-1, -1, -1), reversed(l)) for ind,schedula in reverse_enumerate(self): if not schedula.filter(): logging.debug( "purge %s", str(schedula)) del self[ind] def get_all(self,now=None,genfile=True): # time constants #this is the first and last time that I set the current time if now is None : now=datetime.now() spots=gest_spot(now,minelab,playlistdir) for fascia in spots.get_fasce(genfile): media = spots.ar_url filename = spots.ar_filename scheduledatetime=spots.ar_scheduledatetime length=spots.ar_length emission_done=spots.ar_emission_done number=spots.ar_spots_in_fascia #print scheduledatetime,media,length,number,emission_done if (number != 0 ): self.append(schedule(fascia,scheduledatetime,media,filename,length,"spot",emission_done,title=str(fascia))) programs=gest_program(now,minelab) for programma in programs.get_program(): media = programma.ar_url filename = programma.ar_filename scheduledatetime=programma.ar_scheduledatetime length=programma.ar_length emission_done=programma.ar_emission_done title=programma.ar_title #print scheduledatetime,media,length,emission_done self.append(schedule(programma,scheduledatetime,media,filename,length,"program",\ emission_done,title=title)) playlists=gest_playlist(now,minelab) for playlist in playlists.get_playlist(): media = playlist.ar_url filename = playlist.ar_filename scheduledatetime=playlist.ar_scheduledatetime length=playlist.ar_length maxlength=playlist.length emission_done=playlist.ar_emission_done shuffle=playlist.ar_shuffle #print scheduledatetime,media,length,emission_done self.append(schedule(playlist,scheduledatetime,media,filename,length,"playlist",\ emission_done,shuffle,maxlength,title=str(playlist))) jingles=gest_jingle(now,minelab) for jingle in jingles.get_jingle(): media = jingle.ar_url filename = jingle.ar_filename scheduledatetime=jingle.ar_scheduledatetime length=jingle.ar_length emission_done=jingle.ar_emission_done #print scheduledatetime,media,length,emission_done self.append(schedule(jingle,scheduledatetime,media,filename,length,"jingle",\ emission_done,title=str(jingle))) #return self def get_all_refine(self,now=None,genfile=True): self.get_all(now,genfile) while self.districa(): if (self.districatimes >= 20 ): logging.error("districa do not converge: too many programs in few time") break self.purge() self.sort() #return self class palimpsest(object): def __init__ (self,title=None,datetime_start=None,datetime_end=None, code=None,type=None,subtype=None,production=None,note=None): """ init of palimpsest object """ self.title=title self.datetime_start=datetime_start self.datetime_end=datetime_end self.code=code self.type=type self.subtype=subtype self.production=production self.note=note def __cmp__ (self, b): #check start datetime if self.datetime_start is None and b.datetime_start is None : return 0 if self.datetime_start is None : return -1 if b.datetime_start is None : return 1 if self.datetime_start == b.datetime_start : #check end datetime if self.datetime_end is None and b.datetime_end is None : return 0 if self.datetime_end is None : return -1 if b.datetime_end is None : return 1 if self.datetime_end == b.datetime_end : return 0 elif self.datetime_end < b.datetime_end : return -1 elif self.datetime_end > b.datetime_end : return 1 elif self.datetime_start < b.datetime_start : return -1 elif self.datetime_start > b.datetime_start : return 1 def __str__ (self): return self.title+" "+str(self.datetime_start)+" "+\ str(self.datetime_end)+" "+str(self.type)+" "+\ str(self.subtype)+" "+str(self.production)+" "+str(self.note) def __iter__(self): ''' return a list ''' self.index=0 return self def __next__(self): self.index+=1 if (self.index==1): return self.title if (self.index==2): return self.datetime_start if (self.index==3): return self.datetime_end if (self.index==4): return self.code if (self.index==5): return self.type if (self.index==6): return self.subtype if (self.index==7): return self.production if (self.index==8): return self.note raise StopIteration class dates(object): def __init__(self,datetime_start, datetime_end,step): self.step=step self.datetime_start=datetime_start-self.step self.datetime_end=datetime_end def __iter__(self): return self def __next__(self): self.datetime_start=self.datetime_start+self.step if self.datetime_start <= self.datetime_end: return self.datetime_start else: raise StopIteration #return class palimpsests(list): def get_palimpsest(self,datetime_start,datetime_end): step=timedelta(minutes=minelab*2) for datetimeelab in dates(datetime_start, datetime_end, step): pro=gest_palimpsest(datetimeelab,minelab) for program in pro.get_program(): length=program.show.length if length is None: logging.warning("get_palimpsest: %s legth is None; setting default to 3600 sec",str(program)) length = 3600 pdatetime_start=program.ar_scheduledatetime title=str(program) pdatetime_end=program.ar_scheduledatetime+timedelta(seconds=length) code=program.show.type.code type=program.show.type.type subtype=program.show.type.subtype production=program.show.production note="" if pdatetime_start >= datetime_start and pdatetime_end < datetime_end : self.append(palimpsest(title,pdatetime_start,pdatetime_end, code,type,subtype,production,note)) self.sort() #print ("prima:") #for program in self: # print (program) # timing adjust: # 1) overlay # 2) insert music no stop for interval >15 minutes musicanostop=palimpsests([]) for i in range(len(self)-1): if self[i].datetime_end > self[i+1].datetime_start: self[i].datetime_end=self[i+1].datetime_start elif self[i].datetime_end < self[i+1].datetime_start-timedelta(minutes=15): musicanostop.append(palimpsest("Musica no stop",self[i].datetime_end, self[i+1].datetime_start,code="13f", type="13",subtype="13f",production="autoproduzione",note=None)) for element in musicanostop: self.append(element) self.sort() for i in range(len(self)-1): # 3) chain little interval if self[i].datetime_end != self[i+1].datetime_start: dtmean=self[i].datetime_end+(int((self[i+1].datetime_start-self[i].datetime_end)/2)) self[i].datetime_end=dtmean self[i+1].datetime_start=dtmean # add head and tail: # chain little interval if len(self) > 0 : if self[0].datetime_start != datetime_start : self.insert(0,palimpsest("Musica no stop",datetime_start, self[0].datetime_start,code="13f", type="13",subtype="13f",production="autoproduzione",note=None)) if self[len(self)-1].datetime_end != datetime_end : self.append(palimpsest("Musica no stop",self[len(self)-1].datetime_end, datetime_end,code="13f", type="13",subtype="13f",production="autoproduzione",note=None)) #print "dopo:" #for program in self: # print program # Spots for datetimeelab in dates(datetime_start, datetime_end, step): #print datetimeelab,minelab spots=gest_spot(datetimeelab,minelab,playlistdir) for fascia in spots.get_fasce(genfile=False): length=spots.ar_length #pdatetime_start=spots.ar_emission_done pdatetime_start=spots.ar_scheduledatetime number=spots.ar_spots_in_fascia #title=str(fascia) title="Pubblicità" pdatetime_end=pdatetime_start+timedelta(seconds=length) type="5" subtype="5a" production="" note="%d Spot" % number #if (number <> 0 and pdatetime_start.date() == dateelab): if number != 0 and pdatetime_start >= datetime_start and pdatetime_end < datetime_end : self.append(palimpsest(title,pdatetime_start,pdatetime_end, type,subtype,production,note)) self.sort() return self def main(): logging.basicConfig(level=logging.INFO,) # pali=palimpsests([]) # print "------- palimpsest --------" # for prog in pali.get_palimpsest(datetime.now()-timedelta(days=1),datetime.now()): # print "------- program --------" # # print prog # # #for elemento in prog: # # print elemento scheds=schedules([]) # get the schedule of my insterest # I do a list print("------- schedules --------") for sched in scheds.get_all_refine(): print("------- schedule --------") for elemento in sched: print(elemento) print(sched.type) print(sched.media) print(sched.scheduledatetime) print(sched.shuffle) print(sched.length) if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/autoxmms.py000066400000000000000000000102001454362722700217220ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. import xmms import time import datetime import os def play_ifnot(session=0): ''' start playng if not. ''' # I check if xmms is playng .... otherside I try to play # if xmms is in pause any check is impossible try: ok=xmms.control.is_playing(session) if (not ok): ok = xmms.control.play(session) except: return False def get_playlist_securepos(session=0,securesec=10): ''' Try to secure that there are some time (securesec) to complete all operations in time: if xmms change song during operation will be a big problem ''' try: play_ifnot(session=session) #force to play mintimed=datetime.timedelta(seconds=securesec) toend=datetime.timedelta(seconds=0) volte=0 while ( toend < mintimed ): # take the current position pos=xmms.control.get_playlist_pos(session) timed=datetime.timedelta(seconds=datetime.timedelta(milliseconds=xmms.control.get_playlist_time(pos, session)).seconds) toend=timed-datetime.timedelta(seconds=datetime.timedelta(milliseconds=xmms.control.get_output_time(session)).seconds) newpos=xmms.control.get_playlist_pos(session) if (pos != newpos): #inconsistenza: retry toend=datetime.timedelta(seconds=0) if ( toend < mintimed ): volte +=1 if volte > 10 : break # timeout , I have to play time.sleep(securesec+1) return pos except : return None def playlist_clear_up(atlast=10,session=0): ''' clear playlist starting from current position up. "atlast" numer of song are retained ''' try: play_ifnot(session=session) #force to play # take the current position (if error set pos=0) pos=get_playlist_securepos(session) if pos is None: return False # delete the old ones if pos > atlast : for prm in range(0,pos-atlast): xmms.control.playlist_delete(0,session) return True except: return False def playlist_clear_down(atlast=500,session=0): ''' clear playlist starting from current position + atlast doen. "atlast" numer of song are retained for future play ''' try: play_ifnot(session=session) #force to play # take the current position (if error set pos=0) pos=get_playlist_securepos(session) if pos is None: return False length=xmms.get_playlist_length(session) #elimino il troppo if length-pos > atlast : for prm in range(length,pos+atlast,-1): xmms.control.playlist_delete(prm,session) return True except: return False def get_playlist_posauto(autopath,session=0,securesec=10): ''' get playlist position skipping file with path equal to autopath. Try to secure that there are some time (securesec) to complete all operations in time: if xmms change song during operation will be a big problem ''' try: pos=get_playlist_securepos(session=session,securesec=securesec) if pos is None: return pos pos+=1 file=xmms.control.get_playlist_file(pos, session) if file is None : return pos filepath=os.path.dirname(file) # ora controllo se ci sono gia dei file accodati nella playlist da autoradio # l'unica possibilita di saperlo e verificare il path del file while ( os.path.commonprefix ((filepath,autopath)) == autopath ): pos+=1 file=xmms.control.get_playlist_file(pos, session) if file is None : return pos filepath=os.path.dirname(file) # here I have found the first file added by autoradio return pos except : return None #xmms.control.playlist_clear_up=playlist_clear_up #xmms.control.get_playlist_posauto=get_playlist_posauto #xmms.control.play_ifnot=play_ifnot autoradio-autoradio-3.6-4/autoradio/daemon.py000066400000000000000000000240351454362722700213230ustar00rootroot00000000000000# -*- coding: utf-8 -*- # modified by Paolo Patruno September 2009 ## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany ## Copyright 1999-2009 by Walter Dörwald ## ## All Rights Reserved ## ## Permission is hereby granted, free of charge, to any person obtaining a copy ## of this software and associated documentation files (the "Software"), to deal ## in the Software without restriction, including without limitation the rights ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ## copies of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## ## The above copyright notice and this permission notice shall be included in ## all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ## THE SOFTWARE. ## """ This module can be used on UNIX to fork a daemon process. It is based on `Jürgen Hermann's Cookbook recipe`__. __ http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 An example script might look like this:: from autoradio import daemon tmp = daemon.Daemon( stdin="/dev/null", stdout="/tmp/tmp.log", stderr="/tmp/tmp.err", pidfile="/tmp/tmp.lock", # user=user, # group=group, # env=env ) def main(self): import subprocess self.procs=[subprocess.Popen(["sleep","60"],cwd=self.cwd)] self.procs.append(subprocess.Popen(["sleep","130"],cwd=self.cwd)) if __name__ == '__main__': import sys, os tmp.cwd=os.getcwd() if tmp.service(): sys.stdout.write("Daemon started with pid %d\n" % os.getpid()) sys.stdout.write("Daemon stdout output\n") sys.stderr.write("Daemon stderr output\n") main(tmp) # (this code was run as script) for proc in tmp.procs: proc.wait() sys.exit(0) """ import sys, os, signal, pwd, grp, optparse __docformat__ = "reStructuredText" class Daemon(object): """ The :class:`Daemon` class provides methods for starting and stopping a daemon process as well as handling command line arguments. """ def __init__(self, stdin="/dev/null", stdout="/dev/null", stderr="/dev/null", pidfile=None, user=None, group=None,env=None): """ The :var:`stdin`, :var:`stdout`, and :var:`stderr` arguments are file names that will be opened and be used to replace the standard file descriptors in ``sys.stdin``, ``sys.stdout``, and ``sys.stderr``. These arguments are optional and default to ``"/dev/null"``. Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect. :var:`pidfile` must be the name of a file. :meth:`start` will write the pid of the newly forked daemon to this file. :meth:`stop` uses this file to kill the daemon. :var:`user` can be the name or uid of a user. :meth:`start` will switch to this user for running the service. If :var:`user` is :const:`None` no user switching will be done. In the same way :var:`group` can be the name or gid of a group. :meth:`start` will switch to this group. :env: {} set the ENVIROMENT variables """ options = dict( stdin=stdin, stdout=stdout, stderr=stderr, pidfile=pidfile, user=user, group=group ) self.env=env self.options = optparse.Values(options) self.procs=() self.cwd=os.getcwd() def openstreams(self): """ Open the standard file descriptors stdin, stdout and stderr as specified in the constructor. """ si = open(self.options.stdin, "r") so = open(self.options.stdout, "ab+") se = open(self.options.stderr, "ab+", 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) def handlesighup(self, signum, frame): """ Handle a ``SIG_HUP`` signal: Reopen standard file descriptors. """ import subprocess self.openstreams() for proc in self.procs: if (isinstance(proc,subprocess.Popen)): #proc.send_signal(signum) # work in py ver 2.6 os.kill(proc.pid,signum) if (isistance(proc,int)): os.kill(proc,signum) def handlesigterm(self, signum, frame): """ Handle a ``SIG_TERM`` signal: Remove the pid file and exit. """ import subprocess if self.options.pidfile is not None: try: os.remove(self.options.pidfile) except Exception: pass for proc in self.procs: if (isinstance(proc,subprocess.Popen)): #proc.send_signal(signum) # work in py ver 2.6 os.kill(proc.pid,signum) if (isinstance(proc,int)): os.kill(proc,signum) sys.exit(0) def switchuser(self, user, group, env): """ Switch the effective user and group. If :var:`user` and :var:`group` are both :const:`None` nothing will be done. :var:`user` and :var:`group` can be an :class:`int` (i.e. a user/group id) or :class:`str` (a user/group name). """ groups = [] if group is not None: if isinstance(group, list): for gr in group: if isinstance(gr, str): groups.append(grp.getgrnam(gr).gr_gid) group = group[0] if isinstance(group, str): group = grp.getgrnam(group).gr_gid try: os.setgroups(groups) except: pass os.setgid(group) os.setegid(group) if user is not None: if isinstance(user, str): user = pwd.getpwnam(user).pw_uid os.setuid(user) os.seteuid(user) # todo: check why home is set here #if not "HOME" in os.environ: os.environ["HOME"] = pwd.getpwuid(user).pw_dir if env is not None: for variable in env: os.environ[variable] = env[variable] if "HOME" in os.environ: self.cwd=os.environ["HOME"] try: os.chdir(self.cwd) except: pass def start(self): """ Daemonize the running script. When this method returns the process is completely decoupled from the parent environment. """ # Finish up with the current stdout/stderr sys.stdout.flush() sys.stderr.flush() # Do first fork try: pid = os.fork() if pid > 0: sys.exit(0) # Exit first parent except OSError as exc: sys.exit("%s: fork #1 failed: (%d) %s\n" % (sys.argv[0], exc.errno, exc.strerror)) # Decouple from parent environment os.chdir("/") os.umask(0) os.setsid() # Do second fork try: pid = os.fork() if pid > 0: sys.exit(0) # Exit second parent except OSError as exc: sys.exit("%s: fork #2 failed: (%d) %s\n" % (sys.argv[0], exc.errno, exc.strerror)) # Now I am a daemon! # Switch user self.switchuser(self.options.user, self.options.group, self.env) # Redirect standard file descriptors (will belong to the new user) self.openstreams() # Write pid file (will belong to the new user) if self.options.pidfile is not None: open(self.options.pidfile, "w").write(str(os.getpid())) # Reopen file descriptors on SIGHUP signal.signal(signal.SIGHUP, self.handlesighup) # Remove pid file and exit on SIGTERM signal.signal(signal.SIGTERM, self.handlesigterm) def stop(self): """ Send a ``SIGTERM`` signal to a running daemon. The pid of the daemon will be read from the pidfile specified in the constructor. """ if self.options.pidfile is None: sys.exit("no pidfile specified") try: pidfile = open(self.options.pidfile, "r") except IOError as exc: sys.exit("can't open pidfile %s: %s" % (self.options.pidfile, str(exc))) data = pidfile.read() try: pid = int(data) except ValueError: sys.exit("mangled pidfile %s: %r" % (self.options.pidfile, data)) os.kill(pid, signal.SIGTERM) def optionparser(self): """ Return an :mod:`optparse` parser for parsing the command line options. This can be overwritten in subclasses to add more options. """ from . import _version_ p = optparse.OptionParser(usage="usage: %prog [options] (action=start|stop|restart|run|version)", description="%prog daemon for autoradio suite",version="%prog "+_version_) p.add_option("--pidfile", dest="pidfile", help="PID filename (default %default)", default=self.options.pidfile) p.add_option("--stdin", dest="stdin", help="stdin filename (default %default)", default=self.options.stdin) p.add_option("--stdout", dest="stdout", help="stdout filename (default %default)", default=self.options.stdout) p.add_option("--stderr", dest="stderr", help="stderr filename (default %default)", default=self.options.stderr) p.add_option("--user", dest="user", help="user name or id (default %default)", default=self.options.user) p.add_option("--group", dest="group", help="group name or id (default %default)", default=self.options.group) return p def service(self, args=None,noptions=0): """ Handle command line arguments and start or stop the daemon accordingly. :var:`args` must be a list of command line arguments (including the program name in ``args[0]``). If :var:`args` is :const`None` or unspecified ``sys.argv`` is used. :var:`noptions` max number of options in command line or args The return value is true when a starting option has been specified as the command line argument, i.e. if the daemon should be started. The :mod:`optparse` options and arguments are available afterwards as ``self.options`` and ``self.args``. """ p = self.optionparser() if args is None: args = sys.argv (self.options, self.args) = p.parse_args(args) if len(self.args) == 1 or len(self.args) > noptions+2: p.error("incorrect number of arguments") sys.exit(1) if self.args[1] == "run": return True elif self.args[1] == "restart": try: self.stop() finally: self.start() return True elif self.args[1] == "start": self.start() return True elif self.args[1] == "stop": self.stop() return False else: p.error("incorrect argument %s" % self.args[1]) sys.exit(1) autoradio-autoradio-3.6-4/autoradio/dbusdecorator/000077500000000000000000000000001454362722700223425ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/dbusdecorator/__init__.py000066400000000000000000000005031454362722700244510ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .attribute import DbusAttr from .interface import DbusInterface from .method import DbusMethod from .signal import DbusSignal from .utils import get_mainloop, get_uri, implements, \ list_all_interface, list_interfaces, list_paths autoradio-autoradio-3.6-4/autoradio/dbusdecorator/__main__.py000066400000000000000000000003421454362722700244330ustar00rootroot00000000000000from . import DbusAttr from . import DbusInterface from . import DbusMethod from . import DbusSignal if __name__ == '__main__': print(DbusAttr()) print(DbusInterface()) print(DbusMethod()) print(DbusSignal()) autoradio-autoradio-3.6-4/autoradio/dbusdecorator/attribute.py000066400000000000000000000031041454362722700247150ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .base import Decorator, ATTR_KEY class DbusAttr(Decorator): ''' https://docs.python.org/2/howto/descriptor.html#properties ''' def __init__(self, meth=None, produces=lambda resp: resp): self.attr = meth self.produces = produces self._update_me(meth) def __call__(self, meth): self.attr = meth self._update_me(meth) return self def __get__(self, obj, objtype=None): #static call if not obj: return self _dbus = getattr(obj, ATTR_KEY) props = _dbus.properties iface = _dbus.iface result = props.Get(iface, self.attr.__name__) produces = self.produces return produces(result) def __set__(self, obj, value): if obj: _dbus = getattr(obj, ATTR_KEY) props = _dbus.properties iface = _dbus.iface props.Set(iface, self.attr.__name__, value) else: #static call self.attr = value def __delete__(self, obj): raise AttributeError('can not delete attribute') if __name__ == '__main__': # examples from .interface import DbusInterface @DbusInterface('org.mpris.MediaPlayer2', '/org/mpris/MediaPlayer2') class Example(object): @DbusAttr def Identity(self): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.mpris.MediaPlayer2.vlc'}) assert d.Identity == 'VLC media player' autoradio-autoradio-3.6-4/autoradio/dbusdecorator/base.py000066400000000000000000000010021454362722700236170ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' I_PROP = 'org.freedesktop.DBus.Properties' ARG_KEY = 'dbus_interface_info' ATTR_KEY = '_dbus_interface_info' class Decorator(object): def _update_me(self, target=None): if hasattr(target, "__doc__"): self.__doc__ = target.__doc__ if hasattr(target, "__name__"): self.__name__ = target.__name__ if hasattr(target, "__bases__"): self.__bases__ = target.__bases__ autoradio-autoradio-3.6-4/autoradio/dbusdecorator/interface.py000066400000000000000000000102141454362722700246520ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' import dbus from functools import wraps from .base import Decorator, ARG_KEY, I_PROP, ATTR_KEY class _DbusInfoProperty(object): def __init__(self, iface=None, path=None, uri=None, dbus_object=None, session=None, wrapped=None): self.iface = iface self.path = path self.uri = uri self.object = dbus_object self.session = session self.wrapped = wrapped self.interface = None self.properties = None if not self.object: bus = self.session = self.session or dbus.SessionBus() self.object = bus.get_object(self.uri, self.path) if not self.interface: self.interface = dbus.Interface(self.object, dbus_interface=self.iface) if not self.properties: self.properties = dbus.Interface(self.object, I_PROP) def reconnect(self, session=None): ''' Required if you need update session/proxy object/interfaces ''' session = session or self.session if session == self.session: self.session.close() session = self.session = dbus.SessionBus() self.object = session.get_object(self.uri, self.path) self.interface = dbus.Interface(self.object, dbus_interface=self.iface) self.properties = dbus.Interface(self.object, I_PROP) class DbusInterface(Decorator): def __init__(self, iface=None, path=None, uri=None, dbus_object=None, session=None): self.iface = iface self.path = path self.uri = uri self.object = dbus_object self.session = session self.wrapped = None def __call__(self, meth): ''' Called when any decorated class is loaded''' self.wrapped = meth self._update_me(meth) @wraps(meth) def dbusWrapedInterface(*args, **kw): _args = kw.get(ARG_KEY, {}) info_property = _DbusInfoProperty( iface=_args.get('dbus_iface', self.iface), path=_args.get('dbus_path', self.path), uri=_args.get('dbus_uri', self.uri), dbus_object =_args.get('dbus_object', self.object), session =_args.get('dbus_session', self.session), wrapped=self.wrapped ) if ARG_KEY in kw: del kw[ARG_KEY] return self.dbusWrapedInterface(info_property, *args, **kw) return dbusWrapedInterface def dbusWrapedInterface(self, info_property, *args, **kw): ''' Called when some decoreted class was called Inject attrs from decorator at new object then return object @param *args: list of args to call constructor @param **kw: dict of keywords, can redefine class default parameters @return: instance of decoreted class, with new attributes @see: mpris2.mediaplayer2 to see some examples ''' #call decorated class constructor new_obj = self.wrapped(*args, **kw) if new_obj: setattr(new_obj, ATTR_KEY, info_property) elif len(args) > 0: setattr(args[0], ATTR_KEY, info_property) return new_obj if __name__ == '__main__': # examples @DbusInterface('org.freedesktop.DBus', '/') class Example(object): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert d._dbus_interface_info.iface == 'org.freedesktop.DBus' assert d._dbus_interface_info.path == '/' assert d._dbus_interface_info.uri == 'org.freedesktop.DBus' class ExempleToo(object): @DbusInterface('org.freedesktop.DBus', '/') def __init__(self): pass dd = ExempleToo( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert dd._dbus_interface_info.iface == 'org.freedesktop.DBus' assert dd._dbus_interface_info.path == '/' assert dd._dbus_interface_info.uri == 'org.freedesktop.DBus' autoradio-autoradio-3.6-4/autoradio/dbusdecorator/method.py000066400000000000000000000063751454362722700242070ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .base import Decorator, ATTR_KEY def kw_to_dbus(**kw): return kw def args_to_dbus(*args): return args class DbusMethod(Decorator): def __init__(self, meth=None, iface=None, produces=lambda resp: resp, args_to_dbus=args_to_dbus, kw_to_dbus=kw_to_dbus, std_args=(), std_kwds={}): self.meth = meth self.handler = None self.produces = produces self.iface = iface self.args_to_dbus = args_to_dbus self.kw_to_dbus = kw_to_dbus self.std_args = std_args self.std_kwds = std_kwds self.obj = None self._update_me(meth) def __call__(self, meth=None): self.meth = meth self._update_me(meth) return self def __get__(self, obj=None, cls=None): if obj is None: return self self.obj = obj return self._call_dbus def _call_dbus(self, *args, **kwds): _dbus = getattr(self.obj, ATTR_KEY) if self.iface: iface = self.iface else: iface = _dbus.iface bus_obj = _dbus.object bus_meth = bus_obj.get_dbus_method(self.meth.__name__, iface) _args = self.merge_args(args, self.std_args) args = self.convert_args_to_dbus_args(*_args) _kwds = self.std_kwds.copy() _kwds.update(kwds) kwds = self.convert_kw_to_dbus_kw(**_kwds) result = bus_meth(*args, **kwds) return self.produces(result) @classmethod def merge_args(cls, args, std_args): _len = len(std_args) - len(args) return args + std_args[-_len:] if _len > 0 else args @classmethod def merge_kwds(cls, kwds, std_kwds): _kwds = std_kwds.copy() _kwds.update(kwds) return _kwds def convert_args_to_dbus_args(self, *args): args_to_dbus = self.args_to_dbus if callable(args_to_dbus): return args_to_dbus(*args) #iterate over args result = [] for arg in args: i = args.index(arg) if i < len(args_to_dbus): make = args_to_dbus[i] if callable(make): arg = make(arg) result.append(arg) return tuple(result) def convert_kw_to_dbus_kw(self, **kw): kw_to_dbus = self.kw_to_dbus if callable(kw_to_dbus): return kw_to_dbus(**kw) if hasattr(self.kw_to_dbus, 'keys'): for key, val in kw.items(): make = kw_to_dbus.get(key, lambda v: v) kw[key] = make(val) return kw if __name__ == '__main__': # examples from .interface import DbusInterface @DbusInterface('org.freedesktop.DBus', '/') class Example(object): @DbusMethod def GetId(self): pass @DbusMethod def GetNameOwner(self, name): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert d.GetId() assert d.GetNameOwner('org.freedesktop.DBus') == 'org.freedesktop.DBus' autoradio-autoradio-3.6-4/autoradio/dbusdecorator/signal.py000066400000000000000000000032621454362722700241740ustar00rootroot00000000000000from .base import Decorator, ATTR_KEY class DbusSignal(Decorator): ''' https://docs.python.org/2/howto/descriptor.html#properties ''' def __init__(self, meth=None, iface=None): self.attr = meth self.handler = None self.iface = iface self._update_me(meth) def __call__(self, meth): self.attr = meth self._update_me(meth) return self def __get__(self, obj, objtype=None): if obj: return self.handler #static call return self def __set__(self, obj, value): if obj: _dbus = getattr(obj, ATTR_KEY) interface = _dbus.interface def handle(*args, **kwds): h = self.handler h and h(*args, **kwds) if not self.handler: interface.connect_to_signal(self.attr.__name__, handle, dbus_interface=self.iface) self.handler = value else: #static call self.attr = value def __delete__(self, obj): self.handler = None if __name__ == '__main__': from .interface import DbusInterface from .utils import get_mainloop mainloop = get_mainloop() print('mainloop', mainloop) @DbusInterface('org.mpris.MediaPlayer2.player', '/org/mpris/MediaPlayer2') class Example(object): @DbusSignal def Seeked(self): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.mpris.MediaPlayer2.gmusicbrowser'}) def handler(self, *args): print(args) d.Seeked = handler mainloop and mainloop.run() autoradio-autoradio-3.6-4/autoradio/dbusdecorator/utils.py000066400000000000000000000106661454362722700240650ustar00rootroot00000000000000''' utils functions ''' import dbus, re import xml.etree.ElementTree as ET I_INSPECT = 'org.freedesktop.DBus.Introspectable' def _match_uri(name, pattern='.+'): ''' Filter logic for get_players and get_player_uri @param name: string name to test @param pattern=None: string RegEx to test @return: boolean ''' return re.match(pattern, name) def get_session(): ''' @return: dbus.SessionBus.get_session() ''' return dbus.SessionBus.get_session() def get_uri(pattern='.'): ''' Return string of player bus name @param pattern=None: string RegEx that filter response @return: array string of players bus name ''' for item in get_session().list_names(): if _match_uri(item, pattern): yield item def get_mainloop(): ''' @return: mainloop (with 'run' method) ''' try: from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) try: import gobject return gobject.MainLoop() except: pass try: import gi.repository.GLib return gi.repository.GLib.MainLoop() except: pass except: pass class PyQtMainLoop(): def __init__(self, app): self.app = app def run(self): if hasattr(self.app, 'exec_'): self.app.exec_() if hasattr(self.app, 'exec'): method = getattr(self.app, 'exec') method(self.app) try: from dbus.mainloop.qt import DBusQtMainLoop DBusQtMainLoop(set_as_default=True) try: from PySide.QtGui import QApplication return PyQtMainLoop(QApplication([])) except: pass try: from PyQt5.QtWidgets import QApplication return PyQtMainLoop(QApplication([])) except: pass try: from PyQt4 import Qt return PyQtMainLoop(Qt.QApplication([])) except: pass except: pass return None def _introspect_uri(bus_name, path, bus): bus = bus or dbus.SessionBus.get_session() path = path.replace('//', '/') or '/' obj = bus.get_object(bus_name, path) xml = obj.Introspect(dbus_interface=I_INSPECT) return ET.fromstring(xml) def list_paths(bus_name, path='/', bus=None): ''' Return generator with all subpaths of uri @param bus_name: string dbus object name @param path='/': string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all paths that has interfaces ''' nodes = _introspect_uri(bus_name, path, bus) if [iface for iface in nodes.findall('interface')]: yield path.replace('//', '/') for node in nodes.findall('node'): sub_path = path + '/'+ node.attrib['name'] for path_name in list_paths(bus_name, sub_path, bus): yield path_name def list_interfaces(bus_name, path, bus=None): ''' Return generator with all interfaces of path @param bus_name: string dbus object name @param path: string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all interfaces of path ''' nodes = _introspect_uri(bus_name, path, bus) for interface in nodes.findall('interface'): yield interface.attrib['name'] def list_all_interface(bus_name, path='/', bus=None): ''' Return generator with all interfaces of path and subpaths @param bus_name: string dbus object name @param path: string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all interfaces of path and subpaths ''' paths = list_paths(bus_name, path, bus) for sub_path in paths: for interface in list_interfaces(bus_name, sub_path, bus): yield sub_path, interface def implements(uri, interface, path, bus=None): ''' ''' for iface in list_interfaces(uri, path, bus): if iface == interface: return True if __name__ == '__main__': uri = None for uri in get_uri(): if uri.count(':') == 0: print(uri) if uri: for interface in list_all_interface(uri, '/'): print('\t', interface) else: print('Nothing running') autoradio-autoradio-3.6-4/autoradio/dir2ogg.py000077500000000000000000000735461454362722700214330ustar00rootroot00000000000000#!/usr/bin/python # # Copyright (C) 2007-2009 Julian Andres Klode # Copyright (C) 2003-2006 Darren Kirby # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # 10-08-2009 modified by Paolo Patruno ''' dir2ogg converts mp3, m4a, and wav files to the free open source OGG format. Oggs are about 20-25% smaller than mp3s with the same relative sound quality. Your mileage may vary. Keep in mind that converting from mp3 or m4a to ogg is a conversion between two lossy formats. This is fine if you just want to free up some disk space, but if you're a hard-core audiophile you may be dissapointed. I really can't notice a difference in quality with 'naked' ears myself. This script converts mp3s to wavs using mpg123 then converts the wavs to oggs using oggenc. m4a conversions require faad. Id3 tag support requires mutagen for mp3s. Scratch tags using the filename will be written for wav files (and mp3s with no tags!) ''' import sys import os, os.path import re from fnmatch import _cache, translate from optparse import OptionParser from subprocess import Popen, call, PIPE __version__ = '0.11.7' __date__ = '2009-05-03' FILTERS = {'mp3': ('*.mp3',), 'm4a': ('*.aac', '*.m4a', '*.mp4'), 'wma': ('*.asf', '*.wma', '*.wmf'), 'flash': ('*.flv', ), 'flac': ('*.flac',), 'wav': ('*.wav', ), 'speex': ('*.spx','*.speex' ), } def mmatch(names, patterns, rbool=True): '''names/patterns=str/list/tuple''' results = [] if isinstance(names, str): names = [names] if isinstance(patterns, str): patterns = [patterns] for pat in patterns: pat = pat.lower() if not pat in _cache: _cache[pat] = re.compile(translate(pat)) match = _cache[pat].match for name in names: if match(name.lower()): if rbool: return True else: results.append(name) if rbool: return bool(results) else: return results def read_opts(): if not '--version' in sys.argv: show_banner() if len(sys.argv[1:]) == 0: fatal('No arguments specified, see --help for usage.') parser = OptionParser(usage='%prog [options] [arguments]', version='%prog ' + __version__) parser.add_option('-l', '--license', action='callback', callback=show_license, help='display license informations') parser.add_option('-d', '--directory', action='store_true', help='convert files in all directories specified as arguments') parser.add_option('-r', '--recursive', action='store_true', help='convert files in all subdirectories of all directories specified as arguments') parser.add_option('-c', '--cdda', action='store_true', help="convert audio cd in all devices specified as arguments (or default: /dev/cdrom) [EXPERIMENTAL]") parser.add_option('-q', '--quality', metavar='N', default=3.0, type='float', help='quality. N is a number from 1-10 (default %default)') parser.add_option('-t', '--smart-mp3', action='store_true', help='try to use similar quality as original mp3 file (overwrites -q)') parser.add_option('-T', '--smart-mp3-correction', metavar='N', default=0.0, type='float', help='decrease detected quality (implies -t)') parser.add_option('-n', '--no-mp3', dest='convert_mp3', action='store_false', default=True, help="don't convert mp3s (use with '-d' or '-r')") parser.add_option('-a', '--convert-all', action='store_true', help="convert all supported formats") parser.add_option('-f', '--convert-flac', action='store_true', help="convert flac files (use with '-d')") parser.add_option('-x', '--convert-speex', action='store_true', help="convert speex files (use with '-d')") parser.add_option('-m', '--convert-m4a', action='store_true', help="convert m4a files (use with '-d')") parser.add_option('-w', '--convert-wav', action='store_true', help="convert wav files (use with '-d')") parser.add_option('-W', '--convert-wma', action='store_true', help="convert wma files (use with '-d').") parser.add_option('-F', '--convert-flash', action='store_true', help="convert flash files (use with '-d').") parser.add_option('--delete-input', action='store_true', help='delete input files') parser.add_option('-p', '--preserve-wav', action='store_true', help='keep the wav files (also includes -P)') parser.add_option('-P', '--no-pipe', action='store_true', help='Do not use pipes, use temporary wav files') parser.add_option('-v', '--verbose', action='store_true', help='verbose output') # Setup decoders commands = {'mp3': ('mpg123', 'mpg321', 'lame', 'mplayer'), 'wma': ('mplayer',), 'm4a': ('faad', 'mplayer'), 'flash': ('mplayer',), 'flac': ('flac', 'ogg123', 'mplayer'), 'speex': ('speexdec',), 'cd': ('cdparanoia', 'icedax','cdda2wav', 'mplayer'), } for ext, dec in list(commands.items()): default, choices = None, [] for command in dec: in_path = [prefix for prefix in os.environ['PATH'].split(os.pathsep) if os.path.exists(os.path.join(prefix, command))] if in_path: choices.append(command) default = default or command parser.add_option('--' + ext + '-decoder', type="choice", metavar=default, default=default, choices=choices, help="decoder for %s files (choices: %s)" % (ext, ', '.join(choices))) # End of decoder options options, args = parser.parse_args() options.convert_cd = options.cdda options.filters = [] for ext, pat in list(FILTERS.items()): # Activate Encoders for files on the commandline if options.convert_all or mmatch(args, pat): setattr(options, 'convert_' + ext, True) if getattr(options, 'convert_' + ext): options.filters += pat # Missing decoders if ext != 'wav' and getattr(options, 'convert_' + ext) and not getattr(options, ext + '_decoder'): fatal('%s was enabled, but no decoder has been found.' % ext) if len(args) == 0 and not options.cdda: fatal('No files/directories specified.') return options, args def info(msg): print('Information: %s' % msg) def warn(msg): '''print errors to the screen (red)''' print("Warning: %s" % msg, file=sys.stderr) def fatal(msg): '''Fatal error (error + exit)''' print("Error: %s" % msg, file=sys.stderr) sys.exit(1) def return_dirs(root): mydirs = {} for pdir, dirs, files in os.walk(root): if not pdir in mydirs: mydirs[pdir] = files return mydirs class Id3TagHandler(object): '''Class for handling meta-tags. (Needs mutagen)''' accept = ['album', 'album_subtitle', 'albumartist', 'albumartistsort', 'albumsort', 'artist', 'artistsort', 'asin', 'bpm', 'comment', 'compilation', 'composer', 'composersort', 'conductor', 'copyright', 'date', 'discid', 'discnumber', 'encodedby', 'engineer', 'gapless', 'genre', 'grouping', 'isrc', 'label', 'lyricist', 'lyrics', 'mood', 'musicbrainz_albumartistid', 'musicbrainz_albumid', 'musicbrainz_artistid', 'musicbrainz_discid', 'musicbrainz_sortname', 'musicbrainz_trackid', 'musicbrainz_trmid', 'musicip_puid', 'podcast', 'podcasturl', 'releasecountry', 'musicbrainz_albumstatus', 'musicbrainz_albumtype', 'remixer', 'show', 'showsort', 'subtitle', 'title', 'titlesort', 'tracknumber', 'tracktotal'] def __init__(self, song): self.song = song self.tags = {} def grab_common(self, handler, convert=None, error=None): '''Common grabber, starts the handler and applies the tags to self.tags''' try: mydict = handler(self.song) except error as msg: import warnings,traceback; warn('Mutagen failed on %s, no tags available' % self.song) traceback.print_exc(0) print(file=sys.stderr) return if convert: convert = dict([(k.lower(), v.lower()) for k, v in list(convert.items())]) # Fix convert for key, val in list(mydict.items()): key = key.lower() key = convert and (key in convert and convert[key] or key) or key if not key in self.accept: continue if not convert: # Hack for FLAC, which uses Vorbis tags pass elif hasattr(val, 'text'): val = val.text if convert: new_val = [] if not isinstance(val, list): val = [val] for i in val: if not isinstance(i, str): # Convert all invalid values to unicode try: new_val.append(str(i)) except UnicodeDecodeError: warn('Ignoring UnicodeDecodeError in key %s' % key) new_val.append(str(i, errors='ignore')) else: new_val.append(i) val = new_val del new_val self.tags[key] = val def grab_m4a_tags(self): '''Import MP4 tags handler, set convert and call commonGrab''' convert = {'----:com.apple.iTunes:ASIN': 'asin', '----:com.apple.iTunes:MusicBrainz Album Artist Id': 'musicbrainz_albumartistid', '----:com.apple.iTunes:MusicBrainz Album Id': 'musicbrainz_albumid', '----:com.apple.iTunes:MusicBrainz Album Release Country': 'releasecountry', '----:com.apple.iTunes:MusicBrainz Album Status': 'musicbrainz_albumstatus', '----:com.apple.iTunes:MusicBrainz Album Type': 'musicbrainz_albumtype', '----:com.apple.iTunes:MusicBrainz Artist Id': 'musicbrainz_artistid', '----:com.apple.iTunes:MusicBrainz Disc Id': 'musicbrainz_discid', '----:com.apple.iTunes:MusicBrainz TRM Id': 'musicbrainz_trmid', '----:com.apple.iTunes:MusicBrainz Track Id': 'musicbrainz_trackid', '----:com.apple.iTunes:MusicIP PUID': 'musicip_puid', 'aART': 'albumartist', 'cpil': 'compilation', 'cprt': 'copyright', 'pcst': 'podcast', 'pgap': 'gapless', 'purl': 'podcasturl', 'soaa': 'albumartistsort', 'soal': 'albumsort', 'soar': 'artistsort', 'soco': 'composersort', 'sonm': 'titlesort', 'sosn': 'showsort', 'trkn': 'tracknumber', 'tvsh': 'show', '\xa9ART': 'artist', '\xa9alb': 'album', '\xa9cmt': 'comment', '\xa9day': 'date', '\xa9gen': 'genre', '\xa9grp': 'grouping', '\xa9lyr': 'lyrics', '\xa9nam': 'title', '\xa9too': 'encodedby','\xa9wrt': 'composer'} try: from mutagen.mp4 import MP4, error except ImportError: from mutagen.m4a import M4A as MP4, error self.grab_common(MP4, convert, error) def grab_wma_tags(self): '''Import ASF tags handler, set convert and call commonGrab''' convert = {'Author': 'artist', 'Description': 'comment', 'MusicBrainz/Album Artist Id': 'musicbrainz_albumartistid', 'MusicBrainz/Album Id': 'musicbrainz_albumid', 'MusicBrainz/Album Release Country': 'releasecountry', 'MusicBrainz/Album Status': 'musicbrainz_albumstatus', 'MusicBrainz/Album Type': 'musicbrainz_albumtype', 'MusicBrainz/Artist Id': 'musicbrainz_artistid', 'MusicBrainz/Disc Id': 'musicbrainz_discid', 'MusicBrainz/TRM Id': 'musicbrainz_trmid', 'MusicBrainz/Track Id': 'musicbrainz_trackid', 'MusicIP/PUID': 'musicip_puid', 'WM/AlbumArtist': 'albumartist', 'WM/AlbumArtistSortOrder': 'albumartistsort', 'WM/AlbumSortOrder': 'albumsort', 'WM/AlbumTitle': 'album', 'WM/ArtistSortOrder': 'artistsort', 'WM/BeatsPerMinute': 'bpm', 'WM/Composer': 'composer', 'WM/Conductor': 'conductor', 'WM/ContentGroupDescription': 'grouping', 'WM/Copyright': 'copyright', 'WM/EncodedBy': 'encodedby', 'WM/Genre': 'genre', 'WM/ISRC': 'isrc', 'WM/Lyrics': 'lyrics', 'WM/ModifiedBy': 'remixer', 'WM/Mood': 'mood', 'WM/PartOfSet': 'discnumber', 'WM/Producer': 'engineer', 'WM/Publisher': 'label', 'WM/SetSubTitle': 'album_subtitle', 'WM/SubTitle': 'subtitle', 'WM/TitleSortOrder': 'titlesort', 'WM/TrackNumber': 'tracknumber', 'WM/Writer': 'lyricist', 'WM/Year': 'date', } from mutagen.asf import ASF, error self.grab_common(ASF, convert, error) def grab_flac_tags(self): '''Import FLAC tags handler, and call commonGrab''' from mutagen.flac import FLAC, error self.grab_common(FLAC, error=error) def grab_flash_tags(self): '''Import FLAC tags handler, and call commonGrab''' pass def grab_speex_tags(self): '''Import speex tags handler, and call commonGrab''' from mutagen.oggspeex import OggSpeex, error self.grab_common(OggSpeex, error=error) def grab_mp3_tags(self): '''Import MP3 tags handler, and call commonGrab''' from mutagen.id3 import ID3, error convert = {'TPE1': 'artist', 'TPE2': 'albumartist', 'TPE3': 'conductor', 'TPE4': 'remixer', 'TCOM': 'composer', 'TCON': 'genre', 'TALB': 'album', 'TIT1': 'grouping', 'TIT2': 'title', 'TIT3': 'subtitle', 'TSST': 'discsubtitle', 'TEXT': 'lyricist', 'TCMP': 'compilation', 'TDRC': 'date', 'COMM': 'comment', 'TMOO': 'mood', 'TMED': 'media', 'TBPM': 'bpm', 'WOAR': 'website', 'TSRC': 'isrc', 'TENC': 'encodedby', 'TCOP': 'copyright', 'TSOA': 'albumsort', 'TSOP': 'artistsort', 'TSOT': 'titlesort','TPUB': 'label', 'TRCK': 'tracknumber'} self.grab_common(ID3, convert, error) def list_if_verbose(self): info('Meta-tags I will write:') for key, val in list(self.tags.items()): if type(val) == list: info(key + ': ' + ','.join(val)) else: info(key + ': ' + val) class Convert(Id3TagHandler): ''' Base conversion Class. __init__ creates some useful attributes, grabs the id3 tags, and sets a flag to remove files. Methods are the conversions we can do ''' def __init__(self, song, conf): self.device = "" self.track = "" Id3TagHandler.__init__(self, song) self.conf = conf song_root = os.path.splitext(song)[0] + "." self.songwav = song_root + 'wav' self.songogg = song_root + 'ogg' self.decoder = '' if (os.path.exists(self.songogg)): warn('try to convert to an already present file: %s' % self.songogg) return # (smartmp3) I have to remember default quality for next files original_quality = self.conf.quality for ext, pat in list(FILTERS.items()): if mmatch(self.song, pat) and ext != 'wav': self.decoder = getattr(self.conf, ext + '_decoder') getattr(self, 'grab_%s_tags' % ext)() if ext == 'mp3' and (self.conf.smart_mp3 or \ self.conf.smart_mp3_correction): self.smart_mp3() #self.songogg = "%(artist)s/%(album)s/%(track)s - %(title)s.ogg" % self.tags #self.songogg = "%(artist)s/%(album)s - %(title)s.ogg" % self.tags self.convert() # (smartmp3) Replacing quality by default value self.conf.quality = original_quality def smart_mp3(self): # initial Code by Marek Palatinus , 2007 # Table of quality = relation between mp3 bitrate and vorbis quality. Source: wikipedia # quality_table = {45:-1, 64:0, 80:1, 96:2, 112:3, 128:4, 160:5, 192:6, 224:7, 256:8, 320:9, 500:10 } # log(0.015*bitrate, 1.19) is logaritmic regression of table above. Useful for mp3s in VBR :-). try: from mutagen.mp3 import MP3, HeaderNotFoundError except ImportError: warn('(smartmp3) You dont have mutagen installed. Bitrate detection failed. Using default quality %.02f' % self.conf.quality) return try: mp3info = MP3(self.song) bitrate = mp3info.info.bitrate except HeaderNotFoundError: info('(smartmp3) File is not an mp3 stream. Using default quality %.02f' % self.conf.quality) return import math self.conf.quality = round(5.383 * math.log(0.01616 * bitrate/1000.) - self.conf.smart_mp3_correction, 2) self.conf.quality = max(self.conf.quality, -1) # Lowest quality is -1 self.conf.quality = min(self.conf.quality, 6) # Highest quality is 6 info("(smartmp3) Detected bitrate: %d kbps" % (int(bitrate/1000))) info("(smartmp3) Assumed vorbis quality: %.02f" % self.conf.quality) def decode(self): # Used for mplayer tempwav = 'dir2ogg-%s-temp.wav' % os.getpid() if self.decoder not in ('mplayer','speexdec') and not self.conf.no_pipe and not self.conf.preserve_wav: outfile, outfile1 = '-', '/dev/stdout' use_pipe = 1 else: outfile = outfile1 = self.songwav use_pipe = 0 decoder = {'mpg123': ['mpg123', '-w', outfile1, self.song], 'mpg321': ['mpg321', '-w', outfile, self.song], 'faad': ['faad', '-o' , outfile1, self.song], 'ogg123': ['ogg123', '-dwav', '-f' , outfile, self.song], 'flac': ['flac', '-o', outfile, '-d', self.song], 'speexdec':['speexdec', self.song, outfile], 'lame': ['lame', '--quiet', '--decode', self.song, outfile], 'mplayer': ['mplayer', '-vo', 'null', '-vc' ,'dummy', '-af', 'resample=44100', '-ao', 'pcm:file=' + tempwav, self.song], 'alac-decoder': ['alac-decoder', self.song], 'cd-cdparanoia': ['cdparanoia', '-Z', '-q', '-w', '-d', self.device, str(self.track), outfile], 'cd-icedax': ['icedax', '-H', '-t', str(self.track), '-D',self.device], 'cd-cdda2wav': ['cdda2wav', '-H', '-t', str(self.track), '-D',self.device], 'cd-mplayer': ['mplayer', '-vo', 'null', '-vc' ,'dummy', '-af', 'resample=44100', '-ao', 'pcm:file=temp.wav', '-cdrom-device', self.device, "cdda://" + str(self.track)]} if use_pipe: return True, Popen(decoder[self.decoder], stdout=PIPE) else: decoder['cd-cdparanoia'].remove('-q') decoder['lame'].remove('--quiet') retcode = call(decoder[self.decoder]) if self.decoder == 'mplayer': # Move the file for mplayer (which uses tempwav), so it works # for --preserve-wav. os.rename(tempwav, self.songwav) if retcode != 0: return (False, None) else: return (True, None) def convert(self): ''' Convert wav -> ogg.''' if self.songwav == self.song: success = True dec = None else: success, dec = self.decode() if not success: warn('Decoding of "%s" failed.' % self.song) return if dec and self.decoder == 'mpg123': import mutagen try: info("additional option:" ) opts=['-R', str(mutagen.File(self.song).info.sample_rate)] info(str(opts)) except: opts=[] else: opts=[] if dec: enc = Popen(['oggenc', '-Q', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), '-'] + opts, stdin=dec.stdout) enc.communicate() dec.wait() if dec.returncode < 0: warn('Decoding of "%s" failed.' % self.song) return False elif enc.returncode < 0: warn('Encoding of "%s" failed.' % self.song) return False else: enc = call(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), self.songwav]) if enc != 0: warn('Encoding of "%s" failed.' % self.songwav) return False elif not self.conf.preserve_wav and self.song != self.songwav: os.remove(self.songwav) if self.tags != {}: try: # Add tags to the ogg file from mutagen.oggvorbis import OggVorbis myogg = OggVorbis(self.songogg) myogg.update(self.tags) myogg.save() except: warn('Could not save the tags') import traceback traceback.print_exc() return False elif self.songwav != self.song or 'cd-' in self.decoder: warn('No tags found...') if self.conf.delete_input: os.remove(self.song) return True class ConvertTrack(Convert): '''Wrapper around Convert for CD Tracks''' def __init__(self, device, conf, track, tags): self.device, self.track, self.tags, self.conf = device, track, tags, conf self.song = '' self.songwav = "audio.wav" self.songogg = "%(artist)s/%(album)s/%(ntracknumber)s - %(title)s.ogg" % tags self.conf.preserve_wav = False self.decoder = 'cd-' + self.conf.cd_decoder self.convert() class ConvertDisc(object): '''Wrapper around ConvertTrack to Convert complete cds Currently uses MusicBrainz, but a CDDB fallback will be added, too.''' def __init__(self, dev, conf): warn("Converting CDs is not well supported, please use another " "solution.") self.dev, self.conf = dev, conf try: self.get_mb() except self.MBError: warn('MusicBrainz failed. Trying FreeDB...') self.get_cddb() class MBError(Exception): '''Empty''' def get_cddb(self): try: import CDDB, DiscID except ImportError: fatal('You need python-cddb (http://cddb-py.sf.net) to convert cds. Please install it.') disc_id = DiscID.disc_id(DiscID.open(self.dev)) query_info = CDDB.query(disc_id)[1] if not query_info: fatal('The disk is not listed in FreeDB, dir2ogg only supports disk listed in MusicBrainz or FreeDB') if isinstance(query_info, list): query_info = query_info[0] read_info = CDDB.read(query_info['category'], query_info['disc_id'])[1] for track in range(disc_id[1]): title = {} title['discid'] = query_info['disc_id'] title['artist'], title['album'] = (track.strip() for track in query_info['title'].split("/")) title['genre'] = read_info['DGENRE'] title['date'] = read_info['DYEAR'] title['title'] = read_info['TTITLE' + str(track)] title['tracktotal'] = str(len(list(range(disc_id[1]))) + 1) title['ntracknumber'] = '0' * (len(title['tracktotal'] ) - len(str(track+1)) ) + str(track+1) title['tracknumber'] = str(track+1) for key, val in list(title.items()): title[key] = str(str(val), "ISO-8859-1") ConvertTrack(self.dev, self.conf, track+1, title) def get_mb(self): try: import musicbrainz2.disc as mbdisc import musicbrainz2.webservice as mbws except ImportError as err: warn('You need python-musicbrainz2 (or python-cddb) to convert cds. Please install it. Trying cddb.') raise self.MBError(err) service = mbws.WebService() query = mbws.Query(service) # Read the disc in the drive try: disc = mbdisc.readDisc(self.dev) except mbdisc.DiscError as err: warn(err) raise self.MBError discId = disc.getId() try: myfilter = mbws.ReleaseFilter(discId=discId) results = query.getReleases(myfilter) except mbws.WebServiceError as err: warn(err) raise self.MBError if len(results) == 0: print("Disc is not yet in the MusicBrainz database.") print("Consider adding it via", mbdisc.getSubmissionUrl(disc)) raise self.MBError try: inc = mbws.ReleaseIncludes(artist=True, tracks=True, releaseEvents=True) release = query.getReleaseById(results[0].release.getId(), inc) except mbws.WebServiceError as err: warn(err) raise self.MBError isSingleArtist = release.isSingleArtistRelease() try: # try to get the CDDB ID import DiscID cddb_id = '%08lx' % int(DiscID.disc_id(DiscID.open(self.dev))[0]) except: cddb_id = False trackn = 1 for track in release.tracks: title = {} title['artist'] = isSingleArtist and release.artist.name or track.artist if cddb_id: title['discid'] = cddb_id title['album'] = release.title title['date'] = release.getEarliestReleaseDate() title['musicbrainz_albumartistid'] = release.artist.id.split("/")[-1] title['musicbrainz_albumid'] = release.id.split("/")[-1] title['musicbrainz_discid'] = discId title['musicbrainz_sortname'] = release.artist.sortName title['musicbrainz_trackid'] = track.id.split("/")[-1] title['title'] = track.title title['tracktotal'] = str(len(release.tracks)) title['ntracknumber'] = "%02d" % trackn title['tracknumber'] = str(trackn) ConvertTrack(self.dev, self.conf, trackn, title) trackn+=1 class ConvertDirectory(object): ''' This class is just a wrapper for Convert. Grab the songs to convert, then feed them one by one to the Convert class. ''' def __init__(self, conf, directory, files): ''' Decide which files will be converted.''' if os.path.exists(directory) == 0: fatal('Directory: "%s" not found' % directory) self.directory = directory = os.path.normpath(directory) + os.path.sep self.songs = mmatch(files, conf.filters, False) if conf.verbose: self.print_if_verbose() for song in self.songs: try: Convert(directory + song, conf) except: warn('File: %s error in ogg conversion' % directory + song) def print_if_verbose(self): ''' Echo files to be converted if verbose flag is set.''' info('In %s I am going to convert:' % self.directory) for song in self.songs: print(" ", song) def show_banner(): print('dir2ogg %s (%s), converts audio files into ogg vorbis.\n' % (__version__, __date__)) def show_license(*args, **kwargs): print('Copyright (C) 2007-2008 Julian Andres Klode ') print('Copyright (C) 2003-2006 Darren Kirby \n') print('This program is distributed in the hope that it will be useful,') print('but WITHOUT ANY WARRANTY; without even the implied warranty of') print('MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the') print('GNU General Public License for more details.\n') print('Currently developed by Julian Andres Klode .') sys.exit(0) def main(): conf = read_opts() conf_args, conf = conf[1], conf[0] if conf.cdda: discs = len(conf_args) and conf_args or ("/dev/cdrom",) for disc in discs: ConvertDisc(disc, conf) elif conf.directory or conf.recursive: rdirs = {} for path in conf_args: if not os.path.isdir(path): fatal('Path: %s does not exists' % path) elif conf.recursive: rdirs.update(return_dirs(path)) elif conf.directory: rdirs.update({path: os.listdir(path)}) for directory, files in list(rdirs.items()): try: ConvertDirectory(conf, directory, files) except: warn('DIR: %s ;Files: %s error in ogg conversion' % (directory,files)) else: for path in conf_args: if not os.path.isfile(path): fatal('Path: %s does not exists' % path) for filename in conf_args: try: Convert(filename, conf) except: warn('File: %s error in ogg conversion' % filename) sys.exit(0) if __name__ == '__main__': main() autoradio-autoradio-3.6-4/autoradio/doc/000077500000000000000000000000001454362722700202475ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/doc/__init__.py000066400000000000000000000000001454362722700223460ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/doc/templates/000077500000000000000000000000001454362722700222455ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/doc/templates/doc/000077500000000000000000000000001454362722700230125ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/doc/templates/doc/doc.html000066400000000000000000000421241454362722700244500ustar00rootroot00000000000000{% extends "admin/base_site.html" %} {% load i18n %} {% block content %}

{% trans 'Documentation Home' %}

{% if docitem == "overview" %} {% blocktrans %} Radio automation software. Simple to use, starting from digital audio files, manage on-air broadcasting over a radio-station or web-radio. The main components are:
  • Player (gstreamer): plays all your media files and send digital sound to an audio device or audio server
  • Scheduler: real time manager for emission of special audio files like jingles, spots, playlist and programs; interact with player like supervisor User
  • inteface: WEB interface to monitor the player and scheduler and admin the schedules for the complete control over your station format. The web interface allows you to easily publish podcasts that conform to the RSS 2.0 and iTunes RSS podcast specifications The web interface provide a "full compatible" ogg player.
Developed with Python, Django, Dbus it works in an production enviroment {% endblocktrans %} {% endif %} {% if docitem == "feature" %} {% blocktrans %}
  • manage ogg, mp3, wav and other media file format
  • it's designed as client - server
  • manage playlists, inserting on it jingles, spots and programs
  • programmable rules for schedule and period schedule
  • do not overlap schedules: anticipate, postone or delete
  • player is monitored by web interface
  • spots are grouped and ordered by your preference
  • programs are available for podcasting in a very complete rss feed web interface
  • integrated web player for ogg vorbis that is very compatible with most user's systems
  • can produce a palimpsest and a printable version is available following the the italian law standard
  • integrated daemon system with logging
  • provide enhanced version of dir2ogg.py and mkplaylist.py to manage files with music (convert to ogg and make playlist)
  • do not use DataBases to manage music; you can use your preferred application to produce playlists
  • on line web documentation
{% endblocktrans %} {% endif %} {% if docitem == "player" %}

{% blocktrans %} Partendo da una playlist è in grado di gestire differenti formati di audio digitali per poi inviare il suono o a una scheda audio o a un server audio.

{% endblocktrans %} {% blocktrans %} Esistono varie possibilità:
  • Autoplayerd: Questo player è basato su gstreamer e quindi disponibile su tutte le nuove distribuzioni. Il formato dei file audio è determinato dai plugin di gstreamer installati. Questo player non ha bisogno di un terminale per l'interazione umana. Espone una interfaccia a standard mpris2 su dbus e quindi qualsiasi applicazione che interagisca con questa interfaccia può impartire comandi al player. Autoradio fornisce autoplayergui che ha una interfaccia grafica tramite la quale è possibile eseguire tutte le funzioni elementari quali play, pause, stop etc. Il vantaggio è che un computer senza terminale quale un server può funzionare e avere questo player in modalità daemon, ossia sempre attiva. Il player permette l'invio diretto a un server per lo streaming per la realizzazione di web radio. Questo è il player preferito per l'utilizzo con AutoRadio.
  • Audacious2: Questo player è disponibile su tutte le nuove distribuzioni. Permette l'invio diretto a un server per lo streaming per la realizzazione di web radio.
  • Xmms: E' un player “antico” ma molto robusto. Consigliato solo su vecchie distribuzioni
{% endblocktrans %} {% blocktrans %} Questi sono i meccanismi di funzionamento principale: {% endblocktrans %}
  • {% blocktrans %}deve essere sempre presente nel player una playlist di brani musicali ciascuno di durata non superiore a 7/8 minuti; brani piu' lunghi potrebbero comportare ritardi e cattiva gestione dell'emissione automatica. Per mantenere sempre piena la playlist si consiglia di prevedere almeno due volte al giorno il caricamento automatico di una playlist voluminosa.{% endblocktrans %}
  • {% blocktrans %}quando una schedula raggiunge il tempo per cui è stata programmata viene inserita nella prima posizione successiva a quella attualmente in play, e successiva anche ad ogni file precedentemente inserito da una precedente schedula.{% endblocktrans %}
  • {% blocktrans %}tutto thread save, ossia le funzioni fatte sul player dalle varie schedule saranno sempre consistenti.{% endblocktrans %}
  • {% blocktrans %}le operazioni di inserimento e cancellazione dalla playlist vengono fatte solo quando mancano piu' di 10 secondi alla fine del brano per non cadere in situazioni critiche e inconsistenti.{% endblocktrans %}
  • {% blocktrans %}la testa della playlist, che se tutto è programmato correttamente tende sempre a crescere, viene tagliata a 10 brani.{% endblocktrans %}
  • {% blocktrans %}la coda della playlist che se tutto è programmato correttamente tende sempre a crescere viene tagliata a 500 brani.{% endblocktrans %}
  • {% blocktrans %}il player se in stato "stop" viene sempre rimesso in stato "play".{% endblocktrans %}
  • {% blocktrans %}il player se in stato "pause" rimarrà sempre in "pause" se non ci sarà un intervento manuale.{% endblocktrans %}
  • {% blocktrans %}è possibile visualizzare lo stato del player con interfaccia web.{% endblocktrans %}
{% endif %} {% if docitem == "scheduler" %}

{% blocktrans %} Lo scheduler è un programma che lanciato separatamente comanda all'istante di tempo opportuno il Player per attivare l'emissione delle programmazione preimpostata. Svolge anche altre funzioni logiche e di controllo quali l'esecuzione del player se non dovesse risultare attivo. Ogni volta che una programmazione è stata inserita con successo nella playlist del player nel database di autoradio essa risulta come se fosse stata effettivamente messa in onda.Ovviamente se sul player vengono fatte operazioni manuali lo scheduler non ne puo tenere conto. {% endblocktrans %}

{% blocktrans %} Vengono estratte tutte le schedule in un intervallo di tempo a cavallo tra passato e futuro. Spot e programmi programmati nel passato e non ancora emessi vengono programmati immediatamente se il ritardo non è eccessivo. Le pubblicità che cadono durante l'emissione di un programma vengono anticipare o ritardate a seconda della vicinanza temporale all'inizio o alla fine delle parti del programma. I jingles che cadono durante l'emissione di programmi o publicità vengono eliminati. {% endblocktrans %}

{% blocktrans %} Lo scheduler provvede anche alla generazione dinamica delle playlist delle fasce pubblicitarie per l'eventuale emissione manuale della pubblicità. Queste playlist vengono generate poco prima dell'orario programato per l'emissione e si possono trovare nella cartella specificata nel file di configurazione (playlistdir). {% endblocktrans %}

{% endif %} {% if docitem == "playlist" %}

{% blocktrans %} Le playlist sono il "tappeto" musicale dell'emissione radiofonica. Ogni playlist puo' essere programmata per un istante preciso oppure per una emissione periodica ad iniziare da una una data specifica fino a una data finale per alcuni giorni della settimana specificati. Le playlist prima di essere caricate vengono controllate e i brani musicali corrotti o mancanti vengono eliminati prima di essere inseriti. E' possibile specificare la durata della playlist che verrà inserita nel player. Una opzione permette di attivare la funzione di mescolamento dell'ordine della sequenza dei brani. {% endblocktrans %}

{% blocktrans %} Per poter funzionare Autoradio deve sempre avere un discreto numero di brani musicali caricati nella playlist tra i quali inserire le altre programmazioni. Quando una playlist programmata viene mandata in onda essa viene inserita in testa ai brani già presenti nella lista del player. {% endblocktrans %}

{% endif %} {% if docitem == "jingle" %}

{% blocktrans %} I jingles vengono emessi ad intervalli di tempo fissi. Per ogni jingle è possibile impostare da quale data a quale data effettuare l'emissione, da che ora a che ora effettuare l'emissione e in quali giorni della settimana. E' cosi' facile attivare promo di programmi o altro ad orari specifici. {% endblocktrans %}

{% blocktrans %} Il jingle programmato sarà quello con ultima data di emissione piu' vecchia; se ci sono piu' jingle con la stessa ultiuma data di emissione, i jingle vengono ordinati per il parametro impostabile della priorità. {% endblocktrans %}

{% endif %} {% if docitem == "spot" %}

{% blocktrans %} E' possibile impostare qualsiasi numero di fasce pubblicitarie caratterizzate da un orario di emissione; ogni fascia è attivabile o disattivabile singolarmente. Una fascia pubblicitaria è composta da spot. Ogni fascia pubblicitaria ha uno o piu' spot definiti come prologo che annunciano la pubblicità. Ogni fascia pubblicitaria ha uno o piu' spot definiti come epilogo che annunciano la fine della pubblicità. {% endblocktrans %}

{% blocktrans %} Per ogni spot (o prologo o epilogo) è possibile stabilire da quale data a quale data effettuare l'emissione, in quali giorni della settimana e in quale fascia pubblicitaria. Ogni spot ( o prologo o epilogo) ha una priorità che determina l'oridine di emissione. {% endblocktrans %}

{% endif %} {% if docitem == "program" %}

{% blocktrans %} La gestione dei programmi è la sezione più articolata di Autoradio. Uno show è composto da episodi che a loro volta sono composti da enclosure (parti). Uno show ah alcuni parametri che lo definiscono nel palinsesto. Un episodio ha dei parametri che definiscono quando deve essere mandato in onda da autoradio. Le enclosure (parti) permettono di spezzare episodi di lunga durata per facilitarne la messa in onda, il download e gli inserimenti pubblicitari. Quando dal menù principale si seleziona programmi viene presentato il modulo per l'inserimento di un episodio di uno show. Se lo show a cui appartiene un episodio non è stato ancora definito bisogna farlo come prima operazione; selezionando il + a fianco della voce Show è possibile farlo. {% endblocktrans %}

{% trans 'La definizione di uno Show' %}

{% blocktrans %} Nella sezione principale vengono richieste alcune informazioni sullo show e vengono utilizzate alcune categorie definite dalla legislazione italiana. {% endblocktrans %}

{% blocktrans %} Nella sezione "Podcast options" e "iTunes options" vengono richieste informazioni relative al servizio podcast ben descritto alle voci successive di questa documentazione. {% endblocktrans %}

{% blocktrans %} Nella sezione "Periodic Schedules" e "APeriodic Schedules" vengono richieste informazioni necessarie alla compilazione del palinsesto e alla stampa del libro programmi richiesto dalla legislazione italiana, funzione ben descritta alle voce successiva di questa documentazione. {% endblocktrans %}

{% blocktrans %} Ogni Show puo' essere inserito in palinsesto a un istante preciso oppure per una emissione periodica ad iniziare da una una data specifica fino a una data finale per alcuni giorni della settimana specificati. {% endblocktrans %}

{% trans "FeedBurner and iTunes URLs" %}

{% blocktrans %} After saving at least one show and one episode, consider submitting your feed URL to FeedBurner for keeping track of podcast subscriber statistics. Your feed URL should be something like, where title-of-show is the slug of your show: {% endblocktrans %}

http://www.example.com/podcasts/title-of-show/feed/

{% blocktrans %} Remember to check the checkbox for "I'm a podcaster!" Your new FeedBurner URL should be something like: {% endblocktrans %}

http://feeds.feedburner.com/TitleOfShow

{% blocktrans %} You can now return to your website's admin and paste this URL into your Show's FeedBurner textbox. For bonus points, submit your FeedBurner URL to the iTunes Store. Your iTunes podcast URL should then be something like: {% endblocktrans %}

http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=000000000

{% blocktrans %} The advantage of submitting your FeedBurner URL to the iTunes Store allows you to track show statistics while also giving users the advantage of using the friendly iTunes interface. Return to the admin again and paste the iTunes show URL into the Show's iTunes URL textbox. {% endblocktrans %}

{% trans "Ping iTunes for new content" %}

{% blocktrans %} The iTunes Store checks new content daily but you might want to make a new episode available immediately in the iTunes Store. Visit your show's ping URL to make that episode available, which would be something like: {% endblocktrans %}

{% blocktrans %} Alternatively, if you're a savvy developer, you could set up a cron job to handle this, but note that pinging too often could result in a removal from the iTunes Store. {% endblocktrans %}

{% trans "Yahoo! Media RSS feed submission" %}

{% blocktrans %} Likewise, considering submitting your podcast to Yahoo! Search, which specifically accepts any kind of regularly published media-based (audio, video, image, document, etc.) RSS 2.0 feed or Media RSS feed. Your Media RSS feed should be something like: {% endblocktrans %}

{% trans "Google video sitemaps" %}

{% blocktrans %} If you're creating a video podcast, you can submit a video sitemap to Google Webmaster Tools. The video sitemap will help Google index videos in Google Video. The video sitemap URL should be something like: {% endblocktrans %}

{% blocktrans %} Additionally, you can add the video sitemap URL to your robots.txt file: {% endblocktrans %}

{% blocktrans %} Google allows the submission of a media RSS feed instead of the sitemap to Google Webmaster Tools if you prefer. {% endblocktrans %}

{% trans 'La definizione di un Episodio' %}

{% blocktrans %} Un episodio è composto da una o piu' enclosure (parti) associate a un titolo e un file audio da caricare {% endblocktrans %}

{% blocktrans %} Un episodio ha una o più schedule che definiscono quando dovrà essere mandato in onda automaticamente da autoradio (prima emissione ed eventuali repliche). {% endblocktrans %}

{% blocktrans %} Per ogni episodio è possibile inserire dei metadati utili per effettuare un efficiente podcast/mediacast. {% endblocktrans %}

{% trans "What is the Dublin Core namespace?" %}

{% blocktrans %} The Dublin Core namespace allows for meta data to be associated with content contained in an RSS feed. Additional details on the Dublin Core or the DC extension. {% endblocktrans %}

Podcast

{% trans 'Che cosa è il podcasting/mediacast?' %}

{% blocktrans %} Il podcasting o in senso più generale il Mediacast è un sistema che mette a disposizione brani audio e video attraverso Internet in formato feed RSS, in pratica è un servizio che automaticamente informa ed eventualmente scarica i nuovi file audio messi a disposizione su un sito. Tramite un programma in grado di leggere e decifrare questi feed, è possibile essere informati non appena un nuovo file audio viene pubblicato. Il podcasting consente un ascolto personalizzato dei contenuti: gli utenti scelgono quando ascoltare, dove ascoltare e come ascoltare i file audio. {% endblocktrans %}

{% trans 'Come funziona il podcasting/mediacast?' %}

{% blocktrans %} Il procedimento è semplice: occorre scaricare ed installare sul proprio pc un software per il podcasting. Una volta installato il programma, bisogna indicare da quali fonti scaricare i file e con quale frequenza cercare nuovi brani. {% endblocktrans %}

{% trans 'Autoradio: un efficiente motore per il podcasting/mediacast' %}

{% blocktrans %} Autoradio fornisce una interfaccia web accessibile dal menu principale alla voce Mediacast per navigare i programmi e i relativi episodi fornendo i flussi web necessari per un efficiente podcasting della propria programmazione radiofonica. {% endblocktrans %}

{% endif %} {% if docitem == "programbook" %}

{% blocktrans %} Autoradio permette la stampa del Libro Programmi secondo la legislazione italiana. Selezionata l'apposita voce dal menu principale è possibile procedere alla stampa inserendo gli estremi delle date richieste. Viene generato un file PDF pronto per la stampa. Alcune voci presenti nella stampa sono definite nella tabella "configure" della sezione "programmi" e modificabili dal pannello di amministrazione. {% endblocktrans %}

{% endif %}
{% endblock %} autoradio-autoradio-3.6-4/autoradio/doc/templates/doc/index.html000066400000000000000000000036561454362722700250210ustar00rootroot00000000000000{% extends "admin/base_site.html" %} {% load i18n %} {% block content %}

Documentation

Autoradio {% trans "overview" %}

{% trans "A global vision of Autoradio suite." %}

Autoradio {% trans "features" %}

{% trans "What you can do with Autoradio." %}

{% trans "Main components" %}

{% trans "The components of autoradio suite." %}

Autoradio {% trans "player" %}

{% trans "What you can do with Autoradio." %}

Autoradio {% trans "scheduler" %}

{% trans "Real time emission of your schedule." %}

{% trans "User inteface" %}

{% trans "The web interface." %}

{% blocktrans %}

Ogni classe di configurazione dispone della voce "configure" dalla quale è possibile impostare alcune caratteristiche per l'intera classe quali attivazione/disattivazione o limiti di orario della classe.

La voce "giorno" permette di inserire i nomi dei giorni nella lingua impostata

{% endblocktrans %}

{% trans "Playlist" %}

{% trans "How to start to play music." %}

{% trans "Jingle" %}

{% trans "How to start to use jingles to promote your brand." %}

{% trans "Spot" %}

{% trans "Organize radio advertisement." %}

{% trans "Program" %}

{% trans "Record your programs and set when it will be on air." %}

{% trans "Podcast" %}

{% trans "How to distribute your audio on the net." %}

{% trans "Program's book" %}

{% trans "Palimpsest for the italian law." %}

{% endblock %} autoradio-autoradio-3.6-4/autoradio/doc/urls.py000066400000000000000000000010661454362722700216110ustar00rootroot00000000000000from django.conf.urls import * #from django.views.generic.simple import direct_to_template #from django.conf.urls import patterns from django.views.generic import TemplateView urlpatterns = [ url(r'^$', TemplateView.as_view(template_name="doc/index.html")), url(r'^(?P\w+)/$', TemplateView.as_view(template_name="doc/doc.html")), ] #urlpatterns = patterns('autoradio.doc.views', # (r'^$', direct_to_template , {'template' : 'doc/index.html'}), # (r'^(?P\w+)/$', direct_to_template , {'template' : 'doc/doc.html'}), #) autoradio-autoradio-3.6-4/autoradio/gest_jingle.py000066400000000000000000000130131454362722700223440ustar00rootroot00000000000000#!/usr/bin/env python # This Python file uses the following encoding: utf-8 # GPL. (C) 2007-2009 Paolo Patruno. import os os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' from django.conf import settings import logging from datetime import * from .autoradio_config import * from django.db.models import Q from django.core.exceptions import ObjectDoesNotExist from itertools import * import calendar from .jingles.models import Configure from .jingles.models import Jingle from .jingles.models import Giorno # used to get metadata from audio files import mutagen freq_default=time(00,15,00) def time_iterator(datesched_min,datesched_max,emission_freq): datai=datesched_min.date() delta=timedelta(hours=emission_freq.hour,minutes=emission_freq.minute,\ seconds=emission_freq.second) datac=datetime.combine(datai,time(00,00,00)) while datac < datesched_min: datac=datac+delta yield datac while datesched_max>= datac: datac=datac+delta yield datac class gest_jingle(object): def __init__ (self,now,minelab): """init of jingle application: now : currenti datetime minelab: minutes to elaborate execute the right data retrival to get the schedued jingles""" self.now=now self.minelab=minelab self.ora=now.time() self.oggi=now.date() self.giorno=calendar.day_name[now.weekday()] self.datesched_min=self.now - timedelta( seconds=60*self.minelab) self.datesched_max=self.now + timedelta( seconds=60*self.minelab) logging.debug( "JINGLE: elaborate from %s to %s",self.datesched_min, self.datesched_max) #self.timesched_min=self.datesched_min.time() #self.timesched_max=self.datesched_max.time() #logging.debug( "JINGLE: elaborate from %s to %s",timesched_min, timesched_max) try: self.emission_freq = Configure.objects.get().emission_freq except ObjectDoesNotExist: logging.warning( "JINGLE: emission_freq doesn't exist. Setting default") self.emission_freq = freq_default logging.debug("JINGLE: frequenza di emissione %s",self.emission_freq) if (Configure.objects.filter(active__exact=False).count() == 1): self.jingles=() return #todo: ma i NULL nel sort dove stanno? all'inizio o alla fine? #todo: l'order by qui non funziona in quanto vale praticamente sempre #quello che è stato emesso piu' in la nel tempo #la priorità di fatto non viene considerata # if (timesched_min < timesched_max): # we select every jingle active at "now" # if not selected some time limits is like 00 for start and 24 for end # warning: if you set 18:00 for start and nothing for end it start 18:00 and stop at 24:00 self.jingles= Jingle.objects.filter\ (Q(start_date__lte=self.oggi) | Q(start_date__isnull=True),\ Q(end_date__gte=self.oggi) | Q(end_date__isnull=True),\ Q(start_time__lte=self.ora) | Q(start_time__isnull=True),\ Q(end_time__gte=self.ora) | Q(end_time__isnull=True),\ Q(giorni__name__exact=self.giorno) , Q(active__exact=True))\ .order_by('emission_done','priorita') # TODO: we have to add case were start_time > end_time # this is only a special case; no good # else: # # warning here we are around midnight # # we select every jingle active at "now" # # but we have a value of 24 and 00 for implicit max and min # self.jingles= Jingle.objects.filter\ # (Q(start_date__lte=self.oggi) | Q(start_date__isnull=True),\ # Q(end_date__gte=self.oggi) | Q(end_date__isnull=True),\ # Q(start_time__lte=self.ora) | Q(start_time__isnull=True) | Q(end_time__gte=self.ora) | Q(end_time__isnull=True),\ # Q(giorni__name__exact=self.giorno) , Q(active__exact=True))\ # .order_by('emission_done','priorita') def get_jingle(self): many_jingles=cycle(self.jingles) # for datac in time_iterator(self.datesched_min,self.datesched_max,self.emission_freq): for datac in time_iterator(self.now,self.datesched_max,self.emission_freq): try: jingle=next(many_jingles) except StopIteration: return jingle.ar_filename=jingle.file.path jingle.ar_url=jingle.file.url # jingle.ar_filename=jingle.get_file_filename() jingle.ar_scheduledatetime=datac jingle.ar_emission_done=jingle.emission_done # elaborate the media time length try: jingle.ar_length=mutagen.File(jingle.ar_filename).info.length logging.debug("JINGLE: time length: %s",jingle.ar_length) except: logging.error("JINGLE: error establish time length; use an estimation %s", jingle.ar_filename) jingle.ar_length=30 yield jingle def main(): now=datetime.now() jingles=gest_jingle(now,minelab) for jingle in jingles.get_jingle(): print("----------------------------") print(jingle) print(jingle.ar_url) print(jingle.ar_filename) print(jingle.ar_scheduledatetime) print(jingle.ar_length) print(jingle.ar_emission_done) for giorno in jingle.giorni.all(): print(giorno) if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/gest_palimpsest.py000066400000000000000000000133111454362722700232560ustar00rootroot00000000000000 #!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. import os os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' from django.conf import settings import logging from datetime import * from .autoradio_config import * from django.db.models import Q from .programs.models import Configure from .programs.models import PeriodicSchedule from .programs.models import AperiodicSchedule import os,calendar class gest_palimpsest(object): def __init__ (self,datetimeelab,minelab): """init of palimpsest application: datetimeelab : datetime to elaborate execute the right data retrival to get the schedued programs""" self.radiostation=None self.channel=None self.mezzo=None self.type=None self.datetimeelab = datetimeelab self.oggi=self.datetimeelab.date() ora=datetimeelab.time() self.giorno=calendar.day_name[self.datetimeelab.weekday()] self.schedule=() self.periodicschedule=() self.datesched_min=self.datetimeelab - timedelta( seconds=60*minelab) self.datesched_max=self.datetimeelab + timedelta( milliseconds=60000*minelab-1) #1 millisecond tollerance self.timesched_min=self.datesched_min.time() self.timesched_max=self.datesched_max.time() logging.debug( "PALIMPSEST: elaborate date from %s to %s",self.datesched_min, self.datesched_max) logging.debug( "PALIMPSEST: elaborate time from %s to %s",self.timesched_min, self.timesched_max) if (Configure.objects.filter(active__exact=False).count() == 1): return #todo: the use of ora here is not exact if (Configure.objects.filter(emission_starttime__gt=ora).count() == 1) : return if (Configure.objects.filter(emission_endtime__lt=ora).count() == 1): return # retrive the right records relative to schedule self.schedule=AperiodicSchedule.objects.select_related()\ .filter(emission_date__gte=self.datesched_min)\ .filter(emission_date__lte=self.datesched_max)\ .filter(show__active__exact=True)\ .order_by('emission_date') # retrive the right records relative to periodicschedule if (self.timesched_min < self.timesched_max): self.periodicschedule=PeriodicSchedule.objects\ .filter(Q(start_date__lte=self.oggi) | Q(start_date__isnull=True))\ .filter(Q(end_date__gte=self.oggi) | Q(end_date__isnull=True))\ .filter(time__gte=self.timesched_min)\ .filter(time__lte=self.timesched_max)\ .filter(giorni__name__exact=self.giorno)\ .filter(show__active__exact=True)\ .order_by('time') else: # warning here we are around midnight logging.debug("PALIMPSEST: around midnight") domani=calendar.day_name[self.datesched_max.weekday()] self.periodicschedule=PeriodicSchedule.objects\ .filter(Q(start_date__lte=self.oggi) | Q(start_date__isnull=True))\ .filter(Q(end_date__gte=self.oggi) | Q(end_date__isnull=True))\ .filter(Q(time__gte=self.timesched_min) & Q(giorni__name__exact=self.giorno) |\ Q(time__lte=self.timesched_max) & Q(giorni__name__exact=domani))\ .filter(show__active__exact=True)\ .order_by('time') infos=Configure.objects.filter(active__exact=True) if (infos.count() == 1): for info in infos: self.radiostation=info.radiostation self.channel=info.channel self.mezzo=info.mezzo self.type=info.type def get_program(self): "iterable to get programs" ora=self.datetimeelab.time() for program in self.schedule: logging.debug("PALIMPSEST: schedule %s %s", program.show.title, ' --> '\ ,program.emission_date.isoformat()) program.ar_scheduledatetime=program.emission_date yield program for program in self.periodicschedule: logging.debug("PALIMPSEST: periodic schedule %s %s", program.show.title, ' --> '\ , program.time.isoformat()) if (self.timesched_min < self.timesched_max): program.ar_scheduledatetime=datetime.combine(self.datesched_min.date(), program.time) else: # we are around midnight we have to check the correct date (today, tomorrow) if program.time > time(12): program.ar_scheduledatetime=datetime.combine(self.datesched_min.date(), program.time) else: program.ar_scheduledatetime=datetime.combine(self.datesched_max.date(), program.time) yield program def get_info(self): """ get station info yield: radiostation channel mezzo type """ yield self.radiostation yield self.channel yield self.mezzo yield self.type def main(): logging.basicConfig(level=logging.DEBUG,) # time constants datetimeelab=datetime.now() minelab=60*4 # get the programs of my insterest pro=gest_palimpsest(datetimeelab,minelab) for info in pro.get_info(): print("info: ",info) # I do a list for program in pro.get_program(): #pass print(program) print(program.ar_scheduledatetime) print(program.program.length) print("program",program.program) if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/gest_playlist.py000066400000000000000000000173621454362722700227500ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # GPL. (C) 2007-2009 Paolo Patruno. import os os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' from django.conf import settings import logging import datetime from .autoradio_config import * from django.db.models import Q from .playlists.models import Configure from .playlists.models import PeriodicSchedule from .playlists.models import Schedule from .playlists.models import Playlist if (player == "amarok") : from autoradiod import amarok import os,calendar class gest_playlist(object): def __init__ (self,now,minelab): """init of playlist application: now : currenti datetime minelab: minutes to elaborate execute the right data retrival to get the schedued playlists""" self.now = now ora=self.now.time() self.oggi=self.now.date() self.giorno=calendar.day_name[self.now.weekday()] self.schedule=() self.periodicschedule=() self.datesched_min=self.now - datetime.timedelta( seconds=60*minelab) self.datesched_max=self.now + datetime.timedelta( milliseconds=60000*minelab-1) # 1 millisecond tollerance self.timesched_min=self.datesched_min.time() self.timesched_max=self.datesched_max.time() logging.debug( "PLAYLIST: elaborate date from %s to %s",self.datesched_min, self.datesched_max) logging.debug( "PLAYLIST: elaborate time from %s to %s",self.timesched_min, self.timesched_max) if (Configure.objects.filter(active__exact=False).count() == 1): return #todo: the use of ora here is not exact if (Configure.objects.filter(emission_starttime__gt=ora).count() == 1) : return if (Configure.objects.filter(emission_endtime__lt=ora).count() == 1): return # retrive the right records relative to schedule self.schedule=Schedule.objects.select_related()\ .filter(emission_date__gte=self.datesched_min)\ .filter(emission_date__lte=self.datesched_max)\ .filter(playlist__active__exact=True)\ .order_by('emission_date') # retrive the right records relative to periodicschedule if (self.timesched_min < self.timesched_max): self.periodicschedule=PeriodicSchedule.objects\ .filter(Q(start_date__lte=self.oggi) | Q(start_date__isnull=True))\ .filter(Q(end_date__gte=self.oggi) | Q(end_date__isnull=True))\ .filter(time__gte=self.timesched_min)\ .filter(time__lte=self.timesched_max)\ .filter(giorni__name__exact=self.giorno)\ .filter(playlist__active__exact=True)\ .order_by('time') else: # warning here we are around midnight logging.debug("PLAYLIST: around midnight") ieri=str(calendar.day_name[self.datesched_min.weekday()]) domani=str(calendar.day_name[self.datesched_max.weekday()]) self.periodicschedule=PeriodicSchedule.objects.filter \ (Q(start_date__lte=self.oggi) | Q(start_date__isnull=True),\ Q(end_date__gte=self.oggi) | Q(end_date__isnull=True),\ (Q(time__gte=self.timesched_min) & Q(giorni__name__exact=ieri))\ |\ (Q(time__lte=self.timesched_max) & Q(giorni__name__exact=domani))\ ,\ playlist__active__exact=True)\ .order_by('time') def get_playlist(self): "iterable to get playlist" for playlist in self.schedule: logging.debug("PLAYLIST: schedule %s %s %s", playlist.playlist.playlist, ' --> '\ ,playlist.emission_date.isoformat()) # amarok vuole il nome della playlist che deve gia' esistere del suo elenco # gli altri vogliono il file della playlist if (player == "amarok"): playlist.ar_filename=playlist.playlist.playlist else: playlist.ar_filename=playlist.playlist.file.path playlist.ar_url=playlist.playlist.file.url playlist.ar_scheduledatetime=playlist.emission_date playlist.ar_emission_done=playlist.emission_done # # calcolo la lunghezza del programma # relpath= os.path.basename(playlist.ar_filename) # basedir=os.path.dirname(playlist.ar_filename) # try: # meta = metadata.metadata_from_file(relpath, \ # basedir, tracknrandtitlere, postprocessors) # playlist.ar_length=meta.length # except: # playlist.ar_length=3600 playlist.ar_length=playlist.length if playlist.ar_length is None : playlist.ar_length=3600*24-1 playlist.ar_shuffle=playlist.shuffle yield playlist for playlist in self.periodicschedule: logging.debug("PLAYLIST: periodic schedule %s %s %s", playlist.playlist.playlist, ' --> '\ , playlist.time.isoformat()) # amarok vuole il nome della playlist che deve gia' esistere del suo elenco # gli altri vogliono il file della playlist if (player == "amarok"): playlist.ar_filename=playlist.playlist.playlist else: playlist.ar_filename=playlist.playlist.file.path playlist.ar_url=playlist.playlist.file.url #print self.timesched_min, self.timesched_max if (self.timesched_min < self.timesched_max): #print self.datesched_min.date() #print playlist.time playlist.ar_scheduledatetime=datetime.datetime.combine(self.datesched_min.date(), playlist.time) else: # we are around midnight we have to check the correct date (today, tomorrow) if playlist.time > datetime.time(12): playlist.ar_scheduledatetime=datetime.datetime.combine(self.datesched_min.date(), playlist.time) else: playlist.ar_scheduledatetime=datetime.datetime.combine(self.datesched_max.date(), playlist.time) playlist.ar_emission_done=playlist.emission_done # # calcolo la lunghezza del programma # relpath= os.path.basename(playlist.ar_filename) # basedir=os.path.dirname(playlist.ar_filename) # try: # meta = metadata.metadata_from_file(relpath, \ # basedir, tracknrandtitlere, postprocessors) # playlist.ar_length=meta.length # except: # playlist.ar_length=3600 playlist.ar_length=playlist.length if playlist.ar_length is None : playlist.ar_length=3600*24-1 playlist.ar_shuffle=playlist.shuffle yield playlist def main(): # logging.basicConfig(level=logging.DEBUG,) logging.basicConfig(level=logging.INFO,) # time constants now=datetime.datetime.now() for hour in (0,3,6,9,12,15,18,21): now=now.replace(hour=hour) print() print("Runnig for date: ",now) # get the playlists of my insterest pla=gest_playlist(now,minelab) # I do a list for playlist in pla.get_playlist(): print("--------------------------------") print("found schedule: ",playlist) print(playlist.ar_filename) print(playlist.ar_url) print(playlist.ar_scheduledatetime) print(playlist.ar_length) print("playlist",playlist.playlist) #.program.get_file_filename() print("--------------------------------") if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/gest_program.py000066400000000000000000000114131454362722700225450ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2009 Paolo Patruno. import os os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' from django.conf import settings import logging from datetime import * from .autoradio_config import * from .programs.models import Schedule from .programs.models import ScheduleDone from .programs.models import Show from .programs.models import Configure # to get metadata from audio files import mutagen import os class gest_program: def __init__ (self,now,minelab): """init of program application: now : current datetime minelab: minutes to elaborate execute the right data retrival to get the schedued programs""" self.now = now self.minelab = minelab ora=self.now.time() self.schedules=() datesched_min=self.now - timedelta( seconds=60*self.minelab) datesched_max=self.now + timedelta( milliseconds=60000*self.minelab-1) # 1 millisecond tollerance timesched_min=datesched_min.time() timesched_max=datesched_max.time() logging.debug( "PROGRAM: elaborate from %s to %s",datesched_min,datesched_max) if (Configure.objects.filter(active__exact=False).count() == 1): self.schedules=() return #todo: the use of ora here is not exact if (Configure.objects.filter(emission_starttime__gt=ora).count() == 1) : self.schedules=() return if (Configure.objects.filter(emission_endtime__lt=ora).count() == 1): self.schedules=() return # estraggo i record di mio interesse self.schedules=Schedule.objects.select_related()\ .filter(emission_date__gte=datesched_min)\ .filter(emission_date__lte=datesched_max)\ .filter(episode__active__exact=True)\ .order_by('emission_date') # .filter(emission_done__isnull=True).order_by('emission_date') def get_program(self): "iterate to get program" for schedule in self.schedules: # logging.debug("PROGRAM: %s %s %s", programma.program.file , ' --> '\ # , programma.emission_date.isoformat()) logging.debug("PROGRAM: %s %s %s", schedule.episode , ' --> '\ , schedule.emission_date.isoformat()) firth=True for enclosure in schedule.episode.enclosure_set.order_by('id'): logging.debug("PROGRAM: files: %s", enclosure.file.path) ar_filename=enclosure.file.path ar_url=enclosure.file.url ar_title=schedule.episode.show.title+" / "\ +schedule.episode.title+" / "\ +enclosure.title query=ScheduleDone.objects.filter(enclosure=enclosure,schedule=schedule) if query: scheduledone=query.all()[0] else: #create new entry in table if necessary scheduledone=ScheduleDone(schedule=schedule,enclosure=enclosure) scheduledone.save() ar_emission_done=scheduledone.emission_done # calcolo la lunghezza del programma try: ar_length=mutagen.File(ar_filename).info.length logging.debug("PROGRAM: elaborate time length: %s",ar_length) except: logging.error("PROGRAM: error establish time length; use an estimation %s", ar_filename) ar_length=3600 # the schedule time is postponed every enclosure if firth: ar_scheduledatetime=schedule.emission_date lengthold=ar_length firth=False else: ar_scheduledatetime+=timedelta(seconds=lengthold) lengthold=ar_length programma=scheduledone programma.ar_filename=ar_filename programma.ar_url=ar_url programma.ar_length=ar_length programma.ar_title=ar_title programma.ar_emission_done=ar_emission_done programma.ar_scheduledatetime=ar_scheduledatetime yield programma def main(): logging.basicConfig(level=logging.DEBUG,) # time constants now=datetime.now() #select the programs pro=gest_program(now,minelab) # do a list for programma in pro.get_program(): #pass print(programma.ar_filename) print(programma.ar_url) print(programma.ar_scheduledatetime) print(programma.ar_length) #programma.program.get_file_filename() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/gest_spot.py000066400000000000000000000222751454362722700220730ustar00rootroot00000000000000#!/usr/bin/env python # This Python file uses the following encoding: utf-8 # GPL. (C) 2007-2009 Paolo Patruno. import os, sys os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings' from django.conf import settings import logging import datetime from .autoradio_config import * from django.db.models import Q from .spots.models import Configure from .spots.models import Spot from .spots.models import Fascia from .spots.models import Giorno import time #used to get metadata from audio files import mutagen import tempfile,shutil class gest_spot(object): def __init__ (self,now,minelab,playlistdir): """init of spot application: now : currenti datetime minelab: minutes to elaborate execute the right data retrival to get the schedued spots""" import calendar playlistpath=os.path.join(settings.MEDIA_ROOT, playlistdir) try: # Create the date-based directory if it doesn't exist. os.makedirs(playlistpath) except OSError: # Directory probably already exists. pass self.now=now self.minelab=minelab self.playlistpath=playlistpath ora=self.now.time() self.oggi=self.now.date() self.giorno=calendar.day_name[self.now.weekday()] datesched_min=self.now - datetime.timedelta( seconds=60*self.minelab) datesched_max=self.now + datetime.timedelta( milliseconds=60000*self.minelab-1) # 1 millisec tollerance logging.debug( "SPOT: elaborate from %s to %s",datesched_min, datesched_max) timesched_min=datesched_min.time() timesched_max=datesched_max.time() logging.debug( "SPOT: elaborate from %s to %s",timesched_min, timesched_max) if (Configure.objects.filter(active__exact=False).count() == 1): self.fasce=() return #todo: the use of ora here is not exact if (Configure.objects.filter(emission_starttime__gt=ora).count() == 1) : self.fasce=() return if (Configure.objects.filter(emission_endtime__lt=ora).count() == 1): self.fasce=() return if (timesched_min < timesched_max): self.fasce=Fascia.objects.filter(\ Q(emission_time__gte=timesched_min),Q( emission_time__lte=timesched_max),\ Q(active__exact = True)).order_by('emission_time') else: # here we are around midnight self.fasce=Fascia.objects.filter(\ Q(emission_time__gte=timesched_min)|Q( emission_time__lte=timesched_max),\ Q(active__exact = True)).order_by('emission_time') def get_fasce(self,genfile=True): for fascia in self.fasce: self.fascia=fascia # count the spots self.ar_spots_in_fascia=self.count_spots() self.ar_filename,self.ar_url=self.get_fascia_playlist_media(genfile) self.ar_scheduledatetime=datetime.datetime.combine(self.oggi, fascia.emission_time) # if we are around midnight we have to check the correct date (today, iesterday, tomorrow) datesched_min=self.now - datetime.timedelta( seconds=60*self.minelab) datesched_max=self.now + datetime.timedelta( seconds=60*self.minelab) if not (datesched_min <= self.ar_scheduledatetime and self.ar_scheduledatetime <= datesched_max ): if self.now.time() < datetime.time(12): self.ar_scheduledatetime=datetime.datetime.combine(datesched_min.date(), fascia.emission_time) else: self.ar_scheduledatetime=datetime.datetime.combine(datesched_max.date(), fascia.emission_time) self.ar_emission_done=fascia.emission_done yield fascia def get_prologhi(self): prologhi= self.fascia.spot_set.filter(Q(start_date__lte=self.now) | Q(start_date__isnull=True),\ Q(end_date__gte=self.now) | Q(end_date__isnull=True),\ Q(giorni__name__exact=self.giorno) , Q(prologo__exact=True)).order_by('priorita') for prologo in prologhi: logging.debug( 'SPOT: prologo: %s',prologo) yield prologo def count_spots(self): return self.fascia.spot_set.filter(Q(start_date__lte=self.now) | Q(start_date__isnull=True),\ Q(end_date__gte=self.now) | Q(end_date__isnull=True),\ Q(giorni__name__exact=self.giorno)).exclude(prologo__exact=True)\ .exclude(epilogo__exact=True).count() def get_spots(self): spots=self.fascia.spot_set.filter(Q(start_date__lte=self.now) | Q(start_date__isnull=True),\ Q(end_date__gte=self.now) | Q(end_date__isnull=True),\ Q(giorni__name__exact=self.giorno)).exclude(prologo__exact=True)\ .exclude(epilogo__exact=True).order_by('priorita') for spot in spots: logging.debug('SPOT: spot: %s',spot) yield spot def get_epiloghi(self): epiloghi=self.fascia.spot_set.filter(Q(start_date__lte=self.now) | Q(start_date__isnull=True),\ Q(end_date__gte=self.now) | Q(end_date__isnull=True),\ Q(giorni__name__exact=self.giorno) , Q(epilogo__exact=True)).order_by('priorita') for epilogo in epiloghi: logging.debug ('SPOT: epilogo: %s',epilogo) yield epilogo def get_fascia_spots(self): if (self.ar_spots_in_fascia == 0): # I have found an empty fascia return for prologo in self.get_prologhi(): yield prologo for spot in self.get_spots(): yield spot for epilogo in self.get_epiloghi(): yield epilogo def get_fascia_playlist_media(self,genfile=True): name=self.fascia.name+".m3u" url=os.path.join(os.path.join(settings.MEDIA_URL, playlistdir),name) playlistname =os.path.join(self.playlistpath,name) if genfile : # os.umask(002) # f = open(playlistname, "w") fd,tmpfile=tempfile.mkstemp() f=os.fdopen(fd,"w") # f = open(tmpfile, "w") # f=tempfile.TemporaryFile() length=0 for spot in self.get_fascia_spots(): filename=spot.file.path # filename=spot.get_file_filename() #print >>f, os.path.basename(filename) logging.debug( "SPOT: include %s", filename) if genfile : # this work if LANG is set #f.write(os.path.basename(filename.encode(sys.getfilesystemencoding()))) #f.write(os.path.basename(filename.encode("UTF-8"))) f.write(filename) f.write("\n") # calcolo la lunghezza della fascia try: onelength=mutagen.File(filename).info.length logging.debug("SPOT: computed the partial time length: %d",onelength) length=length+onelength except: logging.error( "SPOT: error establish time length; use an estimation %s", filename) length=length+30 self.ar_length=length logging.debug("SPOT: computed total time length: %d",self.ar_length) if genfile : f.close() os.chmod(tmpfile,0o644) #sometime I get: #shutil.move(tmpfile,playlistname) #File "/usr/lib64/python2.7/shutil.py", line 301, in move #copy2(src, real_dst) #File "/usr/lib64/python2.7/shutil.py", line 130, in copy2 #copyfile(src, dst) #File "/usr/lib64/python2.7/shutil.py", line 83, in copyfile #with open(dst, 'wb') as fdst: # IOError: [Errno 11] Risorsa temporaneamente non disponibile: u'/home/autoradio/media/pubblicita/ore 13.30.m3u' # so I try to do it in a delayed loop ntry=0 while True: try: shutil.move(tmpfile,playlistname) logging.debug("SPOT: moved the playlist %s in %s",tmpfile,playlistname) break except: logging.warning("SPOT: error moving the playlist %s in %s",tmpfile,playlistname) ntry +=1 if ntry > 5: logging.error("SPOT: cannot move the playlist %s in %s",tmpfile,playlistname) break time.sleep(1) return playlistname,url def main(): logging.basicConfig(level=logging.DEBUG,) now=datetime.datetime.now() spots=gest_spot(now,minelab,"/tmp/") for fascia in spots.get_fasce(genfile=True): #print "elaborate fascia >>",fascia for spot in spots.get_fascia_spots(): pass #print "fascia and spot ->",spots.fascia,spot print(spots.ar_filename) print(spots.ar_scheduledatetime) print(spots.ar_length) print(spots.ar_spots_in_fascia) if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/jingles/000077500000000000000000000000001454362722700211355ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/jingles/__init__.py000066400000000000000000000000001454362722700232340ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/jingles/admin.py000066400000000000000000000054161454362722700226050ustar00rootroot00000000000000 from .models import Giorno, Configure, Jingle from django.contrib import admin from django import forms from django.utils.translation import ugettext_lazy import autoradio.settings import magic import autoradio.mime ma = magic.open(magic.MAGIC_MIME_TYPE) ma.load() class MyJingleAdminForm(forms.ModelForm): """ Check file if it is a known media file. """ class Meta(object): model = Jingle fields = '__all__' def clean_file(self): import mutagen, os file = self.cleaned_data.get('file',False) if file: #if file._size > 40*1024*1024: # raise forms.ValidationError("Audio file too large ( > 4mb )") try: type = file.content_type in webmime_audio except: return file if not type: raise forms.ValidationError(ugettext_lazy("Content-Type is not audio/mpeg or audio/flac or video/ogg")) if not os.path.splitext(file.name)[1] in websuffix_audio: raise forms.ValidationError(ugettext_lazy("Doesn't have proper extension: .mp3, .wav, .ogg, .oga, .flac")) try: mime = ma.file(file.temporary_file_path()) audio = mime in mymime_audio except: audio=False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file")) if autoradio.settings.require_tags_in_enclosure: #Check file if it is a known media file. The check is based on mutagen file test. try: audio = not (mutagen.File(file.temporary_file_path()) is None) except: audio = False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file: probably no tags present")) return file else: raise forms.ValidationError(ugettext_lazy("Couldn't read uploaded file")) class GiornoAdmin(admin.ModelAdmin): search_fields = ['name'] admin.site.register(Giorno, GiornoAdmin) class ConfigureAdmin(admin.ModelAdmin): list_display = ('sezione','active','emission_freq',) admin.site.register(Configure, ConfigureAdmin) class JingleAdmin(admin.ModelAdmin): fieldsets = ( (None, {'fields': ('jingle','file','rec_date','active')}), ('Emission information', {'fields': ('start_date','end_date','start_time','end_time','giorni','priorita')}), ) list_display = ('jingle','file','rec_date','emission_done','active') list_filter = ['active','start_date','end_date','start_time','end_time','rec_date','giorni'] date_hierarchy = 'rec_date' search_fields = ['jingle','file'] form = MyJingleAdminForm admin.site.register(Jingle, JingleAdmin) autoradio-autoradio-3.6-4/autoradio/jingles/migrations/000077500000000000000000000000001454362722700233115ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/jingles/migrations/0001_initial.py000066400000000000000000000063441454362722700257630ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9 on 2016-01-25 17:57 import autoradio.jingles.models from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Configure', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('sezione', models.CharField(default=b'jingle', editable=False, max_length=50, unique=True)), ('active', models.BooleanField(default=True, help_text='activate/deactivate the intere jingle class', verbose_name='Activate Jingle')), ('emission_freq', models.TimeField(verbose_name='Frequency')), ], ), migrations.CreateModel( name='Giorno', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(choices=[('luned\xec', 'luned\xec'), ('marted\xec', 'marted\xec'), ('mercoled\xec', 'mercoled\xec'), ('gioved\xec', 'gioved\xec'), ('venerd\xec', 'venerd\xec'), ('sabato', 'sabato'), ('domenica', 'domenica')], help_text='weekday name', max_length=20, unique=True)), ], ), migrations.CreateModel( name='Jingle', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('jingle', models.CharField(max_length=80, unique=True, verbose_name='Jingle name')), ('file', autoradio.jingles.models.DeletingFileField(help_text='The jingle file to upload', max_length=255, upload_to=b'jingles', verbose_name='File')), ('rec_date', models.DateTimeField(help_text='When the jingle was done (for reference only)', verbose_name='Recording date')), ('active', models.BooleanField(default=True, help_text='Activate the jingle for emission', verbose_name='Active')), ('start_date', models.DateField(blank=True, help_text='The jingle will be scheduled starting from this date', null=True, verbose_name='Emission starting date')), ('end_date', models.DateField(blank=True, help_text='The jingle will be scheduled ending this date', null=True, verbose_name='Emission end date')), ('start_time', models.TimeField(blank=True, help_text='The jingle will be scheduled starting from this date', null=True, verbose_name='Emission start time')), ('end_time', models.TimeField(blank=True, help_text='The jingle will be scheduled ending this date', null=True, verbose_name='Emission end time')), ('priorita', models.IntegerField(default=50, help_text='When there are more jingle that wait for emission from the same time, the emission will be ordered by this numer', verbose_name='Priority')), ('emission_done', models.DateTimeField(editable=False, null=True, verbose_name='emission done')), ('giorni', models.ManyToManyField(blank=True, help_text='The jingle will be scheduled those weekdays', to='jingles.Giorno', verbose_name='Scheduled days')), ], ), ] autoradio-autoradio-3.6-4/autoradio/jingles/migrations/0002_auto_20180721_1059.py000066400000000000000000000012751454362722700267430ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.10.5 on 2018-07-21 10:59 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('jingles', '0001_initial'), ] operations = [ migrations.AlterField( model_name='giorno', name='name', field=models.CharField(choices=[(b'luned\xc3\xac', b'luned\xc3\xac'), (b'marted\xc3\xac', b'marted\xc3\xac'), (b'mercoled\xc3\xac', b'mercoled\xc3\xac'), (b'gioved\xc3\xac', b'gioved\xc3\xac'), (b'venerd\xc3\xac', b'venerd\xc3\xac'), (b'sabato', b'sabato'), (b'domenica', b'domenica')], help_text='weekday name', max_length=20, unique=True), ), ] autoradio-autoradio-3.6-4/autoradio/jingles/migrations/__init__.py000066400000000000000000000000001454362722700254100ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/jingles/models.py000066400000000000000000000123731454362722700230000ustar00rootroot00000000000000from django.db import models from django.utils.translation import ugettext_lazy import calendar from autoradio.autoradio_config import * from django import VERSION as djversion if ((djversion[0] == 1 and djversion[1] >= 3) or djversion[0] > 1): from django.db import models from django.db.models import signals class DeletingFileField(models.FileField): """ FileField subclass that deletes the refernced file when the model object itself is deleted. WARNING: Be careful using this class - it can cause data loss! This class makes at attempt to see if the file's referenced elsewhere, but it can get it wrong in any number of cases. """ def contribute_to_class(self, cls, name): super(DeletingFileField, self).contribute_to_class(cls, name) signals.post_delete.connect(self.delete_file, sender=cls) def delete_file(self, instance, sender, **kwargs): file = getattr(instance, self.attname) # If no other object of this type references the file, # and it's not the default value for future objects, # delete it from the backend. if file and file.name != self.default and \ not sender._default_manager.filter(**{self.name: file.name}): file.delete(save=False) elif file: # Otherwise, just close the file, so it doesn't tie up resources. file.close() else: DeletingFileField=models.FileField def giorno_giorno(): giorni=[] for giorno in (calendar.day_name): #giorno=giorno.decode('utf-8') giorni.append(( giorno, giorno)) return giorni # yield 'Tutti','Tutti' class Giorno(models.Model): name = models.CharField(max_length=20,choices=giorno_giorno(),unique=True,\ help_text=ugettext_lazy("weekday name")) def __str__(self): return self.name class Admin(object): search_fields = ['name'] class Configure(models.Model): sezione = models.CharField(max_length=50,unique=True,default='jingle',editable=False) active = models.BooleanField(ugettext_lazy("Activate Jingle"),default=True, help_text=ugettext_lazy("activate/deactivate the intere jingle class")) emission_freq = models.TimeField(ugettext_lazy('Frequency')) def __str__(self): return self.sezione+" "+self.active.__str__()+" "+self.emission_freq.isoformat() class Admin(object): list_display = ('sezione','active','emission_freq',) class Jingle(models.Model): jingle = models.CharField(ugettext_lazy("Jingle name"),max_length=80,unique=True) file = DeletingFileField(ugettext_lazy('File'),upload_to='jingles',max_length=255,\ help_text=ugettext_lazy("The jingle file to upload")) rec_date = models.DateTimeField(ugettext_lazy('Recording date'),\ help_text=ugettext_lazy("When the jingle was done (for reference only)")) active = models.BooleanField(ugettext_lazy("Active"),default=True,\ help_text=ugettext_lazy("Activate the jingle for emission")) start_date = models.DateField(ugettext_lazy('Emission starting date'),null=True,blank=True,\ help_text=ugettext_lazy("The jingle will be scheduled starting from this date")) end_date = models.DateField(ugettext_lazy('Emission end date'),null=True,blank=True,\ help_text=ugettext_lazy("The jingle will be scheduled ending this date")) start_time = models.TimeField(ugettext_lazy('Emission start time'),null=True,blank=True,\ help_text=ugettext_lazy("The jingle will be scheduled starting from this date")) end_time = models.TimeField(ugettext_lazy('Emission end time'),null=True,blank=True,\ help_text=ugettext_lazy("The jingle will be scheduled ending this date")) giorni = models.ManyToManyField(Giorno,verbose_name=ugettext_lazy('Scheduled days'),blank=True,\ help_text=ugettext_lazy("The jingle will be scheduled those weekdays")) priorita = models.IntegerField(ugettext_lazy("Priority"),default=50,\ help_text=ugettext_lazy("When there are more jingle that wait for emission from the same time, the emission will be ordered by this numer")) emission_done = models.DateTimeField(ugettext_lazy('emission done'),null=True,editable=False ) def was_recorded_today(self): return self.rec_date.date() == datetime.date.today() was_recorded_today.short_description = ugettext_lazy('Recorded today?') def __str__(self): return self.jingle class Admin(object): fields = ( (None, {'fields': ('jingle','file','rec_date','active')}), ('Emission information', {'fields': ('start_date','end_date','start_time','end_time','giorni','priorita')}), ) list_display = ('jingle','file','rec_date','emission_done') list_filter = ['start_date','end_date','start_time','end_time','giorni'] date_hierarchy = 'rec_date' search_fields = ['jingle'] #class Meta: # unique_together = ("prologo", "epilogo","fasce") autoradio-autoradio-3.6-4/autoradio/jingles/urls.py000066400000000000000000000003171454362722700224750ustar00rootroot00000000000000from django.conf.urls.defaults import * #from models import Fascia, Spot # #urlpatterns = patterns('', # (r'^$', 'programs.views.index'), # (r'^/schedule/(?P\d+)/$', 'views.detail'), # #) autoradio-autoradio-3.6-4/autoradio/jingles/views.py000066400000000000000000000000321454362722700226370ustar00rootroot00000000000000# Create your views here. autoradio-autoradio-3.6-4/autoradio/manageamarok.py000066400000000000000000000141071454362722700225020ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007 Paolo Patruno. import logging from qt import * import dcopext from kdecore import * from datetime import * from threading import * def ar_emitted(self): self.emission_done=datetime.now() self.save() def KdeInit(): "inizializzo kde" aboutdata = KAboutData("AutoAmarok","Autoamarok","1.0", "Amarok radio station", KAboutData.License_GPL, "Copyright (C) 2007 Paolo Patruno") KCmdLineArgs.init(aboutdata) return KApplication () class Kde: def __init__ (self,kapp): "init of kde application" self.dcopclient = kapp.dcopClient() def connect(self,application): "connetto with kde application" self.dcopapplication = dcopext.DCOPApp(application, self.dcopclient) class ScheduleProgram: def __init__ (self,kapp,function,operation,media,scheduledatetime,programma): "init schedule" self.kapp=kapp self.function=function self.operation=operation self.media=media self.scheduledatetime=scheduledatetime self.programma=programma scheduledatetime #print "differenza ",datetime.now(),self.scheduledatetime delta=( self.scheduledatetime - datetime.now()) #print delta #self.deltasec=max(secondi(delta),1) self.deltasec=secondi(delta) self.deltasec self.timer = Timer(self.deltasec, self.function, [self.kapp,self.operation,self.media,self.programma]) def start (self): "start of programmed schedule" #self.function (self.kde,self.media) self.timer.start() def ManageAmarok (kapp,operation,media,programma): "Manage amarok to do operation on media" kde=Kde(kapp) kde.connect("amarok") logging.info( "kde operation: %s",operation) if ( operation == "queueMedia"): # ok,result = kde.dcopapplication.playlist.adjustDynamicPrevious() # print "kde.dcopapplication.playlist.adjustDynamicPrevious" # print 'status is:',ok,result ok,result = kde.dcopapplication.playlist.queueMedia(KURL(media)) logging.info( "kde.dcopapplication.playlist.queueMedia %s",media) test_status(ok,result) ok,result = kde.dcopapplication.player.isPlaying() logging.info( "kde.dcopapplication.player.isPlaying") test_status(ok,result) if ( not result): ok,result = kde.dcopapplication.player.play() logging.info ("kde.dcopapplication.player.play") test_status(ok,result) elif (operation == "loadPlaylist"): ok,result = kde.dcopapplication.playlistbrowser.loadPlaylist(QString(media)) logging.info( "kde.dcopapplication.playlistbrowser.loadPlaylist %s",media) test_status(ok,result) ok,result = kde.dcopapplication.playlist.repopulate() logging.info( "kde.dcopapplication.playlistbrowser.repopulate") test_status(ok,result) ok,result = kde.dcopapplication.player.isPlaying() logging.info( "kde.dcopapplication.player.isPlaying") test_status(ok,result) if ( not result): ok,result = kde.dcopapplication.player.play() logging.info( "kde.dcopapplication.player.play") test_status(ok,result) if (ok): logging.info( "scrivo in django: %s",programma) ar_emitted(programma) logging.info( "scritto in django: %s",programma) def secondi(delta): secondi=delta.seconds # correggo i viaggi che si fa seconds if delta.days < 0 : secondi = secondi + (3600*24*delta.days) return secondi class dummy_programma: def __init__(self): pass def save(self): pass #print "faccio finta di salvarlo" def amarok_watchdog(kapp): try: kde=Kde(kapp) kde.connect("amarok") ok,result = kde.dcopapplication.playlist.getTotalTrackCount() logging.info( "kde.dcopapplication.playlist.getTotalTrackCount") except: ok=False result="error on kde.dcopapplication.playlist.getTotalTrackCount()" test_status(ok,result) if (result > 40 or result < 5 ): logging.error("Ho trovato troppa (poca) roba in playlist ! ci sono %s tracce",result) ok,result = kde.dcopapplication.playlist.saveM3u(QString("/tmp/autoradio.m3u"), False) logging.info( "kde.dcopapplication.playlist.saveM3u") test_status(ok,result) ok,result = kde.dcopapplication.playlist.repopulate() logging.info( "kde.dcopapplication.playlist.repopulate") test_status(ok,result) return ok def save_status(kapp): kde=Kde(kapp) kde.connect("amarok") ok,result = kde.dcopapplication.playlist.saveCurrentPlaylist() logging.info ( "kde.dcopapplication.playlist.saveCurrentPlaylist") test_status(ok,result) return ok def test_status( ok,result): # print ok,result if (ok == True): logging.info( "status is: %s result: %s",ok,str(result)) else: logging.error( "status is: %s result: %s",ok,str(result)) def main(): kapp=KdeInit() programma=dummy_programma() function=ManageAmarok operation="queueMedia" media = "/home/pat1/Musica/mp3/goran_bregovic/ederlezi/talijanska.mp3" #media = raw_input("dammi il media? ") scheduledatetime=datetime.now()+timedelta(seconds=15) schedule=ScheduleProgram(kapp,function,operation,media,scheduledatetime,programma) schedule.start() scheduledatetime=datetime.now()+timedelta(seconds=30) media = "/home/pat1/Musica/mp3/goran_bregovic/ederlezi/underground_tango.mp3" schedule=ScheduleProgram(kapp,function,operation,media,scheduledatetime,programma) schedule.start() scheduledatetime=datetime.now()+timedelta(seconds=45) media = "/home/pat1/Musica/mp3/goran_bregovic/ederlezi/lullabye.mp3" schedule=ScheduleProgram(kapp,function,operation,media,scheduledatetime,programma) schedule.start() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/manageaudacious.py000066400000000000000000000164661454362722700232170ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007 Paolo Patruno. import logging import dbus from . import autoaudacious from datetime import * from threading import * from django.conf import settings import os from . import autoradio_config class AudaciousError(Exception): def __str__(self): return repr(self.args[0]) def shuffle_playlist(infile,shuffle=False,relative_path=False,length=None): from . import mkplaylist import os,random,tempfile,codecs media_files=list(mkplaylist.read_playlist(infile, not relative_path)) if shuffle: random.shuffle(media_files) # else: # media_files.sort() fd,outfile=tempfile.mkstemp(".m3u") #ffoutfile = os.fdopen(fd,"w") foutfile = codecs.open(outfile, "w", encoding="UTF-8") mkplaylist.write_extm3u(media_files, foutfile,length) foutfile.close() os.close(fd) return outfile lock = Lock() def ar_emitted(self): ''' Save in django datatime when emission is done ''' self.emission_done=datetime.now() self.save() class ScheduleProgram(object): ''' activate a schedule setting it for a time in the future ''' def __init__ (self,session,schedule): "init schedule" self.deltasec=secondi( schedule.scheduledatetime - datetime.now()) self.session=session self.function=ManageAudacious self.schedule=schedule self.timer = Timer(self.deltasec, self.function,[self.session,self.schedule]) def start (self): "start of programmed schedule" self.timer.start() def ManageAudacious (session,schedule): "Manage audacious to do operation on media" try: if ( schedule.type == "spot" ): operation="queueMedia" elif ( schedule.type == "program" ): operation="queueMedia" elif ( schedule.type == "jingle" ): operation="queueMedia" elif ( schedule.type == "playlist" ): operation="loadPlaylist" else: raise AudaciousError("ManageAudacious: type not supported: %s"% schedule.type) if operation == "loadPlaylist": media=shuffle_playlist(schedule.filename,schedule.shuffle,relative_path=False,length=schedule.maxlength) else: media=schedule.filename aud=autoaudacious.audacious() # Regione critica lock.acquire() try: if not aud.playlist_clear_up(atlast=10): raise AudaciousError("ManageAudacious: ERROR in playlist_clear_up") #print settings.MEDIA_ROOT #pos=aud.get_playlist_posauto(autopath=settings.MEDIA_ROOT,securesec=10) pos=aud.get_playlist_posauto(autopath="/cacca",securesec=10) curpos=aud.get_playlist_pos() # inserisco il file nella playlist if pos is None: raise AudaciousError("ManageXmms: ERROR in xmms.control.get_playlist_posauto") logging.info( "ManageXmms: insert media: %s at position %d",media,pos) aud.org.PlaylistInsUrlString("file://"+media,pos) # recheck for consistency newpos=aud.get_playlist_pos() if curpos != newpos: raise AudaciousError("Manageaudacious: strange ERROR: consinstency problem; pos: %d , newpos: %d"% (curpos,newpos)) if not aud.playlist_clear_down(atlast=500): raise AudaciousError("ManageAudacious: ERROR in playlist_clear_down") finally: #signal.alarm(0) lock.release() if schedule.shuffle: os.remove(media) logging.info( "ManageAudacious: write in django: %s",schedule.djobj) ar_emitted(schedule.djobj) logging.info( "ManageAudacious: write in django: %s",schedule.djobj) except AudaciousError as e: logging.error(e) return aud.play_ifnot() def secondi(delta): secondi=float(delta.seconds) secondi=secondi+(delta.microseconds/100000.) if delta.days < 0 : secondi = secondi + (3600*24*delta.days) return secondi class dummy_programma(object): def __init__(self): pass def save(self): #print "masquerade as we save it" pass def audacious_watchdog(session): from distutils.version import LooseVersion reqversion=LooseVersion("1.5") version=LooseVersion("0.0") logging.debug( "audacious_watchdog: test if audacious is running" ) try: aud=autoaudacious.audacious() except: logging.error("audacious_watchdog: audacious is not running or error on is_running") import subprocess try: logging.info("audacious_watchdog: try launching audacious") subprocess.Popen("audacious" , shell=True) except: logging.error("audacious_watchdog: error launching audacious") try: logging.info("audacious_watchdog: try launching audacious2") subprocess.Popen("audacious2" , shell=True) except: logging.error("audacious_watchdog: error launching audacious2") import time time.sleep(5) logging.info("audacious_watchdog: launch_audacious") aud=autoaudacious.audacious() try: aud=autoaudacious.audacious() except: logging.error("audacious_watchdog: audacious2 not started: try with audacious") import subprocess subprocess.Popen("audacious" , shell=True) import time time.sleep(5) logging.info("audacious_watchdog: launch_audacious") aud=autoaudacious.audacious() try: # aud.root.Identity() version=LooseVersion(aud.org.Version()) logging.info("audacious_watchdog: audacious version: %s" % str(version)) except: logging.error("audacious_watchdog: eror gettin audacious version") return True if ( version < reqversion ): logging.error("audacious_watchdog: audacious %s version is wrong (>=1.5) " % version ) raise Exception aud.play_ifnot() logging.debug("audacious_watchdog: audacious start playing if not") return True def save_status(session): """ Do nothing """ logging.debug ( "DUMMY xmms.saveCurrentPlaylist") return True def main(): from . import autoradio_core programma=dummy_programma() audacious_watchdog(0) session=0 shuffle=False maxlength=None type="program" media = "/home/pat1/tmp/pippo.mp3" #media = "/home/pat1/Musica/STOP AL PANICO/ISOLA POSSE STOP AL PANICO.mp3" #media = "/home/autoradio/django/media/playlist/tappeto_musicale.m3u" #media = raw_input("dammi il media? ") scheduledatetime=datetime.now()+timedelta(seconds=5) sched=autoradio_core.schedule(programma,scheduledatetime,media,filename=media,type=type,shuffle=shuffle,maxlength=maxlength) threadschedule=ScheduleProgram(session,sched) threadschedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=8) # media = "/home/autoradio/django/media/programs/borsellino_giordano.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=10) # media = "/home/autoradio/django/media/programs/mister_follow_follow.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/managempris.py000066400000000000000000000204111454362722700223550ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007-2012 Paolo Patruno. import logging import dbus from . import autompris from . import autompris2 from datetime import * from threading import * import os from . import autoradio_config import traceback os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.conf import settings class PlayerError(Exception): def __str__(self): return repr(self.args[0]) def shuffle_playlist(infile,shuffle=False,relative_path=False,length=None): from . import mkplaylist import os,random,tempfile,codecs media_files=list(mkplaylist.read_playlist(infile, not relative_path)) if shuffle: random.shuffle(media_files) # else: # media_files.sort() fd,outfile=tempfile.mkstemp(".m3u") #ffoutfile = os.fdopen(fd,"w") foutfile = codecs.open(outfile, "w", encoding="UTF-8") mkplaylist.write_extm3u(media_files, foutfile,length) foutfile.close() os.close(fd) return outfile lock = Lock() def ar_emitted(self): ''' Save in django datatime when emission is done ''' self.emission_done=datetime.now() self.save() class ScheduleProgram(object): ''' activate a schedule setting it for a time in the future ''' def __init__ (self,player,session,schedule): "init schedule" self.deltasec=secondi( schedule.scheduledatetime - datetime.now()) # round to nearest future if self.deltasec < 5 : self.deltasec = 5 self.player=player self.session=session self.function=ManagePlayer self.schedule=schedule self.timer = Timer(self.deltasec, self.function,[self.player,self.session,self.schedule]) def start (self): "start of programmed schedule" # A thread can be flagged as a "daemon thread". # The significance of this flag is that the entire Python program # exits when only daemon threads are left. # The initial value is inherited from the creating thread. # The flag can be set through the daemon property. self.timer.daemon=True self.timer.start() def cancel (self): "cancel programmed schedule" self.timer.cancel() def ManagePlayer (player,session,schedule): "Manage player to do operation on media" try: if ( schedule.type == "spot" ): operation="queueMedia" elif ( schedule.type == "program" ): operation="queueMedia" elif ( schedule.type == "jingle" ): operation="queueMedia" elif ( schedule.type == "playlist" ): operation="loadPlaylist" else: raise PlayerError("Managempris: type not supported: %s"% schedule.type) try: if operation == "loadPlaylist": media=shuffle_playlist(schedule.filename,schedule.shuffle,relative_path=False,length=schedule.maxlength) else: media=schedule.filename if player == "vlc" or player == "AutoPlayer": aud = autompris2.mediaplayer(player=player,session=session) else: aud = autompris.mediaplayer(player=player,session=session) except: raise PlayerError("Managempris: error connecting to player dbus") # Regione critica lock.acquire() try: if not aud.playlist_clear_up(atlast=10): raise PlayerError("Managempris: ERROR in playlist_clear_up") #print settings.MEDIA_ROOT pos=aud.get_playlist_posauto(autopath=settings.MEDIA_ROOT,securesec=20) curpos=aud.get_playlist_pos() # inserisco il file nella playlist if pos is None: raise PlayerError("Managempris: ERROR in xmms.control.get_playlist_posauto") logging.info( "Managempris: insert media: %s at position %d",media,pos) aud.playlist_add_atpos("file://"+media,pos) # recheck for consistency newpos=aud.get_playlist_pos() if curpos != newpos: raise PlayerError("Managempris: strange ERROR: consinstency problem; pos: %s , newpos: %s"% (str(curpos),str(newpos))) if not aud.playlist_clear_down(atlast=500): raise PlayerError("Managempris: ERROR in playlist_clear_down") finally: #signal.alarm(0) lock.release() # here we have a problem ... sometime the player is not ready when the file is deleted ! # so we comment it out # if schedule.shuffle: # os.remove(media) logging.info( "Managempris: write in django: %s",schedule.djobj) ar_emitted(schedule.djobj) logging.info( "Managempris: written in django: %s",schedule.djobj) aud.play_ifnot() except PlayerError as e: logging.error(e) except dbus.DBusException as e: logging.error(e) except: logging.error("generic error in ManagePlayer") traceback.print_exc() return def secondi(delta): secondi=float(delta.seconds) secondi=secondi+(delta.microseconds/100000.) if delta.days < 0 : secondi = secondi + (3600*24*delta.days) return secondi class dummy_programma(object): def __init__(self): pass def save(self): #print "masquerade as we save it" pass def player_watchdog(player,session): logging.debug( "player_watchdog: test if player is running" ) try: if player == "vlc" or player == "AutoPlayer": aud = autompris2.mediaplayer(player=player,session=session) else: aud = autompris.mediaplayer(player=player,session=session) except: logging.error("player_watchdog: player do not communicate on d-bus") if player == "audacious" or player == "xmms": import subprocess try: logging.info("player_watchdog: try launching player") subprocess.Popen(player , shell=True) except: logging.error("player_watchdog: error launching "+player) if player == "xmms": try: logging.info("player_watchdog: try launching "+player+"2") subprocess.Popen(player+"2" , shell=True) except: logging.error("player_watchdog: error launching "+player+"2") import time time.sleep(5) logging.info("player_watchdog: player executed") try: if player == "vlc" or player == "AutoPlayer": aud = autompris2.mediaplayer(player=player,session=session) else: aud = autompris.mediaplayer(player=player,session=session) except: logging.error("player_watchdog serious problem: player do not comunicate on d-bus") try: aud.play_ifnot() logging.debug("player_watchdog: start playing if not") except: logging.error("player_watchdog: cannot start playing if not") return True def save_status(session): """ Do nothing """ logging.debug ( "DUMMY xmms.saveCurrentPlaylist") return True def main(): from . import autoradio_core player="AutoPlayer" session=0 logging.getLogger('').setLevel(logging.DEBUG) programma=dummy_programma() player_watchdog(player=player,session=session) shuffle=False maxlength=None type="program" media = "/home/pat1/svn/autoradio/trunk/media/pippo.mp3" #media = "/home/pat1/Musica/STOP AL PANICO/ISOLA POSSE STOP AL PANICO.mp3" #media = "/home/autoradio/django/media/playlist/tappeto_musicale.m3u" #media = raw_input("dammi il media? ") scheduledatetime=datetime.now()+timedelta(seconds=5) sched=autoradio_core.schedule(programma,scheduledatetime,media,filename=media,type=type,shuffle=shuffle,maxlength=maxlength) threadschedule=ScheduleProgram(player,session,sched) threadschedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=8) # media = "/home/autoradio/django/media/programs/borsellino_giordano.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=10) # media = "/home/autoradio/django/media/programs/mister_follow_follow.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/managepytone.py000066400000000000000000000065211454362722700225470ustar00rootroot00000000000000import os,sys import events, network, requests, version, helper from datetime import * from threading import * def ar_emitted(self): self.emission_done=datetime.now() self.save() class ScheduleProgram(object): def __init__ (self,function,operation,media,scheduledatetime,programma): "init schedule" self.function=function self.operation=operation self.media=media self.scheduledatetime=scheduledatetime self.programma=programma scheduledatetime print("differenza ",datetime.now(),self.scheduledatetime) delta=( self.scheduledatetime - datetime.now()) print(delta) #self.deltasec=max(secondi(delta),1) self.deltasec=secondi(delta) self.deltasec self.timer = Timer(self.deltasec, self.function, [self.operation,self.media,self.programma]) def start (self): "start of programmed schedule" self.timer.start() def ManagePytone (operation,media,programma): "Manage pytone to do operation on media" unixsocketfile = os.path.expanduser("~/.pytone/pytonectl") networklocation = unixsocketfile print(networklocation) try: channel = network.clientchannel(networklocation) except Exception as e: print("Error: cannot connect to PyTone server: %s" % e) sys.exit(2) channel.start() root,ext=os.path.splitext(media) if (ext == ".m3u"): medias=[] f = open(media, "r") for line in f.readlines(): medias.append(line[:-1]) f.close() else: medias=(media,) for mediasplit in medias: print("invio ->",mediasplit) if operation == "queueMedia": song = channel.request(\ requests.autoregisterer_queryregistersong("main", mediasplit)) channel.notify(events.playlistaddsongtop(song)) channel.quit() print("scrivo in django") print(programma) ar_emitted(programma) print("scritto in django") def secondi(delta): secondi=delta.seconds # correggo i viaggi che si fa seconds if delta.days < 0 : secondi = secondi + (3600*24*delta.days) return secondi class dummy_programma(object): def __init__(self): pass def save(self): print("faccio finta di salvarlo") def main(): programma=dummy_programma() function=ManagePytone operation="queueMedia" # media = "/home/pat1/django/autoradio/media/spots/spot-bibbiano.ogg" media="/home/pat1/django/autoradio/media/playlist/pomeridiana_ore_14_00.m3u" #media = raw_input("dammi il media? ") scheduledatetime=datetime.now()+timedelta(seconds=15) schedule=ScheduleProgram(function,operation,media,scheduledatetime,programma) schedule.start() scheduledatetime=datetime.now()+timedelta(seconds=100) media = "/home/pat1/django/autoradio/media/spots/spot-nocino.ogg" schedule=ScheduleProgram(function,operation,media,scheduledatetime,programma) schedule.start() scheduledatetime=datetime.now()+timedelta(seconds=200) media = "/home/pat1/django/autoradio/media/spots/spot-panedellamoni.ogg" schedule=ScheduleProgram(function,operation,media,scheduledatetime,programma) schedule.start() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/managexmms.py000066400000000000000000000167431454362722700222240ustar00rootroot00000000000000#!/usr/bin/env python # GPL. (C) 2007 Paolo Patruno. import logging import xmms,autoxmms from datetime import * from threading import * from django.conf import settings import os from . import autoradio_config #import signal class XmmsError(Exception): pass def shuffle_playlist(infile,shuffle=False,relative_path=False,length=None): from . import mkplaylist import os,random,tempfile,codecs media_files=list(mkplaylist.read_playlist(infile, not relative_path)) if shuffle: random.shuffle(media_files) # else: # media_files.sort() fd,outfile=tempfile.mkstemp(".m3u") #ffoutfile = os.fdopen(fd,"w") foutfile = codecs.open(outfile, "w", encoding="UTF-8") mkplaylist.write_extm3u(media_files, foutfile,length) foutfile.close() os.close(fd) return outfile lock = Lock() def ar_emitted(self): ''' Save in django datatime when emission is done ''' self.emission_done=datetime.now() self.save() class ScheduleProgram: ''' activate a schedule setting it for a time in the future ''' def __init__ (self,session,schedule): #session,function,operation, #media,scheduledatetime,programma,shuffle=None,length=None): "init schedule" #self.function=function #self.operation=operation #self.schedule=schedule #self.media=media #self.scheduledatetime=scheduledatetime #self.programma=programma #self.shuffle=shuffle #self.length=length #scheduledatetime #print "difference ",datetime.now(),self.scheduledatetime #self.deltasec=max(secondi( schedule.scheduledatetime - datetime.now()),1) self.deltasec=secondi( schedule.scheduledatetime - datetime.now()) self.session=session self.function=ManageXmms self.schedule=schedule self.timer = Timer(self.deltasec, self.function,[self.session,self.schedule]) # [self.session,self.operation,self.chedule # self.media,self.programma,self.shuffle,self.length]) def start (self): "start of programmed schedule" self.timer.start() def ManageXmms (session,schedule): "Manage xmms to do operation on media" try: if ( schedule.type == "spot" ): operation="queueMedia" elif ( schedule.type == "program" ): operation="queueMedia" elif ( schedule.type == "jingle" ): operation="queueMedia" elif ( schedule.type == "playlist" ): operation="loadPlaylist" else: raise XmmsError("ManageXmms: type not supported: %s"% schedule.type) media=schedule.media if operation == "loadPlaylist": media=shuffle_playlist(schedule.media,schedule.shuffle,relative_path=False,length=schedule.maxlength) # Regione critica lock.acquire() try: if not autoxmms.playlist_clear_up(atlast=10,session=session): raise XmmsError("ManageXmms: ERROR in xmms.control.playlist_clear_up") pos=autoxmms.get_playlist_posauto(autopath=settings.MEDIA_ROOT,securesec=10,session=session) curpos=xmms.control.get_playlist_pos(session) # inserisco il file nella playlist if pos is None: raise XmmsError("ManageXmms: ERROR in xmms.control.get_playlist_posauto") logging.info( "ManageXmms: insert media: %s at position %d",media,pos) xmms.control.playlist_ins_url_string(media,pos,session) #error test impossible # recheck for consistency newpos=xmms.control.get_playlist_pos(session) if curpos != newpos: raise XmmsError("ManageXmms: strange ERROR: consinstency problem; pos: %d , newpos: %d"% (curpos,newpos)) if not autoxmms.playlist_clear_down(atlast=500,session=session): raise XmmsError("ManageXmms: ERROR in xmms.control.playlist_clear_down") finally: #signal.alarm(0) lock.release() if schedule.shuffle: os.remove(media) logging.info( "ManageXmms: write in django: %s",schedule.djobj) ar_emitted(schedule.djobj) logging.info( "ManageXmms: write in django: %s",schedule.djobj) except XmmsError as e: logging.error(e.message) #except: # logging.error( "ManageXmms: ERRORE type: %s, media: %s",schedule.type,schedule.media) return autoxmms.play_ifnot(session=session) def secondi(delta): secondi=float(delta.seconds) secondi=secondi+(delta.microseconds/100000.) # correggo i viaggi che si fa seconds if delta.days < 0 : secondi = secondi + (3600*24*delta.days) return secondi class dummy_programma: def __init__(self): pass def save(self): #print "masquerade as we save it" pass def xmms_watchdog(session): logging.debug( "xmms_watchdog: test if xmms.is running" ) try: ok = xmms.control.is_running(session) logging.debug("xmms_watchdog: xmms.is_running return %s", str(ok)) except: ok=False logging.error("xmms_watchdog: error on xmms.is_running") if (not ok ): logging.error("xmms_watchdog: xmms is not running") try: xmms.control.enqueue_and_play_launch_if_session_not_started("file",session=session, stdout_to_dev_null=True, stderr_to_dev_null=True) ok=True logging.info("xmms_watchdog: pyxmms < 2.07 xmms.control.enqueue_and_play_launch_if_session_not_started") except: try: xmms.control.enqueue_and_play_launch_if_session_not_started("file",session=session) ok=True logging.info("xmms_watchdog: pyxmms >= 2.07 xmms.control.enqueue_and_play_launch_if_session_not_started") except: ok=False logging.error("xmms_watchdog: error xmms.control.enqueue_and_play_launch_if_session_not_started") return ok def save_status(session): # file dovra essere prima salvato usando: # xmms.get_playlist_length(session) (restituisce il numero di brani nella playlist # get_playlist_file(index, session=0) -> absolute filename (string) # get_playlist_pos(session=0) -> position (integer) logging.debug ( "DUMMY xmms.saveCurrentPlaylist") return True def main(): from . import autoradio_core programma=dummy_programma() session=0 shuffle=True maxlength=None type="playlist" media = "/home/autoradio/django/media/playlist/playlistmingogozza.m3u" #media = "/home/autoradio/django/media/playlist/tappeto_musicale.m3u" #media = raw_input("dammi il media? ") scheduledatetime=datetime.now()+timedelta(seconds=5) sched=autoradio_core.schedule(programma,scheduledatetime,media,type=type,shuffle=shuffle,maxlength=maxlength) threadschedule=ScheduleProgram(session,sched) threadschedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=8) # media = "/home/autoradio/django/media/programs/borsellino_giordano.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() # scheduledatetime=datetime.now()+timedelta(seconds=10) # media = "/home/autoradio/django/media/programs/mister_follow_follow.mp3" # schedule=ScheduleProgram(session,function,operation,media,scheduledatetime,programma,shuffle) # schedule.start() if __name__ == '__main__': main() # (this code was run as script) autoradio-autoradio-3.6-4/autoradio/mime.py000066400000000000000000000026441454362722700210110ustar00rootroot00000000000000 # audio/basic: mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046 # audio/L24: 24bit Linear PCM audio at 8-48kHz, 1-N channels; Defined in RFC 3190 # audio/mp4: MP4 audio # audio/mpeg: MP3 or other MPEG audio; Defined in RFC 3003 # audio/ogg: Ogg Vorbis, Speex, Flac and other audio; Defined in RFC 5334 # audio/vorbis: Vorbis encoded audio; Defined in RFC 5215 # audio/x-ms-wma: Windows Media Audio; Documented in MS kb288102[9] # audio/x-ms-wax: Windows Media Audio Redirector; Documented in MS kb288102[9] # audio/vnd.rn-realaudio: RealAudio; Documented in RealPlayer Help[10] # audio/vnd.wave: WAV audio; Defined in RFC 2361 # audio/webm: WebM open media format mymime_audio=("application/ogg","audio/mpeg", "audio/mp4", "audio/x-flac", "audio/x-wav") mymime_ogg=("application/ogg",) webmime_audio = ("audio/mpeg","audio/mp3","audio/flac","video/ogg","audio/ogg","audio/oga", \ "audio/basic","audio/L24","audio/mp4","audio/vorbis","audio/x-ms-wma2",\ "audio/x-ms-wax","audio/vnd.rn-realaudio","audio/vnd.wave","audio/webm",\ "application/ogg","audio/wav") websuffix_audio = (".mp3",".wav",".ogg",".oga",".flac",".Mp3",".Wav",".Ogg",".Oga",".Flac",".MP3",".WAV",".OGG",".OGA",".FLAC" ) webmime_ogg = ("video/ogg","audio/oga","audio/ogg","audio/oga","audio/vorbis","application/ogg") websuffix_ogg = (".ogg",".oga",".Ogg",".Oga",".OGG") autoradio-autoradio-3.6-4/autoradio/mkplaylist.py000077500000000000000000000404661454362722700222620ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- #----------------------------------------------------------------------------- # Name: mkplaylist.py # Purpose: ReCreate playlists from directory scans or m3u playlist. # # Author: Marc 'BlackJack' Rintsch # Paolo Patruno # Created: 2004-11-09 # Last modified: 2012-08-04 # Copyright: (c) 2004-2009 # Licence: GPL #----------------------------------------------------------------------------- """Make a playlist file. :var factory: instance of a `PlaylistEntryFactory`. :var WRITERS: dictionary that maps playlist format names to functions that write a sequence of `PlaylistEntry` objects in that format to a file. :todo: Check if docstrings and code are still in sync. :todo: Refactor cache code. Introduce a Cache class. Maybe subclassing `PlaylistEntryFactory` with a caching version. Keep in mind that this scales, i.e. implementing an SQLite cache or using AmaroK's db should be considered too. :todo: Find a strategically favourable place to minimise the contents of the meta data dictionaries to the bare minimum to cut down the cache file size. It is not necessary to have the version of the vorbis library in ogg meta data for example. """ import sys import os import os.path import random import logging from itertools import chain import mutagen import urllib.request, urllib.error, urllib.parse __author__ = "Marc 'BlackJack' Rintsch " __version__ = '0.6.0' __date__ = '$Date: 2012-11-26 $' __docformat__ = 'reStructuredText' # Disable `pylint` name convention warning for names on module level that # are not ``def``\ed functions and still have no conventional constant names, # i.e. only capital letters. # # pylint: disable-msg=C0103 # # Use logging for ouput at different *levels*. # logging.getLogger().setLevel(logging.INFO) log = logging.getLogger("mkplaylist") handler = logging.StreamHandler(sys.stderr) log.addHandler(handler) #----------------------------------------------------------------------------- # Functions to read meta data from media files. # # now use mutagen # # The functions return a dictionary with the meta data. The minimal # postcondition is an empty dictionary if no information could be # read from the file. # # Keys to use (yes, they are all uppercase!): # # ARTIST, TITLE, TIME (playing time in seconds) # # All other keys are currently not used by any output format. def metadata_reader(path): """Reads info from media file.""" info = dict() if path[:5] == "http:": info['TIME'] = None info['ARTIST'] = "streaming" info['ALBUM'] = "streaming" info['TITLE'] = path else: try: m=mutagen.File(path,easy=True) # in seconds (type float). info['TIME'] = m.info.length for value_name, key in (('artist', 'ARTIST'), ('album', 'ALBUM'), ('title', 'TITLE')): value = m.get(value_name) if value: info[key] = value[0] except: log.info("Could not read info from file: %s ",path) return info #----------------------------------------------------------------------------- class PlaylistEntry(object): """A generic playlist entry with a `path` attribute and dictionary like behavior for meta data. `PlaylistEntry` objects can be converted to strings and are comparable with their `path` attribute as key. The meta data contains at least the path of the media file. :ivar path: path of the media file. :type path: str :ivar metadata: meta data of the media file. :type metadata: dict of str -> str :invariant: self['path'] is not None """ def __init__(self, path, metadata=None): """Creates a playlist entry. :param path: the path of the media file. :type path: str :param metadata: a dictionary with meta data. :type metadata: dict of str -> str :precondition: The meta data must not contain a key 'path'. :postcondition: The meta data contains the `path` as key. """ self.path = path if metadata is None: metadata = dict() metadata['PATH'] = self.path self.metadata = metadata # TODO: Some black magic to fill the metadata from examining # the file name if the dict is empty. def __getitem__(self, key): return self.metadata.get(key, '') def __setitem__(self, key, value): self.metadata[key] = value if key == 'PATH': self.path = key def __cmp__(self, other): return (self.path > other.path) - (self.path < other.path) def __str__(self): return self.path def __unicode__(self): try: return self.path.decode("UTF-8") except: log.info("Could not decode UTF-8: %s ",self.path) return "" class PlaylistEntryFactory(object): """A media file factory allows registritation of media file types, their file name extensions and functions for reading meta data from the files. This is not a "real" class but more an abuse of a class as a namespace. If the program grows so large that it will become unavoidable to split it into several modules, the contents of this class may be moved to the top level of a module. :ivar types: dictionary that maps a file name extension to a tuple containing a descriptive name of the type and a sequence of functions to read meta data from this file type. :type types: dict :ivar cachefile: pathname of a file to store the pickled data from cached PlaylistEntries :type cachefile: string """ def __init__(self): pass def is_media_file(self, path): """Check file if it is a known media file. The check is based on mutagen file test :param path: filename of the file to check. :type path: str :returns: `True` if known media file, `False` otherwise. :rtype: bool """ try: return not mutagen.File(path) is None except: return False def is_media_url(self, path): """Check file if it is a url. The check is based on the prefix thet will be http: :param path: filename of the file to check. :type path: str :returns: `True` if url, `False` otherwise. :rtype: bool """ return path[:5] in ("http:","file:") def create_entry(self, path): """Reads metadata and returns PlaylistEntry objects. :param path: path to the media file. :type path: str :return: dictionary with meta data. :rtype: dict of str -> str """ playlist_entry = PlaylistEntry(path, metadata_reader(path)) log.debug("(new)") return playlist_entry # # Create a PlaylistEntryFactory instance and populate it with the # known file extensions. # factory = PlaylistEntryFactory() #----------------------------------------------------------------------------- # Playlist writers. def write_m3u(playlist, outfile,timelen=None): """Writes the playlist in m3u format.""" totaltime=0. i=0 for entry in playlist: if not entry['TIME'] is None : totaltime += entry['TIME'] else: if not timelen is None : log.error("error evalutate time length on file: %s ",entry ) continue if timelen is None : wr=True else: wr=False if totaltime < timelen : wr=True if (wr): print(str(entry), file=outfile) i+=1 else: break log.info("That's %d out file(s).", i) def write_extm3u(playlist, outfile,timelen=None): """Writes the playlist in extended m3u format.""" totaltime=0. i=0 print('#EXTM3U', file=outfile) for entry in playlist: if not entry['TIME'] is None : totaltime += entry['TIME'] else: if not timelen is None : log.error("error evalutate time length on file: %s",entry ) continue if timelen is None : wr=True else: wr=False if totaltime < timelen : wr=True if (wr): time=entry['TIME'] if time is None : time = -1 if entry['ARTIST'] and entry['TITLE']: print('#EXTINF:%s,%s - %s' % (time, entry['ARTIST'], entry['TITLE']), file=outfile) print(str(entry), file=outfile) i+=1 else: break log.info("That's %d out file(s).", i) def write_pls(playlist, outfile,timelen=None): """Write the `playlist` in PLS format. :todo: Guess playlist name from `outfile.name`. :todo: Add command line option for playlist title. """ totaltime=0. print('[playlist]', file=outfile) print('PlaylistName=Playlist', file=outfile) i = 0 for i, entry in enumerate(playlist): if not entry['TIME'] is None : totaltime += entry['TIME'] else: log.error("evaluate time length on file: %s",entry ) continue if timelen is None : wr=True else: wr=False if totaltime < timelen : wr=True if (wr) : i += 1 print('File%d=%s' % (i, entry), file=outfile) title = entry['TITLE'] or os.path.basename(str(entry)) print('Title%d=%s' % (i, title), file=outfile) print('Length%d=%s' % (i, entry['TIME']), file=outfile) else: break print('NumberOfEntries=%d' % i, file=outfile) print('Version=2', file=outfile) log.info("That's %d out file(s).", i) WRITERS = { 'm3u': write_m3u, 'extm3u': write_extm3u, 'pls': write_pls } #----------------------------------------------------------------------------- def read_playlist(infile, absolute_paths=True): """Iterates over media files in playlist. Extended M3U directives are skipped. :param infile: filename of playlist :type infile: str :param absolute_paths: converts relative path names to absolute ones if set to `True`. :type absolute_paths: bool :returns: iterator over `PlaylistEntry` objects. :rtype: iterable of `PlaylistEntry` """ root = os.getcwd() if infile == '-': finfile = sys.stdin else: finfile = open(infile, encoding='utf-8', errors='replace') root = os.path.join(root , os.path.dirname(infile)) log.debug("root dir: %s", root) for filename in finfile.read().strip().split("\n"): log.debug("entry: %s", filename) if len(filename) == 0 or filename[0] == "#": # skip empty and comment lines log.debug("ignore %s", filename) continue # convert thinks like %20 in file name filename=urllib.request.url2pathname(filename) if filename[:7] == "file://" : filename=filename[7:] if factory.is_media_file(filename): log.debug("found %s", filename) if filename[0] != "/" : full_name = os.path.join(root, filename) else: full_name=filename log.debug("full_name: %s", full_name) if not os.path.isfile(full_name): log.info("ignore %s do not exist", full_name) continue if absolute_paths: full_name = os.path.abspath(full_name) else: l=len(os.path.commonprefix((root,full_name)).rpartition("/")[0]) if l>0 : full_name=full_name[l+1:] log.debug("post full_name: %s", full_name) yield factory.create_entry(full_name) elif factory.is_media_url(filename): yield factory.create_entry(filename) else: log.info("ignore %s", filename) finfile.close() def search(path, absolute_paths=True): """Iterates over media files in `path` (recursivly). Symlinked directories are skipped to avoid endless scanning due to possible cycles in directory structure. :param path: root of the directory tree to search. :type path: str :param absolute_paths: converts relative path names to absolute ones if set to `True`. :type absolute_paths: bool :returns: iterator over `PlaylistEntry` objects. :rtype: iterable of `PlaylistEntry` """ for (root, dummy, filenames) in os.walk(path): log.info("Scanning %s...", root) # TODO: Check if there are linked directories. for filename in filenames: full_name = os.path.join(root, filename) if factory.is_media_file(full_name): log.debug("found %s", filename) if absolute_paths: full_name = os.path.abspath(full_name) yield factory.create_entry(full_name) def main(): """Main function.""" import codecs from optparse import OptionParser usage = ("usage: %prog [-h|--help|--version]\n" " %prog [options] directory [directory ...]") parser = OptionParser(usage=usage, version="%prog " + __version__) parser.add_option("-i", "--input", type="string", dest="infile", default='-', help="name of the m3u playlist input file or '-' for stdout (default)") parser.add_option("-t", "--timelen", type="float", dest="timelen", default=None, help="Len of Playlist in seconds (default= infinite)") parser.add_option("-o", "--output", type="string", dest="outfile", default='-', help="name of the output file or '-' for stdout (default)") parser.add_option("-f", "--output-format", type="choice", dest="output_format", default="extm3u", choices=list(WRITERS.keys()), help="format of the output %r (default: %%default)" % list(WRITERS.keys())) parser.add_option("-r", "--relative-paths", action="store_true", dest="relative_paths", default=False, help="write relative paths. (default: absolute paths)") parser.add_option("--shuffle", action="store_true", default=False, help="shuffle the playlist before saving it.") parser.add_option("--sort", action="store_true", default=False, help="sort the playlist before saving it.") parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="be more verbose.") parser.add_option("-q", "--quiet", action="store_true", default=False, dest="quiet", help="be really quiet.") (options, args) = parser.parse_args() # if len(args) == 0: # parser.error("wrong number of arguments") write_playlist = WRITERS[options.output_format] if options.quiet: log.setLevel(logging.WARNING) if options.verbose: log.setLevel(logging.DEBUG) # # Input. # if len(args) == 0: log.info("Read %s file.", options.infile) media_files=list(read_playlist(options.infile, not options.relative_paths)) else: media_files = list(chain(*[search(path, not options.relative_paths) for path in args])) # # Processing. # if options.shuffle: random.shuffle(media_files) elif options.sort: media_files.sort() # # Output. # outfile = sys.stdout if options.outfile != '-': #outfile = file(options.outfile, "w") outfile = codecs.open(options.outfile, "w", encoding="UTF-8") write_playlist(media_files, outfile,options.timelen) outfile.close() log.info("That's %d good input file(s).", len(media_files)) if __name__ == '__main__': main() autoradio-autoradio-3.6-4/autoradio/mpris2/000077500000000000000000000000001454362722700207165ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/mpris2/__init__.py000077500000000000000000000107041454362722700230340ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: UTF8 -* ''' This is a copy of mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/ That also works as python lib. Version 2.2 =========== Copyright © 2006-2010 the VideoLAN team(Mirsal Ennaime, Rafaël Carré, Jean-Paul Saman) Copyright © 2005-2008 Milosz Derezynski Copyright © 2008 Nick Welch Copyright © 2010-2012 Alex Merry This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. About ===== The Media Player Remote Interfacing Specification is a standard D-Bus interface which aims to provide a common programmatic API for controlling media players. It provides a mechanism for compliant media players discovery, basic playback and media player state control as well as a tracklist interface which is used to add context to the current item. Changes ======= Changes (Permalink) From 2.1 to 2.2: * Added the optional Fullscreen and CanSetFullscreen properties to the org.mpris.MediaPlayer2 interface. * The path /org/mpris/MediaPlayer2/TrackList/NoTrack now represents "no track" where required in the org.mpris.MediaPlayer2.TrackList interface (since empty paths are not allowed by D-Bus). * The suggested unique instance identifier no longer violates the D-Bus specification by begining with a digit. From 2.0 to 2.1: * Added the optional org.mpris.MediaPlayer2.Playlists interface. Bus Name Policy =============== Each media player *must* request a unique bus name which begins with *org.mpris.MediaPlayer2*. For example: * org.mpris.MediaPlayer2.audacious * org.mpris.MediaPlayer2.vlc * org.mpris.MediaPlayer2.bmp * org.mpris.MediaPlayer2.xmms2 This allows clients to list available media players (either already running or which can be started via D-Bus activation) In the case where the media player allows multiple instances running simultaneously, each additional instance should request a unique bus name, adding a dot and a unique identifier to its usual bus name, such as one based on a UNIX process id. For example, this could be: * org.mpris.MediaPlayer2.vlc.7389 Note: According to the D-Bus specification, the unique identifier "must only contain the ASCII characters '[A-Z][a-z][0-9]_-'" and "must not begin with a digit". Entry point =========== The media player *must* expose the */org/mpris/MediaPlayer2* object path, which *must* implement the following interfaces: * :doc:`org.mpris.MediaPlayer2<../mpris2.mediaplayer2>` * :doc:`org.mpris.MediaPlayer2.Player<../mpris2.player>` The */org/mpris/MediaPlayer2* object may implement the :doc:`org.mpris.MediaPlayer2.TrackList<../mpris2.tracklist>` interface. The */org/mpris/MediaPlayer2* object may implement the :doc:`org.mpris.MediaPlayer2.Playlists<../mpris2.playlists>` interface. The PropertiesChanged signal ============================ The MPRIS uses the org.freedesktop.DBus.Properties.PropertiesChanged signal to notify clients of changes in the media player state. If a client implementation uses D-Bus bindings which do not support this signal, then it should connect to it manually. If a media player implementation uses D-Bus bindings which do not support this signal, then it should send it manually Corrections =========== 2010-09-26: Added EmitsChangedSignal annotation to Volume property on the Player interface. 2011-01-26: Added PlaylistChanged signal to the Playlists interface. Interfaces ========== * :doc:`org.mpris.MediaPlayer2<../mpris2.mediaplayer2>` * :doc:`org.mpris.MediaPlayer2.Player<../mpris2.player>` * :doc:`org.mpris.MediaPlayer2.Playlists<../mpris2.playlists>` * :doc:`org.mpris.MediaPlayer2.TrackList<../mpris2.tracklist>` ''' from .interfaces import Interfaces from .mediaplayer2 import MediaPlayer2 from .player import Player from .playlists import Playlists from .tracklist import TrackList from .utils import get_players_uri from .some_players import Some_Players as SomePlayers autoradio-autoradio-3.6-4/autoradio/mpris2/__main__.py000066400000000000000000000004121454362722700230050ustar00rootroot00000000000000from . import Interfaces from . import MediaPlayer2 from . import Player from . import Playlists from . import TrackList if __name__ == '__main__': print(Interfaces()) print(MediaPlayer2()) print(Player()) print(Playlists()) print(TrackList()) autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/000077500000000000000000000000001454362722700227005ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/__init__.py000066400000000000000000000005031454362722700250070ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .attribute import DbusAttr from .interface import DbusInterface from .method import DbusMethod from .signal import DbusSignal from .utils import get_mainloop, get_uri, implements, \ list_all_interface, list_interfaces, list_paths autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/__main__.py000066400000000000000000000003421454362722700247710ustar00rootroot00000000000000from . import DbusAttr from . import DbusInterface from . import DbusMethod from . import DbusSignal if __name__ == '__main__': print(DbusAttr()) print(DbusInterface()) print(DbusMethod()) print(DbusSignal()) autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/attribute.py000066400000000000000000000031041454362722700252530ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .base import Decorator, ATTR_KEY class DbusAttr(Decorator): ''' https://docs.python.org/2/howto/descriptor.html#properties ''' def __init__(self, meth=None, produces=lambda resp: resp): self.attr = meth self.produces = produces self._update_me(meth) def __call__(self, meth): self.attr = meth self._update_me(meth) return self def __get__(self, obj, objtype=None): #static call if not obj: return self _dbus = getattr(obj, ATTR_KEY) props = _dbus.properties iface = _dbus.iface result = props.Get(iface, self.attr.__name__) produces = self.produces return produces(result) def __set__(self, obj, value): if obj: _dbus = getattr(obj, ATTR_KEY) props = _dbus.properties iface = _dbus.iface props.Set(iface, self.attr.__name__, value) else: #static call self.attr = value def __delete__(self, obj): raise AttributeError('can not delete attribute') if __name__ == '__main__': # examples from .interface import DbusInterface @DbusInterface('org.mpris.MediaPlayer2', '/org/mpris/MediaPlayer2') class Example(object): @DbusAttr def Identity(self): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.mpris.MediaPlayer2.vlc'}) assert d.Identity == 'VLC media player' autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/base.py000066400000000000000000000010021454362722700241550ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' I_PROP = 'org.freedesktop.DBus.Properties' ARG_KEY = 'dbus_interface_info' ATTR_KEY = '_dbus_interface_info' class Decorator(object): def _update_me(self, target=None): if hasattr(target, "__doc__"): self.__doc__ = target.__doc__ if hasattr(target, "__name__"): self.__name__ = target.__name__ if hasattr(target, "__bases__"): self.__bases__ = target.__bases__ autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/interface.py000066400000000000000000000102141454362722700252100ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' import dbus from functools import wraps from .base import Decorator, ARG_KEY, I_PROP, ATTR_KEY class _DbusInfoProperty(object): def __init__(self, iface=None, path=None, uri=None, dbus_object=None, session=None, wrapped=None): self.iface = iface self.path = path self.uri = uri self.object = dbus_object self.session = session self.wrapped = wrapped self.interface = None self.properties = None if not self.object: bus = self.session = self.session or dbus.SessionBus() self.object = bus.get_object(self.uri, self.path) if not self.interface: self.interface = dbus.Interface(self.object, dbus_interface=self.iface) if not self.properties: self.properties = dbus.Interface(self.object, I_PROP) def reconnect(self, session=None): ''' Required if you need update session/proxy object/interfaces ''' session = session or self.session if session == self.session: self.session.close() session = self.session = dbus.SessionBus() self.object = session.get_object(self.uri, self.path) self.interface = dbus.Interface(self.object, dbus_interface=self.iface) self.properties = dbus.Interface(self.object, I_PROP) class DbusInterface(Decorator): def __init__(self, iface=None, path=None, uri=None, dbus_object=None, session=None): self.iface = iface self.path = path self.uri = uri self.object = dbus_object self.session = session self.wrapped = None def __call__(self, meth): ''' Called when any decorated class is loaded''' self.wrapped = meth self._update_me(meth) @wraps(meth) def dbusWrapedInterface(*args, **kw): _args = kw.get(ARG_KEY, {}) info_property = _DbusInfoProperty( iface=_args.get('dbus_iface', self.iface), path=_args.get('dbus_path', self.path), uri=_args.get('dbus_uri', self.uri), dbus_object =_args.get('dbus_object', self.object), session =_args.get('dbus_session', self.session), wrapped=self.wrapped ) if ARG_KEY in kw: del kw[ARG_KEY] return self.dbusWrapedInterface(info_property, *args, **kw) return dbusWrapedInterface def dbusWrapedInterface(self, info_property, *args, **kw): ''' Called when some decoreted class was called Inject attrs from decorator at new object then return object @param *args: list of args to call constructor @param **kw: dict of keywords, can redefine class default parameters @return: instance of decoreted class, with new attributes @see: mpris2.mediaplayer2 to see some examples ''' #call decorated class constructor new_obj = self.wrapped(*args, **kw) if new_obj: setattr(new_obj, ATTR_KEY, info_property) elif len(args) > 0: setattr(args[0], ATTR_KEY, info_property) return new_obj if __name__ == '__main__': # examples @DbusInterface('org.freedesktop.DBus', '/') class Example(object): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert d._dbus_interface_info.iface == 'org.freedesktop.DBus' assert d._dbus_interface_info.path == '/' assert d._dbus_interface_info.uri == 'org.freedesktop.DBus' class ExempleToo(object): @DbusInterface('org.freedesktop.DBus', '/') def __init__(self): pass dd = ExempleToo( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert dd._dbus_interface_info.iface == 'org.freedesktop.DBus' assert dd._dbus_interface_info.path == '/' assert dd._dbus_interface_info.uri == 'org.freedesktop.DBus' autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/method.py000066400000000000000000000063751454362722700245450ustar00rootroot00000000000000''' This is not part of specification Helper class to make it work as python lib ''' from .base import Decorator, ATTR_KEY def kw_to_dbus(**kw): return kw def args_to_dbus(*args): return args class DbusMethod(Decorator): def __init__(self, meth=None, iface=None, produces=lambda resp: resp, args_to_dbus=args_to_dbus, kw_to_dbus=kw_to_dbus, std_args=(), std_kwds={}): self.meth = meth self.handler = None self.produces = produces self.iface = iface self.args_to_dbus = args_to_dbus self.kw_to_dbus = kw_to_dbus self.std_args = std_args self.std_kwds = std_kwds self.obj = None self._update_me(meth) def __call__(self, meth=None): self.meth = meth self._update_me(meth) return self def __get__(self, obj=None, cls=None): if obj is None: return self self.obj = obj return self._call_dbus def _call_dbus(self, *args, **kwds): _dbus = getattr(self.obj, ATTR_KEY) if self.iface: iface = self.iface else: iface = _dbus.iface bus_obj = _dbus.object bus_meth = bus_obj.get_dbus_method(self.meth.__name__, iface) _args = self.merge_args(args, self.std_args) args = self.convert_args_to_dbus_args(*_args) _kwds = self.std_kwds.copy() _kwds.update(kwds) kwds = self.convert_kw_to_dbus_kw(**_kwds) result = bus_meth(*args, **kwds) return self.produces(result) @classmethod def merge_args(cls, args, std_args): _len = len(std_args) - len(args) return args + std_args[-_len:] if _len > 0 else args @classmethod def merge_kwds(cls, kwds, std_kwds): _kwds = std_kwds.copy() _kwds.update(kwds) return _kwds def convert_args_to_dbus_args(self, *args): args_to_dbus = self.args_to_dbus if callable(args_to_dbus): return args_to_dbus(*args) #iterate over args result = [] for arg in args: i = args.index(arg) if i < len(args_to_dbus): make = args_to_dbus[i] if callable(make): arg = make(arg) result.append(arg) return tuple(result) def convert_kw_to_dbus_kw(self, **kw): kw_to_dbus = self.kw_to_dbus if callable(kw_to_dbus): return kw_to_dbus(**kw) if hasattr(self.kw_to_dbus, 'keys'): for key, val in kw.items(): make = kw_to_dbus.get(key, lambda v: v) kw[key] = make(val) return kw if __name__ == '__main__': # examples from .interface import DbusInterface @DbusInterface('org.freedesktop.DBus', '/') class Example(object): @DbusMethod def GetId(self): pass @DbusMethod def GetNameOwner(self, name): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.freedesktop.DBus'}) assert d.GetId() assert d.GetNameOwner('org.freedesktop.DBus') == 'org.freedesktop.DBus' autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/signal.py000066400000000000000000000032621454362722700245320ustar00rootroot00000000000000from .base import Decorator, ATTR_KEY class DbusSignal(Decorator): ''' https://docs.python.org/2/howto/descriptor.html#properties ''' def __init__(self, meth=None, iface=None): self.attr = meth self.handler = None self.iface = iface self._update_me(meth) def __call__(self, meth): self.attr = meth self._update_me(meth) return self def __get__(self, obj, objtype=None): if obj: return self.handler #static call return self def __set__(self, obj, value): if obj: _dbus = getattr(obj, ATTR_KEY) interface = _dbus.interface def handle(*args, **kwds): h = self.handler h and h(*args, **kwds) if not self.handler: interface.connect_to_signal(self.attr.__name__, handle, dbus_interface=self.iface) self.handler = value else: #static call self.attr = value def __delete__(self, obj): self.handler = None if __name__ == '__main__': from .interface import DbusInterface from .utils import get_mainloop mainloop = get_mainloop() print('mainloop', mainloop) @DbusInterface('org.mpris.MediaPlayer2.player', '/org/mpris/MediaPlayer2') class Example(object): @DbusSignal def Seeked(self): pass d = Example( dbus_interface_info={ 'dbus_uri': 'org.mpris.MediaPlayer2.gmusicbrowser'}) def handler(self, *args): print(args) d.Seeked = handler mainloop and mainloop.run() autoradio-autoradio-3.6-4/autoradio/mpris2/decorator/utils.py000066400000000000000000000110741454362722700244150ustar00rootroot00000000000000''' utils functions ''' import dbus, re import xml.etree.ElementTree as ET I_INSPECT = 'org.freedesktop.DBus.Introspectable' def _match_uri(name, pattern='.+'): ''' Filter logic for get_players and get_player_uri @param name: string name to test @param pattern=None: string RegEx to test @return: boolean ''' return re.match(pattern, name) def get_session(busaddress=None): ''' @return: dbus.SessionBus.get_session() ''' if busaddress is None: return dbus.SessionBus.get_session() else: return dbus.bus.BusConnection(busaddress) def get_uri(pattern='.',busaddress=None): ''' Return string of player bus name @param pattern=None: string RegEx that filter response @return: array string of players bus name ''' for item in get_session(busaddress).list_names(): if _match_uri(item, pattern): yield item def get_mainloop(): ''' @return: mainloop (with 'run' method) ''' try: from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) try: import gobject return gobject.MainLoop() except: pass try: import gi.repository.GLib return gi.repository.GLib.MainLoop() except: pass except: pass class PyQtMainLoop(): def __init__(self, app): self.app = app def run(self): if hasattr(self.app, 'exec_'): self.app.exec_() if hasattr(self.app, 'exec'): method = getattr(self.app, 'exec') method(self.app) try: from dbus.mainloop.qt import DBusQtMainLoop DBusQtMainLoop(set_as_default=True) try: from PySide.QtGui import QApplication return PyQtMainLoop(QApplication([])) except: pass try: from PyQt5.QtWidgets import QApplication return PyQtMainLoop(QApplication([])) except: pass try: from PyQt4 import Qt return PyQtMainLoop(Qt.QApplication([])) except: pass except: pass return None def _introspect_uri(bus_name, path, bus): bus = bus or dbus.SessionBus.get_session() path = path.replace('//', '/') or '/' obj = bus.get_object(bus_name, path) xml = obj.Introspect(dbus_interface=I_INSPECT) return ET.fromstring(xml) def list_paths(bus_name, path='/', bus=None): ''' Return generator with all subpaths of uri @param bus_name: string dbus object name @param path='/': string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all paths that has interfaces ''' nodes = _introspect_uri(bus_name, path, bus) if [iface for iface in nodes.findall('interface')]: yield path.replace('//', '/') for node in nodes.findall('node'): sub_path = path + '/'+ node.attrib['name'] for path_name in list_paths(bus_name, sub_path, bus): yield path_name def list_interfaces(bus_name, path, bus=None): ''' Return generator with all interfaces of path @param bus_name: string dbus object name @param path: string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all interfaces of path ''' nodes = _introspect_uri(bus_name, path, bus) for interface in nodes.findall('interface'): yield interface.attrib['name'] def list_all_interface(bus_name, path='/', bus=None): ''' Return generator with all interfaces of path and subpaths @param bus_name: string dbus object name @param path: string dbus object path @param bus=None: Conn dbus.Conn (commonly SessionBus or SystemBus) @return: generator with all interfaces of path and subpaths ''' paths = list_paths(bus_name, path, bus) for sub_path in paths: for interface in list_interfaces(bus_name, sub_path, bus): yield sub_path, interface def implements(uri, interface, path, bus=None): ''' ''' for iface in list_interfaces(uri, path, bus): if iface == interface: return True if __name__ == '__main__': uri = None for uri in get_uri(): if uri.count(':') == 0: print(uri) if uri: for interface in list_all_interface(uri, '/'): print('\t', interface) else: print('Nothing running') autoradio-autoradio-3.6-4/autoradio/mpris2/interfaces.py000077500000000000000000000020331454362722700234140ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/#Interfaces ''' class Interfaces(object): ''' This class contains the constants defined at index of MPRIS2 definition: **Interfaces:** * MEDIA_PLAYER 'org.mpris.MediaPlayer2' * TRACK_LIST 'org.mpris.MediaPlayer2.TrackList' * PLAYER 'org.mpris.MediaPlayer2.Player' * PLAYLISTS 'org.mpris.MediaPlayer2.Playlists' * PROPERTIES 'org.freedesktop.DBus.Properties' **Signals:** * SIGNAL 'PropertiesChanged' **Objects:** * OBJECT_PATH '/org/mpris/MediaPlayer2' ''' #interface MEDIA_PLAYER = 'org.mpris.MediaPlayer2' TRACK_LIST = 'org.mpris.MediaPlayer2.TrackList' PLAYER = 'org.mpris.MediaPlayer2.Player' PLAYLISTS = 'org.mpris.MediaPlayer2.Playlists' PROPERTIES = 'org.freedesktop.DBus.Properties' #signal SIGNAL = 'PropertiesChanged' #Object OBJECT_PATH = '/org/mpris/MediaPlayer2' autoradio-autoradio-3.6-4/autoradio/mpris2/mediaplayer2.py000077500000000000000000000214441454362722700236560ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Media_Player.html ''' from .decorator import DbusAttr from .decorator import DbusInterface from .decorator import DbusMethod from .decorator import DbusSignal from .interfaces import Interfaces class MediaPlayer2(Interfaces): ''' Interface for MediaPlayer2 (org.mpris.MediaPlayer2) ''' PROPERTIES_CAN_QUIT = 'CanQuit' PROPERTIES_CAN_RAISE = 'Identity' PROPERTIES_HAS_TRACK_LIST = 'HasTrackList' PROPERTIES_IDENTITY = 'Identity' PROPERTIES_DESKTOP_ENTRY = 'DesktopEntry' PROPERTIES_SUPPORTED_URI_SCHEMES = 'SupportedUriSchemes' PROPERTIES_SUPPORTED_MINE_TYPES = 'SupportedMimeTypes' SIGNALS_PROPERTIES_CHANGED = 'PropertiesChanged' @DbusInterface(Interfaces.MEDIA_PLAYER, Interfaces.OBJECT_PATH) def __init__(self): '''Constructor''' @DbusMethod def Raise(self): ''' Brings the media player's user interface to the front using any appropriate mechanism available. The media player may be unable to control how its user interface is displayed, or it may not have a graphical user interface at all. In this case, the Identity property is false and this method does nothing. ''' @DbusMethod def Quit(self): ''' Causes the media player to stop running. The media player may refuse to allow clients to shut it down. In this case, the CanQuit property is false and this method does nothing. ..note:: Media players which can be D-Bus activated, or for which there is no sensibly easy way to terminate a running instance (via the main interface or a notification area icon for example) should allow clients to use this method. Otherwise, it should not be needed. If the media player does not have a UI, this should be implemented ''' @DbusAttr def CanQuit(self): ''' **Returns** Read only Inject attrs from decorator at new object then return obje When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. If false, calling Quit will have no effect, and may raise a NotSupported error. If true, calling Quit will cause the media application to attempt to quit (although it may still be prevented from quitting by the user, for example). ''' @DbusAttr def Fullscreen(self): ''' **Returns** Read Write Whether the media player is occupying the fullscreen. This property is optional. Clients should handle its absence gracefully. When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. This is typically used for videos. A value of true indicates that the media player is taking up the full screen. Media center software may well have this value fixed to true If CanSetFullscreen is true, clients may set this property to true to tell the media player to enter fullscreen mode, or to false to return to windowed mode. If CanSetFullscreen is false, then attempting to set this property should have no effect, and may raise an error. However, even if it is true, the media player may still be unable to fulfil the request, in which case attempting to set this property will have no effect (but should not raise an error). Added in 2.2. ''' @DbusAttr def CanSetFullscreen(self): ''' **Returns** Read only If false, attempting to set Fullscreen will have no effect, and may raise an error. If true, attempting to set Fullscreen will not raise an error, and (if it is different from the current value) will cause the media player to attempt to enter or exit fullscreen mode. This property is optional. Clients should handle its absence gracefully. When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Added in 2.2. ..note:: Note that the media player may be unable to fulfil the request. In this case, the value will not change. If the media player knows in advance that it will not be able to fulfil the request, however, this property should be false. ''' @DbusAttr def CanRaise(self): ''' **Returns** Read only If false, calling Raise will have no effect, and may raise a NotSupported error. If true, calling Raise will cause the media application to attempt to bring its user interface to the front, although it may be prevented from doing so (by the window manager, for example). When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. ''' @DbusAttr def HasTrackList(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Indicates whether the /org/mpris/MediaPlayer2 object implements the org.mpris.MediaPlayer2.TrackList interface. ''' @DbusAttr def DesktopEntry(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The basename of an installed .desktop file which complies with the Desktop entry specification, with the '.desktop' extension stripped. Example: The desktop entry file is '/usr/share/applications/vlc.desktop', and this property contains 'vlc' This property is optional. Clients should handle its absence gracefully ''' @DbusAttr def Identity(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. If false, calling Raise will have no effect, and may raise a NotSupported error. If true, calling Raise will cause the media application to attempt to bring its user interface to the front, although it may be prevented from doing so (by the window manager, for example). ''' @DbusAttr def SupportedUriSchemes(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The URI schemes supported by the media player. This can be viewed as protocols supported by the player in almost all cases. Almost every media player will include support for the 'file' scheme. Other common schemes are 'http' and 'rtsp'. Note that URI schemes should be lower-case. .. note:: This is important for clients to know when using the editing capabilities of the Playlist interface, for example. ''' @DbusAttr def SupportedMimeTypes(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The mime-types supported by the media player. Mime-types should be in the standard format (eg: audio/mpeg or application/ogg). .. note:: This is important for clients to know when using the editing capabilities of the Playlist interface, for example. ''' @DbusSignal(iface=Interfaces.PROPERTIES) def PropertiesChanged(self, *args, **kw): ''' **Parameters:** * args - list unnamed parameters passed by dbus signal * kw - dict named parameters passed by dbus signal Every time that some property change, signal will be called ''' if __name__ == '__main__': from .utils import get_players_uri, implements, get_mainloop mainloop = get_mainloop() # to set signal handler # set_default_mainloop # need to be called before instance creation for uri in get_players_uri(): if implements(uri, Interfaces.PLAYER): mp2 = MediaPlayer2(dbus_interface_info={ 'dbus_uri': uri }) print(mp2.SupportedUriSchemes) def another_handler(self, *args, **kw): print(args, '\n', kw) if mainloop: mp2.PropertiesChanged = another_handler mainloop.run() break else: print('no player with mediaplayer2 interface found')autoradio-autoradio-3.6-4/autoradio/mpris2/player.py000077500000000000000000000400161454362722700225700ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html ''' from .decorator import DbusAttr from .decorator import DbusInterface from .decorator import DbusMethod from .decorator import DbusSignal from .interfaces import Interfaces from .types import Time_In_Us from .types import Loop_Status from .types import Playback_Status from .types import Playback_Rate from .types import Metadata_Map from .types import Volume class Player(Interfaces): ''' This interface implements the methods for querying and providing basic control over what is currently playing. ''' @DbusInterface(Interfaces.PLAYER, Interfaces.OBJECT_PATH) def __init__(self): '''Constructor''' @DbusMethod def Next(self): ''' Skips to the next track in the tracklist. If there is no next track (and endless playback and track repeat are both off), stop playback. If playback is paused or stopped, it remains that way. If CanGoNext is false, attempting to call this method should have no effect. ''' @DbusMethod def Previous(self): ''' Skips to the previous track in the tracklist. If there is no previous track (and endless playback and track repeat are both off), stop playback. If playback is paused or stopped, it remains that way. If CanGoPrevious is false, attempting to call this method should have no effect. ''' @DbusMethod def Pause(self): ''' Pauses playback. If playback is already paused, this has no effect. Calling Play after this should cause playback to start again from the same position. If CanPause is false, attempting to call this method should have no effect. ''' @DbusMethod def PlayPause(self): ''' Pauses playback. If playback is already paused, resumes playback. If playback is stopped, starts playback. If CanPause is false, attempting to call this method should have no effect and raise an error. ''' @DbusMethod def Stop(self): ''' Stops playback. If playback is already stopped, this has no effect. Calling Play after this should cause playback to start again from the beginning of the track. If CanControl is false, attempting to call this method should have no effect and raise an error. ''' @DbusMethod def Play(self): ''' Starts or resumes playback. If already playing, this has no effect. If there is no track to play, this has no effect. If CanPlay is false, attempting to call this method should have no effect. ''' @DbusMethod def Seek(self, Offet): ''' **Parameters:** * Offset - x (Time_In_Us) The number of microseconds to seek forward. Seeks forward in the current track by the specified number of microseconds. A negative value seeks back. If this would mean seeking back further than the start of the track, the position is set to 0. If the value passed in would mean seeking beyond the end of the track, acts like a call to Next. If the CanSeek property is false, this has no effect. ''' @DbusMethod def SetPosition(self, TrackId, Position): ''' **Parameters** * TrackId - o (Track_Id) The currently playing track's identifier. If this does not match the id of the currently-playing track, the call is ignored as 'stale'. * Position - x (Time_In_Us) Track position in microseconds. This must be between 0 and . Sets the current track position in microseconds. If the Position argument is less than 0, do nothing. If the Position argument is greater than the track length, do nothing. If the CanSeek property is false, this has no effect. ''' @DbusMethod def OpenUri(self, Uri): ''' **Parameters:** * Uri - s (Uri) Uri of the track to load. Its uri scheme should be an element of the org.mpris.MediaPlayer2.SupportedUriSchemes property and the mime-type should match one of the elements of the org.mpris.MediaPlayer2.SupportedMimeTypes. Opens the Uri given as an argument If the playback is stopped, starts playing If the uri scheme or the mime-type of the uri to open is not supported, this method does nothing and may raise an error. In particular, if the list of available uri schemes is empty, this method may not be implemented. Clients should not assume that the Uri has been opened as soon as this method returns. They should wait until the mpris:trackid field in the Metadata property changes. If the media player implements the TrackList interface, then the opened track should be made part of the tracklist, the org.mpris.MediaPlayer2.TrackList.TrackAdded or org.mpris.MediaPlayer2.TrackList.TrackListReplaced signal should be fired, as well as the org.freedesktop.DBus.Properties.PropertiesChanged signal on the tracklist interface. ''' @DbusSignal def Seeked(self, Position): ''' **Parameters:** * Position - x (Time_In_Us) The new position, in microseconds. Indicates that the track position has changed in a way that is inconsistant with the current playing state. When this signal is not received, clients should assume that: * When playing, the position progresses according to the rate property. * When paused, it remains constant. This signal does not need to be emitted when playback starts or when the track changes, unless the track is starting at an unexpected position. An expected position would be the last known one when going from Paused to Playing, and 0 when going from Stopped to Playing. ''' return Time_In_Us(Position) @DbusSignal(iface=Interfaces.PROPERTIES) def PropertiesChanged(self, *args, **kw): ''' **Parameters** * args - list unnamed parameters passed by dbus signal * kw - dict named parameters passed by dbus signal Every time that some property change, signal will be called ''' @DbusAttr(produces=Playback_Status) def PlaybackStatus(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The current playback status. May be 'Playing', 'Paused' or 'Stopped'. ''' @DbusAttr(produces=Loop_Status) def LoopStatus(self): ''' **Returns** Read/Write When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The current loop / repeat status May be: * 'None' if the playback will stop when there are no more tracks to play * 'Track' if the current track will start again from the begining once it has finished playing * 'Playlist' if the playback loops through a list of tracks This property is optional, and clients should deal with NotSupported errors gracefully. If CanControl is false, attempting to set this property should have no effect and raise an error. ''' @DbusAttr(produces=Playback_Rate) def Rate(self): ''' **Returns** Read/Write When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The current playback rate. The value must fall in the range described by MinimumRate and MaximumRate, and must not be 0.0. If playback is paused, the PlaybackStatus property should be used to indicate this. A value of 0.0 should not be set by the client. If it is, the media player should act as though Pause was called. If the media player has no ability to play at speeds other than the normal playback rate, this must still be implemented, and must return 1.0. The MinimumRate and MaximumRate properties must also be set to 1.0. Not all values may be accepted by the media player. It is left to media player implementations to decide how to deal with values they cannot use; they may either ignore them or pick a 'best fit' value. Clients are recommended to only use sensible fractions or multiples of 1 (eg: 0.5, 0.25, 1.5, 2.0, etc). ''' @DbusAttr def Shuffle(self): ''' **Returns** Read/Write When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. A value of false indicates that playback is progressing linearly through a playlist, while true means playback is progressing through a playlist in some other order. This property is optional, and clients should deal with NotSupported errors gracefully. If CanControl is false, attempting to set this property should have no effect and raise an error. ''' @DbusAttr(produces=Metadata_Map) def Metadata(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The metadata of the current element. If there is a current track, this must have a 'mpris:trackid' entry at the very least, which contains a string that uniquely identifies this track. See the type documentation for more details. ''' @DbusAttr(produces=Volume) def Volume(self): ''' **Returns** Read/Write When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The volume level. When setting, if a negative value is passed, the volume should be set to 0.0. If CanControl is false, attempting to set this property should have no effect and raise an error. ''' @DbusAttr def Position(self): ''' **Returns** Read only The org.freedesktop.DBus.Properties.PropertiesChanged signal is not emitted when this property changes. The current track position in microseconds, between 0 and the 'mpris:length' metadata entry (see Metadata). .. note:: If the media player allows it, the current playback position can be changed either the SetPosition method or the Seek method on this interface. If this is not the case, the CanSeek property is false, and setting this property has no effect and can raise an error. If the playback progresses in a way that is inconstistant with the Rate property, the Seeked signal is emited. ''' @DbusAttr def MinimumRate(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The minimum value which the Rate property can take. Clients should not attempt to set the Rate property below this value. Note that even if this value is 0.0 or negative, clients should not attempt to set the Rate property to 0.0. This value should always be 1.0 or less. ''' @DbusAttr def MaximumRate(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The maximum value which the Rate property can take. Clients should not attempt to set the Rate property above this value. This value should always be 1.0 or greater. ''' @DbusAttr def CanGoNext(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Whether the client can call the Next method on this interface and expect the current track to change. If CanControl is false, this property should also be false. ''' @DbusAttr def CanGoPrevious(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Whether the client can call the Previous method on this interface and expect the current track to change. If CanControl is false, this property should also be false. ''' @DbusAttr def CanPlay(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Whether playback can be started using Play or PlayPause. Note that this is related to whether there is a 'current track': the value should not depend on whether the track is currently paused or playing. In fact, if a track is currently playing CanControl is true), this should be true. If CanControl is false, this property should also be false. ''' @DbusAttr def CanPause(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Whether playback can be paused using Pause or PlayPause. Note that this is an intrinsic property of the current track: its value should not depend on whether the track is currently paused or playing. In fact, if playback is currently paused (and CanControl is true), this should be true. If CanControl is false, this property should also be false. ''' @DbusAttr def CanSeek(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. Whether the client can control the playback position using Seek and SetPosition. This may be different for different tracks. If CanControl is false, this property should also be false. ''' @DbusAttr def CanControl(self): ''' **Returns** Read only The org.freedesktop.DBus.Properties.PropertiesChanged signal is not emitted when this property changes. Whether the media player may be controlled over this interface. This property is not expected to change, as it describes an intrinsic capability of the implementation. If this is false, clients should assume that all properties on this interface are read-only (and will raise errors if writing to them is attempted); all methods are not implemented and all other properties starting with 'Can' are also false. ''' if __name__ == '__main__': from .utils import get_players_uri, implements for uri in get_players_uri(): if implements(uri, Interfaces.PLAYER): mp2 = Player(dbus_interface_info={'dbus_uri': uri}) print( mp2.LoopStatus ) print( mp2.Shuffle ) mp2.Shuffle = not mp2.Shuffle print( mp2.Shuffle ) break else: print('no player with player interface found')autoradio-autoradio-3.6-4/autoradio/mpris2/playlists.py000077500000000000000000000116151454362722700233230ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Playlists_Interface.html ''' from .decorator import DbusAttr from .decorator import DbusInterface from .decorator import DbusMethod from .decorator import DbusSignal from .interfaces import Interfaces from .types import Playlist, Maybe_Playlist from dbus import UInt64 class Playlists(Interfaces): ''' Provides access to the media player's playlists. Since D-Bus does not provide an easy way to check for what interfaces are exported on an object, clients should attempt to get one of the properties on this interface to see if it is implemented. ''' @DbusInterface(Interfaces.PLAYLISTS, Interfaces.OBJECT_PATH) def __init__(self): '''Constructor''' pass @DbusMethod def ActivatePlaylist(self, PlaylistId): ''' **Parameters:** * PlaylistId - o The id of the playlist to activate. Starts playing the given playlist. Note that this must be implemented. If the media player does not allow clients to change the playlist, it should not implement this interface at all. It is up to the media player whether this completely replaces the current tracklist, or whether it is merely inserted into the tracklist and the first track starts. For example, if the media player is operating in a 'jukebox' mode, it may just append the playlist to the list of upcoming tracks, and skip to the first track in the playlist. ''' pass @DbusMethod(produces=lambda playlist_list: \ [Playlist(playlist) for playlist in playlist_list], args_to_dbus=[UInt64, UInt64, str, bool]) def GetPlaylists(self, Index, MaxCount, Order, ReverseOrder=False): ''' **Parameters:** * Index - u The index of the first playlist to be fetched (according to the ordering). * MaxCount - u The maximum number of playlists to fetch. * Order - s (Playlist_Ordering) The ordering that should be used. * ReverseOrder - b Whether the order should be reversed. **Returns** * Playlists - a(oss) (Playlist_List) A list of (at most MaxCount) playlists. Gets a set of playlists. ''' pass @DbusSignal def PlaylistChanged(self, Playlist): ''' **Parameters** * Playlist - (oss) (Playlist) The playlist whose details have changed. Indicates that the name or icon for a playlist has changed. Note that, for this signal to operate correctly, the id of the playlist must not change when the name changes. ''' pass @DbusAttr def PlaylistCount(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The number of playlists available. ''' pass @DbusAttr def Orderings(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The avaislable orderings. At least one must be offered. ''' pass @DbusAttr(produces=Maybe_Playlist) def ActivePlaylist(self): ''' **Returns** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. The currently-active playlist. If there is no currently-active playlist, the structure's Valid field will be false, and the Playlist details are undefined. Note that this may not have a value even after ActivatePlaylist is called with a valid playlist id as ActivatePlaylist implementations have the option of simply inserting the contents of the playlist into the current tracklist. ''' pass if __name__ == '__main__': from .utils import get_players_uri, implements for uri in get_players_uri(): if implements(uri, Interfaces.PLAYLISTS): mp2 = Playlists(dbus_interface_info={'dbus_uri': uri}) print( mp2.ActivePlaylist ) print( 'Active is valid playlist: ', bool(mp2.ActivePlaylist) ) if mp2.ActivePlaylist: print( 'Active playlist name:', mp2.ActivePlaylist.Playlist.Name ) from mpris2.types import Playlist_Ordering print( hasattr('anystring', 'eusequenaotem') ) print( 'bla', mp2.GetPlaylists(0, 20, Playlist_Ordering.ALPHABETICAL, False) ) break else: print('no player with playlist interface found') autoradio-autoradio-3.6-4/autoradio/mpris2/some_players.py000077500000000000000000000032171454362722700240000ustar00rootroot00000000000000class Some_Players(object): ''' Not defined in documentation Maybe this player (and other) implement mpris2 **Some players** * AUDACIOUS 'audacious' * AUTOPLAYER 'AutoPlayer' * BANSHEE 'banshee' * BEATBOX 'beatbox' * BMP 'bmp' * CLEMENTINE 'clementine' * DRAGONPLAYER 'dragonplayer' * EXAILE 'exaile' * GMUSICBROWSER 'gmusicbrowser' * GMPC 'gmpc' * GUAYADEQUE 'guayadeque' * MOPIDY 'mopidy' * MPDRIS 'mpDris' * QUODLIBET 'quodlibet' * RAVEND 'ravend' * RHYTHMBOX 'rhythmbox' * SPOTIFY 'spotify' * VLC 'vlc' * XBMC 'xbmc' * XMMS2 'xmms2' * XNOISE 'xnoise' ''' AUDACIOUS = 'audacious' AUTOPLAYER = 'AutoPlayer' BANSHEE = 'banshee' BEATBOX = 'beatbox' BMP = 'bmp' CLEMENTINE = 'clementine' DRAGONPLAYER = 'dragonplayer' EXAILE = 'exaile' GMUSICBROWSER = 'gmusicbrowser' GMPC = 'gmpc' GUAYADEQUE = 'guayadeque' MOPIDY = 'mopidy' MPDRIS = 'mpDris' QUODLIBET = 'quodlibet' RAVEND = 'ravend' RHYTHMBOX = 'rhythmbox' SPOTIFY = 'spotify' VLC = 'vlc' XBMC = 'xbmc' XMMS2 = 'xmms2' XNOISE = 'xnoise' @staticmethod def get_dict(): result = {} for key in dir(Some_Players): if key[0] not in ('_', 'g'): result[key] = getattr(Some_Players, key) return result if __name__ == '__main__': print('Well know players:', Some_Players.get_dict().values()) autoradio-autoradio-3.6-4/autoradio/mpris2/tracklist.py000077500000000000000000000245641454362722700233060ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/Track_List_Interface.html ''' from .decorator import DbusAttr from .decorator import DbusMethod from .decorator import DbusSignal from .decorator import DbusInterface from .interfaces import Interfaces from .types import Metadata_Map class TrackList(Interfaces): ''' Interface for TrackList (org.mpris.MediaPlayer2.TrackList) Provides access to a short list of tracks which were recently played or will be played shortly. This is intended to provide context to the currently-playing track, rather than giving complete access to the media player's playlist. Example use cases are the list of tracks from the same album as the currently playing song or the Rhythmbox play queue. Each track in the tracklist has a unique identifier. The intention is that this uniquely identifies the track within the scope of the tracklist. In particular, if a media item (a particular music file, say) occurs twice in the track list, each occurrence should have a different identifier. If a track is removed from the middle of the playlist, it should not affect the track ids of any other tracks in the tracklist. As a result, the traditional track identifiers of URLs and position in the playlist cannot be used. Any scheme which satisfies the uniqueness requirements is valid, as clients should not make any assumptions about the value of the track id beyond the fact that it is a unique identifier. Note that the (memory and processing) burden of implementing the TrackList interface and maintaining unique track ids for the playlist can be mitigated by only exposing a subset of the playlist when it is very long (the 20 or so tracks around the currently playing track, for example). This is a recommended practice as the tracklist interface is not designed to enable browsing through a large list of tracks, but rather to provide clients with context about the currently playing track. ''' PROPERTIES_TACKS = 'Tracks' PROPERTIES_CAN_EDIT_TRACKS = 'CanEditTracks' SIGNALS_TRACK_LIST_REPLACED = 'TrackListReplaced' SIGNALS_TRACK_ADDED = 'TrackAdded' SIGNALS_TRACK_REMOVED = 'TrackRemoved' SIGNALS_TRACK_METADATA_CHANGED = 'TrackMetadataChanged' SIGNALS_PROPERTIES_CHANGED = 'PropertiesChanged' @DbusInterface(Interfaces.TRACK_LIST, Interfaces.OBJECT_PATH) def __init__(self): '''Constructor''' @DbusMethod(produces=lambda map_list:\ [Metadata_Map(metadata_map) for metadata_map in map_list]) def GetTracksMetadata(self, TrackIds): ''' **Parameters:** * TrackIds - ao (Track_Id_List) The list of track ids for which metadata is requested. **Returns** * Metadata - aa{sv} (Metadata_Map_List) Metadata of the set of tracks given as input. See the type documentation for more details. Gets all the metadata available for a set of tracks. Each set of metadata must have a 'mpris:trackid' entry at the very least, which contains a string that uniquely identifies this track within the scope of the tracklist. ''' pass @DbusMethod() def AddTrack(self, Uri, AfterTrack='', SetAsCurrent=False): ''' **Parameters:** * Uri - s (Uri) The uri of the item to add. Its uri scheme should be an element of the org.mpris.MediaPlayer2.SupportedUriSchemes property and the mime-type should match one of the elements of the org.mpris.MediaPlayer2.SupportedMimeTypes * AfterTrack - o (Track_Id) The identifier of the track after which the new item should be inserted. The path /org/mpris/MediaPlayer2/TrackList/NoTrack indicates that the track should be inserted at the start of the track list. * SetAsCurrent - b Whether the newly inserted track should be considered as the current track. Setting this to trye has the same effect as calling GoTo afterwards. Adds a URI in the TrackList. If the CanEditTracks property is false, this has no effect. .. note:: Clients should not assume that the track has been added at the time when this method returns. They should wait for a TrackAdded (or TrackListReplaced) signal. ''' pass @DbusMethod def RemoveTrack(self, TrackId): ''' **Parameters:** * TrackId - o (TrackId) Identifier of the track to be removed. /org/mpris/MediaPlayer2/TrackList/NoTrack is not a valid value for this argument. Removes an item from the TrackList. If the track is not part of this tracklist, this has no effect. If the CanEditTracks property is false, this has no effect. .. note:: Clients should not assume that the track has been removed at the time when this method returns. They should wait for a TrackRemoved (or TrackListReplaced) signal. ''' pass @DbusMethod def GoTo(self, TrackId): ''' **Parameters:** * TrackId - o (Track_Id) Identifier of the track to skip to. /org/mpris/MediaPlayer2/TrackList/NoTrack is not a valid value for this argument. Skip to the specified TrackId. If the track is not part of this tracklist, this has no effect. If this object is not /org/mpris/MediaPlayer2, the current TrackList's tracks should be replaced with the contents of this TrackList, and the TrackListReplaced signal should be fired from /org/mpris/MediaPlayer2. ''' @DbusSignal def TrackListReplaced(self, Tracks, CurrentTrack): ''' **Parameters:** * Tracks - ao (Track_Id_List) The new content of the tracklist. * CurrentTrack - o (Track_Id) The identifier of the track to be considered as current. /org/mpris/MediaPlayer2/TrackList/NoTrack indicates that there is no current track. This should correspond to the mpris:trackid field of the Metadata property of the org.mpris.MediaPlayer2.Player interface. Indicates that the entire tracklist has been replaced. It is left up to the implementation to decide when a change to the track list is invasive enough that this signal should be emitted instead of a series of TrackAdded and TrackRemoved signals. ''' pass @DbusSignal def TrackAdded(self, Metadata, AfterTrack=''): ''' **Parameters:** * Metadata - a{sv} (Metadata_Map) The metadata of the newly added item. This must include a mpris:trackid entry. See the type documentation for more details. * AfterTrack - o (Track_Id) The identifier of the track after which the new track was inserted. The path /org/mpris/MediaPlayer2/TrackList/NoTrack indicates that the track was inserted at the start of the track list. Indicates that a track has been added to the track list. ''' pass @DbusSignal def TrackRemoved(self, TrackId): ''' **Parameters:** * TrackId - o (Track_Id) The identifier of the track being removed. /org/mpris/MediaPlayer2/TrackList/NoTrack is not a valid value for this argument. Indicates that a track has been removed from the track list. ''' pass @DbusSignal def TrackMetadataChanged(self, TrackId, Metadata): ''' **Parameters:** * TrackId - o (Track_Id) The id of the track which metadata has changed. If the track id has changed, this will be the old value. /org/mpris/MediaPlayer2/TrackList/NoTrack is not a valid value for this argument. * Metadata - a{sv} (Metadata_Map) The new track metadata. This must include a mpris:trackid entry. See the type documentation for more details. Indicates that the metadata of a track in the tracklist has changed. This may indicate that a track has been replaced, in which case the mpris:trackid metadata entry is different from the TrackId argument. ''' pass @DbusAttr def Tracks(self): ''' **Returns:** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted, but the new value is not sent. An array which contains the identifier of each track in the tracklist, in order. The org.freedesktop.DBus.Properties.PropertiesChanged signal is emited every time this property changes, but the signal message does not contain the new value. Client implementations should rather rely on the TrackAdded, TrackRemoved and TrackListReplaced signals to keep their representation of the tracklist up to date. ''' pass @DbusAttr def CanEditTracks(self): ''' **Returns:** Read only When this property changes, the org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted with the new value. If false, calling AddTrack or RemoveTrack will have no effect, and may raise a NotSupported error. ''' pass if __name__ == '__main__': from .utils import get_players_uri, implements for uri in get_players_uri(): if implements(uri, Interfaces.TRACK_LIST): # this is optional, maybe running player don't implement it # VLC does if you want try mp2 = TrackList(dbus_interface_info={'dbus_uri': uri}) #print(dir(mp2)) print('Tracks:', mp2.Tracks) print('CanEditTracks:', bool(mp2.CanEditTracks)) break else: print('no player with playlist interface found') autoradio-autoradio-3.6-4/autoradio/mpris2/types/000077500000000000000000000000001454362722700220625ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/mpris2/types/__init__.py000066400000000000000000000006171454362722700241770ustar00rootroot00000000000000from .loop_status import Loop_Status from .metadata_map import Metadata_Map from .playback_rate import Playback_Rate from .playback_status import Playback_Status from .playlist import Playlist from .playlist import Maybe_Playlist from .playlist_id import Playlist_Id from .playlist_ordering import Playlist_Ordering from .time_in_us import Time_In_Us from .uri import Uri from .volume import Volume autoradio-autoradio-3.6-4/autoradio/mpris2/types/__main__.py000066400000000000000000000010651454362722700241560ustar00rootroot00000000000000from . import Loop_Status from . import Metadata_Map from . import Playback_Rate from . import Playback_Status from . import Playlist from . import Maybe_Playlist from . import Playlist_Id from . import Playlist_Ordering from . import Time_In_Us from . import Uri from . import Volume if __name__ == '__main__': print(Loop_Status) print(Metadata_Map) print(Playback_Rate) print(Playback_Status) print(Playlist) print(Playlist_Id) print(Playlist_Ordering) print(Maybe_Playlist) print(Time_In_Us) print(Uri) print(Volume)autoradio-autoradio-3.6-4/autoradio/mpris2/types/loop_status.py000077500000000000000000000017231454362722700250160ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Enum:Loop_Status ''' class Loop_Status(str): ''' A repeat / loop status * None (None) The playback will stop when there are no more tracks to play * Track (Track) The current track will start again from the begining once it has finished playing * Playlist (Playlist) The playback loops through a list of tracks ''' NONE = 'None' TRACK = 'Track' PLAYLIST = 'Playlist' VALUES = (NONE, TRACK, PLAYLIST) def __init__(self, status): self._status = status def __int__(self): return Loop_Status.VALUES.index(self._status) def __str__(self): return self._status if __name__ == '__main__': assert Loop_Status.PLAYLIST != 'None' assert Loop_Status.PLAYLIST == 'Playlist' assert Loop_Status.TRACK == 'Track' assert Loop_Status.NONE == 'None' autoradio-autoradio-3.6-4/autoradio/mpris2/types/metadata_map.py000077500000000000000000000044721454362722700250630ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Track_List_Interface.html#Mapping:Metadata_Map ''' class Metadata_Map(dict): ''' A mapping from metadata attribute names to values. The mpris:trackid attribute must always be present. This contains a string that uniquely identifies the track within the scope of the playlist. If the length of the track is known, it should be provided in the metadata property with the 'mpris:length' key. The length must be given in microseconds, and be represented as a signed 64-bit integer. If there is an image associated with the track, a URL for it may be provided using the 'mpris:artUrl' key. For other metadata, fields defined by the Xesam ontology should be used, prefixed by 'xesam:'. See http://wiki.xmms2.xmms.se/wiki/MPRIS_Metadata for a list of common fields. Lists of strings should be passed using the array-of-string ('as') D-Bus type. Dates should be passed as strings using the ISO 8601 extended format (eg: 2007-04-29T14:35:51). If the timezone is known, RFC 3339's internet profile should be used (eg: 2007-04-29T14:35:51+02:00). * Attribute - s The name of the attribute; see http://wiki.xmms2.xmms.se/wiki/MPRIS_Metadata for guidelines on names to use. * Value - v The value of the attribute, in the most appropriate format. ''' ART_URI = 'mpris:artUrl' TRACKID = 'mpris:trackid' LENGTH = 'mpris:length' ALBUM = 'xesam:album' ALBUM_ARTIST = 'xesam:albumArtist' ARTIST = 'xesam:artist' AS_TEXT = 'xesam:asText' AUDIO_BPM = 'xesam:audioBPM' AUTO_RATING = 'xesam:autoRating' COMMENT = 'xesam:comment' COMPOSER = 'xesam:composer' CONTENT_CREATED = 'xesam:contentCreated' DISC_NUMBER = 'xesam:discNumber' FIRST_USED = 'xesam:firstUsed' GENRE = 'xesam:genre' LAST_USED = 'xesam:lastUsed' LYRICIST = 'xesam:lyricist' TITLE = 'xesam:title' TRACK_NUMBER = 'xesam:trackNumber' URL = 'xesam:url' USE_COUNT = 'xesam:useCount' USER_RATING = 'xesam:userRating' def __init__(self, metadata): super(Metadata_Map, self).__init__(**metadata) if __name__ == '__main__': mdm = Metadata_Map({Metadata_Map.ALBUM : 'Marcelo Nova Ao Vivo'}) assert mdm[Metadata_Map.ALBUM] == 'Marcelo Nova Ao Vivo' autoradio-autoradio-3.6-4/autoradio/mpris2/types/playback_rate.py000077500000000000000000000012121454362722700252340ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Simple-Type:Playback_Rate ''' class Playback_Rate(float): ''' A playback rate This is a multiplier, so a value of 0.5 indicates that playback is happening at half speed, while 1.5 means that 1.5 seconds of 'track time' is consumed every second. ''' def __init__(self, rate=1.0): self._rate = rate def __float__(self): return self._rate def __str__(self): return str(self._rate) if __name__ == '__main__': pr = Playback_Rate(1.2) assert pr == 1.2 autoradio-autoradio-3.6-4/autoradio/mpris2/types/playback_status.py000077500000000000000000000016641454362722700256370ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Enum:Playback_Status ''' class Playback_Status(str): ''' A playback state. * Playing (Playing) A track is currently playing. * Paused (Paused) A track is currently paused. * Stopped (Stopped) There is no track currently playing. ''' PLAYING = 'Playing' PAUSED = 'Paused' STOPPED = 'Stopped' VALUES = (PLAYING, PAUSED, STOPPED) def __init__(self, status): self._status = status def __int__(self): return Playback_Status.VALUES.index(self._status) def __str__(self): return self._status if __name__ == '__main__': assert Playback_Status.PLAYING == 'Playing' assert Playback_Status.PAUSED == 'Paused' assert Playback_Status.STOPPED == 'Stopped' assert Playback_Status.STOPPED != 'Playing' autoradio-autoradio-3.6-4/autoradio/mpris2/types/playlist.py000077500000000000000000000043061454362722700243030ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/Playlists_Interface.html#Struct:Playlist ''' from dbus import Struct class Playlist(Struct): ''' A data structure describing a playlist. * Id - o (Playlist_Id) A unique identifier for the playlist. This should remain the same if the playlist is renamed. * Name - s The name of the playlist, typically given by the user. * Icon - s (Uri) The URI of an (optional) icon. ''' def __init__(self, playlist): Struct.__init__( self, iter(playlist), signature=playlist.signature, variant_level=playlist.variant_level ) @property def Id(self): return self[0] @property def Name(self): return self[1] @property def Icon(self): return self[2] class Maybe_Playlist(Struct): ''' * Valid - b Whether this structure refers to a valid playlist. * Playlist - (oss) (Playlist) The playlist, providing Valid is true, otherwise undefined. When constructing this type, it should be noted that the playlist ID must be a valid object path, or D-Bus implementations may reject it. This is true even when Valid is false. It is suggested that '/' is used as the playlist ID in this case. ''' def __init__(self, maybe_playlist=None): Struct.__init__( self, (maybe_playlist[0], maybe_playlist[1]), signature=maybe_playlist.signature, variant_level=maybe_playlist.variant_level ) @property def Valid(self): return self[0] @property def Playlist(self): return Playlist(self[1]) def __nonzero__(self): return bool(self.Valid) def __bool__(self): return self.__nonzero__() if __name__ == '__main__': expect = Struct((1, 'My Playlist', None), signature='iss') p = Playlist(expect) assert p.Id == 1 assert p.Name == 'My Playlist' assert p.Icon == None m_expect = Struct((False, p)) mp = Maybe_Playlist(m_expect) assert not mp.Valid assert not mp autoradio-autoradio-3.6-4/autoradio/mpris2/types/playlist_id.py000077500000000000000000000007101454362722700247520ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/Playlists_Interface.html#Simple-Type:Playlist_Id ''' class Playlist_Id(str): ''' Unique playlist identifier. ''' def __init__(self, playlist_id): self._playlist_id = playlist_id def __str__(self): return self._status if __name__ == '__main__': pid = Playlist_Id('id of a playlist') assert pid == 'id of a playlist' autoradio-autoradio-3.6-4/autoradio/mpris2/types/playlist_ordering.py000077500000000000000000000022771454362722700262010ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/Playlists_Interface.html#Enum:Playlist_Ordering ''' class Playlist_Ordering(str): ''' Specifies the ordering of returned playlists. * Alphabetical (Alphabetical) Alphabetical ordering by name, ascending. * CreationDate (Created) Ordering by creation date, oldest first. * ModifiedDate (Modified) Ordering by last modified date, oldest first. * LastPlayDate (Played) Ordering by date of last playback, oldest first. * UserDefined (User) A user-defined ordering. ''' ALPHABETICAL = 'Alphabetical' CREATION_DATE = 'CreationDate' MODIFIED_DATE = 'ModifiedDate' LAST_PLAY_DATE = 'LastPlayDate' USER_DEFINE = 'UserDefined' VALUES = (ALPHABETICAL,CREATION_DATE,MODIFIED_DATE,LAST_PLAY_DATE,USER_DEFINE) def __init__(self, ordering): self._ordering = ordering def __str__(self): return self._ordering if __name__ == '__main__': po = Playlist_Ordering('Alphabetical') assert po == 'Alphabetical' assert po == Playlist_Ordering.ALPHABETICAL assert po != Playlist_Ordering.CREATION_DATE autoradio-autoradio-3.6-4/autoradio/mpris2/types/time_in_us.py000077500000000000000000000006661454362722700246020ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Simple-Type:Time_In_Us ''' class Time_In_Us(int): '''Time in microseconds.''' def __init__(self, time=0): self._time = time def __int__(self): return int(self._time) def __str__(self): return str(self._time) if __name__ == '__main__': assert Time_In_Us(10) == 10 autoradio-autoradio-3.6-4/autoradio/mpris2/types/uri.py000077500000000000000000000006111454362722700232340ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/2.2/Playlists_Interface.html#Simple-Type:Uri ''' class Uri(str): '''A unique resource identifier.''' def __init__(self, uri): self._uri = uri def __str__(self): return str(self._uri) if __name__ == '__main__': assert Uri('http://www.com.br') == 'http://www.com.br' autoradio-autoradio-3.6-4/autoradio/mpris2/types/volume.py000077500000000000000000000015531454362722700237520ustar00rootroot00000000000000''' From mprisV2.2 documentation http://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Simple-Type:Volume ''' class Volume(float): ''' Audio volume level * 0.0 means mute. * 1.0 is a sensible maximum volume level (ex: 0dB). Note that the volume may be higher than 1.0, although generally clients should not attempt to set it above 1.0. ''' MIN = 0.0 MAX = 1.0 RANGE = set([n/10.0 for n in range(11)]) def __init__(self, volume=1.0): assert volume <= 1 self._volume = float(volume) def __float__(self): return self._volume def __str__(self): return str(self._volume) if __name__ == '__main__': assert Volume(1) == 1 assert Volume(0.1) == 0.1 assert Volume(1) == 1.0 assert Volume(1.0) == 1 assert Volume(0.1) != 1.2 autoradio-autoradio-3.6-4/autoradio/mpris2/utils.py000077500000000000000000000033031454362722700224320ustar00rootroot00000000000000''' utils functions not defined in espec ''' import re from .interfaces import Interfaces from .decorator.utils import get_session, get_uri, get_mainloop # @UnusedImport from .decorator.utils import list_interfaces as _list_interfaces from .decorator.utils import implements as _implements def get_players_uri(pattern='',busaddress=None): ''' Return string of player bus name @param pattern=None: string RegEx that filter response @return: array string of players bus name ''' return get_uri(Interfaces.MEDIA_PLAYER + '.*' + pattern,busaddress) def get_player_id_from_uri(uri): ''' Returns player mpris2 id from uri @param uri: string mpris2 player dbus uri @return: string mrpis2 id ''' mateched = re.match(Interfaces.MEDIA_PLAYER + '\.(.+)', uri or '') return mateched.groups()[0]\ if mateched\ else '' def get_players_id(pattern=None): ''' Return string of player mpris2 id @param pattern=None: string RegEx that filter response @return: array string of players bus name ''' for item in get_uri(Interfaces.MEDIA_PLAYER + '.*' + pattern): yield get_player_id_from_uri(item) def list_interfaces(uri, path=None, bus=None): return _list_interfaces(uri, path or Interfaces.OBJECT_PATH, bus) def implements(uri, interface, path=Interfaces.OBJECT_PATH, bus=None): return _implements(uri, interface, path or Interfaces.OBJECT_PATH, bus) if __name__ == '__main__': uris = get_players_uri() if not uris: print('No running players') for uri in uris: print(uri, ':') for interface in list_interfaces(uri): print('\t', interface) autoradio-autoradio-3.6-4/autoradio/mpris2client.py000077500000000000000000000056021454362722700224750ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # GPL. (C) 2013 Paolo Patruno. #Connect to player from mpris2.mediaplayer2 import MediaPlayer2 from mpris2.player import Player from mpris2.tracklist import TrackList from mpris2.interfaces import Interfaces from mpris2.some_players import Some_Players from mpris2.utils import get_players_uri from mpris2.utils import get_session from dbus.mainloop.glib import DBusGMainLoop from gi.repository import GLib import dbus def playhandler( *args, **kw): #print args, kw playbackstatus = args[1].get("PlaybackStatus",None) position = args[1].get("Position",None) if playbackstatus is not None: print("PlaybackStatus",playbackstatus) if position is not None: print("Position", position) def trackhandler( *args, **kw): print("forse track list replaced") print(args, kw) DBusGMainLoop(set_as_default=True) #import gobject from gi.repository import GObject as gobject #busaddress='tcp:host=localhost,port=1234' busaddress=None #mloop = gobject.MainLoop() mloop = GLib.MainLoop () uris = get_players_uri(pattern=".",busaddress=busaddress) for uri in uris: #uri = Interfaces.MEDIA_PLAYER + '.' + Some_Players.AUDACIOUS #uri = Interfaces.MEDIA_PLAYER + '.' + Some_Players.AUTOPLAYER #uri = Interfaces.MEDIA_PLAYER + '.' +'AutoPlayer' print(uri) if busaddress is None: bus = dbus.SessionBus() else: bus =dbus.bus.BusConnection(busaddress) mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) #Call methods #play.Next() # play next media #Get attributes #print play.Metadata #current media data print(play.PlaybackStatus) play.PropertiesChanged = playhandler try: if mp2.HasTrackList: tl = TrackList(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus}) tl.PropertiesChanged = trackhandler tl.TrackListReplaced = trackhandler # attributes and methods together for track in tl.GetTracksMetadata( tl.Tracks): print(track.get(u'mpris:trackid',None),track.get(u'mpris:length',None),track.get(u'xesam:artist',None), track.get(u'xesam:title',None)) except: print("mmm audacious mpris2 interface is buggy") #play with the first player mloop.run() else: print("No players availables") #s = get_session() #s.add_signal_receiver(handler, # "PropertiesChanged", # "org.freedesktop.DBus.Properties", # path="/org/mpris/MediaPlayer2") # Interfaces.SIGNAL, # Interfaces.PROPERTIES, # uri, # Interfaces.OBJECT_PATH) #def my_handler(self, Position): # print 'handled', Position, type(Position) # print 'self handled', self.last_fn_return, type(self.last_fn_return) autoradio-autoradio-3.6-4/autoradio/mprisweb.py000066400000000000000000000157201454362722700217110ustar00rootroot00000000000000#!/usr/bin/env python # coding=utf-8 """ Show mediaplayer playlist on a simple web server. """ #try: # import sys,glob # from distutils.sysconfig import get_python_lib # compatCherryPyPath = glob.glob( get_python_lib()+"/CherryPy-2.*").pop() # sys.path.insert(0, compatCherryPyPath) #finally: from . import autoradio_config import cherrypy import os import datetime from . import autompris from . import autompris2 cpversion3=cherrypy.__version__.startswith("3") cpversion5=cherrypy.__version__.startswith("5") maxplele=100 # max number of elements in playlist port=8888 # server port head=''' MediaPlayer monitor | ''' tail=''' ''' class HomePage(object): # def Main(self): # # Let's link to another method here. # htmlresponse='Goto player status for autoradio!
' # htmlresponse+='Goto player playlist for autoradio!
' # return htmlresponse # Main.exposed = True def __init__(self,iht,player,session): self.iht=iht self.player=player self.session=session def test(self): "return test page" return "Test Page" test.exposed = True # def status(self): # "return media player status" # # try: # # --------------------------------- # org_obj = bus.get_object("org.atheme.audacious", '/org/atheme/audacious') # org = dbus.Interface(org_obj, dbus_interface='org.atheme.audacious') # # --------------------------------- # except: # # return "error intializing dbus" # # if (org.Playing()): # return "player is playing" # else: # return "player is stopped" # # # # status.exposed = True def index(self): "return media player playlist" if (self.iht) : htmlresponse=head else: htmlresponse="" try: if self.player == "vlc" or self.player == "AutoPlayer": mp= autompris2.mediaplayer(player=self.player,session=0) else: mp= autompris.mediaplayer(player=self.player,session=0) except: return "error intializing dbus" try: cpos=mp.get_playlist_pos() if cpos is None: cpos=0 cpos=int(cpos) except: return "error get_playlist_pos()" try: isplaying= mp.isplaying() except: return "error isplaying()" try: len=mp.get_playlist_len() htmlresponse+='

player have %i songs in playlist // song number %i selected

' % (len,cpos+1) htmlresponse+='' htmlresponse+='' for pos in range(0,min(len,maxplele)): htmlresponse+='' metadata=mp.get_metadata(pos) timelength=datetime.timedelta(seconds=datetime.timedelta(milliseconds=metadata["mtimelength"]).seconds) timeposition=datetime.timedelta(seconds=datetime.timedelta(milliseconds=metadata["mtimeposition"]).seconds) if pos == cpos and isplaying: col="#FF0000" toend=timelength-timeposition elif pos < cpos : col="#0000FF" toend="" else: col="#00FF00" toend="" if (metadata["artist"] is not None) or (metadata["title"] is not None): htmlresponse+='' % \ (col,pos+1,str(timelength),str(toend),metadata["file"],metadata["artist"],metadata["title"]) else: purefilename=os.path.splitext(metadata["file"])[0] htmlresponse+='' % \ (col,pos+1,str(timelength),str(toend),metadata["file"],os.path.basename(purefilename)) htmlresponse+='' except: htmlresponse+='error getting player information' htmlresponse+='
positionlenght // remainmedia
%i %s // %s %s // %s%i %s // %s %s
' try: if len > maxplele : htmlresponse+="

ATTENTION: there are more file than you can see here.

" except: pass if (self.iht) : htmlresponse+=tail return htmlresponse index.exposed = True def start_http_server(iht=False,player="AutoPlayer",session=0): """ start web server to monitor player iht=False # do not emit header e tail """ #import os #pid = os.fork() settings = { 'global': { 'server.socket_port' : port, 'server.socket_host': "0.0.0.0", 'server.socket_file': "", 'server.socket_queue_size': 5, 'server.protocol_version': "HTTP/1.0", 'server.log_to_screen': False, 'server.log_file': "/tmp/mprisweb.log", 'server.reverse_dns': False, 'server.thread_pool': 10, 'server.environment': "development", #'server.environment': "production", 'tools.encode.on':True, # 'tools.encode.encoding':'utf8', }, } # CherryPy always starts with cherrypy.root when trying to map request URIs # to objects, so we need to mount a request handler object here. A request # to '/' will be mapped to cherrypy.root.index(). if (cpversion3 or cpversion5): cherrypy.quickstart(HomePage(iht,player,session),config=settings) else: cherrypy.config.update(settings) cherrypy.root = HomePage(iht,player,session) cherrypy.server.start() def main(): # Set the signal handler #import signal #signal.signal(signal.SIGINT, signal.SIG_IGN) # Start the CherryPy server. try: start_http_server(iht=True,player=autoradio_config.player,session=0) except: print("Error") raise finally: print("Terminated") if __name__ == '__main__': main() autoradio-autoradio-3.6-4/autoradio/player/000077500000000000000000000000001454362722700207765ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/player/__init__.py000066400000000000000000000000331454362722700231030ustar00rootroot00000000000000VERSION = (0, "1.0", None) autoradio-autoradio-3.6-4/autoradio/player/urls.py000066400000000000000000000003251454362722700223350ustar00rootroot00000000000000from django.conf.urls import * from . import views urlpatterns = [ # Episode detail of one show url(r'^nohtml5/(?P(.*))', views.playernohtml5cmd), url(r'^(?P(.*))', views.playercmd), ] autoradio-autoradio-3.6-4/autoradio/player/views.py000066400000000000000000000010231454362722700225010ustar00rootroot00000000000000from django.shortcuts import render_to_response import autoradio.settings def playercmd(request, media): """ player commander Template: ``player/player.html`` Context: play a media file """ return render_to_response('player/player.html', {'media': media}) def playernohtml5cmd(request, media): """ player commander for no html5 Template: ``player/playernohtml5.html`` Context: play a media file """ return render_to_response('player/playernohtml5.html', {'media': media}) autoradio-autoradio-3.6-4/autoradio/playlists/000077500000000000000000000000001454362722700215265ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/playlists/__init__.py000066400000000000000000000000001454362722700236250ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/playlists/admin.py000066400000000000000000000035041454362722700231720ustar00rootroot00000000000000from .models import Giorno, Configure, Playlist, Schedule, PeriodicSchedule from django.contrib import admin class ScheduleInline(admin.StackedInline): #class ScheduleInline(admin.TabularInline): model = Schedule extra=2 class PeriodicScheduleInline(admin.StackedInline): model = PeriodicSchedule extra=2 class GiornoAdmin(admin.ModelAdmin): search_fields = ['name'] admin.site.register(Giorno, GiornoAdmin) class ConfigureAdmin(admin.ModelAdmin): list_display = ('sezione','active',\ 'emission_starttime'\ ,'emission_endtime') admin.site.register(Configure, ConfigureAdmin) class PlaylistAdmin(admin.ModelAdmin): fieldsets = ( (None, {'fields': ('playlist','file')}), ('Date information', {'fields': ('rec_date','active',)}), ) list_display = ('playlist','rec_date','was_recorded_today','active') search_fields = ['playlist','file'] date_hierarchy = 'rec_date' list_filter = ['rec_date','active'] inlines = [ ScheduleInline,PeriodicScheduleInline, ] admin.site.register(Playlist, PlaylistAdmin) class ScheduleAdmin(admin.ModelAdmin): list_display = ('file', 'shuffle','length','emission_date','emission_done'\ ,'was_scheduled_today') list_filter = ['emission_date','emission_done'] search_fields = ['playlist','emission_date'] date_hierarchy = 'emission_date' admin.site.register(Schedule, ScheduleAdmin) class PeriodicScheduleAdmin(admin.ModelAdmin): list_display = ('file', 'shuffle','length','start_date','end_date','time'\ ,'emission_done') list_filter = ['start_date','end_date','time','giorni','emission_done'] search_fields = ['playlist','giorni'] date_hierarchy = 'start_date' admin.site.register(PeriodicSchedule, PeriodicScheduleAdmin) autoradio-autoradio-3.6-4/autoradio/playlists/migrations/000077500000000000000000000000001454362722700237025ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/playlists/migrations/0001_initial.py000066400000000000000000000121031454362722700263420ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9 on 2016-01-25 17:58 import autoradio.playlists.models from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Configure', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('sezione', models.CharField(default=b'playlist', editable=False, max_length=50, unique=True)), ('active', models.BooleanField(default=True, help_text='activate/deactivate the intere playlist class', verbose_name='Activate Playlist')), ('emission_starttime', models.TimeField(blank=True, help_text='The start time from wich the playlist will be active', null=True, verbose_name='Programmed start time')), ('emission_endtime', models.TimeField(blank=True, help_text='The end time the playlist will be active', null=True, verbose_name='Programmed start time')), ], ), migrations.CreateModel( name='Giorno', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(choices=[('luned\xec', 'luned\xec'), ('marted\xec', 'marted\xec'), ('mercoled\xec', 'mercoled\xec'), ('gioved\xec', 'gioved\xec'), ('venerd\xec', 'venerd\xec'), ('sabato', 'sabato'), ('domenica', 'domenica')], help_text='weekday name', max_length=20, unique=True)), ], ), migrations.CreateModel( name='PeriodicSchedule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('shuffle', models.BooleanField(default=True, help_text="Every time the playlist will be scheduled it's order will be randomly changed", verbose_name='Shuffle Playlist on start')), ('length', models.FloatField(blank=True, default=None, help_text='If this time is set the playlist will be truncated', null=True, verbose_name='Max time length (seconds)')), ('start_date', models.DateField(blank=True, help_text='The playlist will be scheduled starting from this date', null=True, verbose_name='Programmed start date')), ('end_date', models.DateField(blank=True, help_text='The playlist will be scheduled ending this date', null=True, verbose_name='Programmed end date')), ('time', models.TimeField(blank=True, help_text='This is the time when the playlist will be on air', null=True, verbose_name='Programmed time')), ('emission_done', models.DateTimeField(editable=False, null=True, verbose_name='Emission done')), ('giorni', models.ManyToManyField(blank=True, help_text='The playlist will be scheduled those weekdays', to='playlists.Giorno', verbose_name='Programmed days')), ], ), migrations.CreateModel( name='Playlist', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('playlist', models.CharField(max_length=200, verbose_name='Playlist name')), ('file', autoradio.playlists.models.DeletingFileField(help_text='The playlist file to upload, format should be extm3u, m3u, pls', max_length=255, upload_to=b'playlist', verbose_name='File')), ('rec_date', models.DateTimeField(help_text='When the playlist was done (for reference only)', verbose_name='Generation date')), ('active', models.BooleanField(default=True, help_text='Activate the playlist for emission', verbose_name='Active')), ], ), migrations.CreateModel( name='Schedule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('shuffle', models.BooleanField(default=True, help_text="Every time the playlist will be scheduled it's order will be randomly changed", verbose_name='Shuffle Playlist on start')), ('length', models.FloatField(blank=True, default=None, help_text='If this time is set the playlist will be truncated', null=True, verbose_name='Max time length (seconds)')), ('emission_date', models.DateTimeField(help_text='This is the date and time when the playlist will be on air', verbose_name='Programmed date')), ('emission_done', models.DateTimeField(editable=False, null=True, verbose_name='Emission done')), ('playlist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='playlists.Playlist', verbose_name='refer to playlist:')), ], ), migrations.AddField( model_name='periodicschedule', name='playlist', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='playlists.Playlist', verbose_name='refer to playlist:'), ), ] autoradio-autoradio-3.6-4/autoradio/playlists/migrations/0002_auto_20180721_1059.py000066400000000000000000000012771454362722700273360ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.10.5 on 2018-07-21 10:59 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('playlists', '0001_initial'), ] operations = [ migrations.AlterField( model_name='giorno', name='name', field=models.CharField(choices=[(b'luned\xc3\xac', b'luned\xc3\xac'), (b'marted\xc3\xac', b'marted\xc3\xac'), (b'mercoled\xc3\xac', b'mercoled\xc3\xac'), (b'gioved\xc3\xac', b'gioved\xc3\xac'), (b'venerd\xc3\xac', b'venerd\xc3\xac'), (b'sabato', b'sabato'), (b'domenica', b'domenica')], help_text='weekday name', max_length=20, unique=True), ), ] autoradio-autoradio-3.6-4/autoradio/playlists/migrations/__init__.py000066400000000000000000000000001454362722700260010ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/playlists/models.py000066400000000000000000000201261454362722700233640ustar00rootroot00000000000000from django.db import models from django.utils.translation import ugettext_lazy import datetime import calendar from autoradio.autoradio_config import * from django import VERSION as djversion if ((djversion[0] == 1 and djversion[1] >= 3) or djversion[0] > 1): from django.db import models from django.db.models import signals class DeletingFileField(models.FileField): """ FileField subclass that deletes the refernced file when the model object itself is deleted. WARNING: Be careful using this class - it can cause data loss! This class makes at attempt to see if the file's referenced elsewhere, but it can get it wrong in any number of cases. """ def contribute_to_class(self, cls, name): super(DeletingFileField, self).contribute_to_class(cls, name) signals.post_delete.connect(self.delete_file, sender=cls) def delete_file(self, instance, sender, **kwargs): file = getattr(instance, self.attname) # If no other object of this type references the file, # and it's not the default value for future objects, # delete it from the backend. if file and file.name != self.default and \ not sender._default_manager.filter(**{self.name: file.name}): file.delete(save=False) elif file: # Otherwise, just close the file, so it doesn't tie up resources. file.close() else: DeletingFileField=models.FileField def giorno_giorno(): giorni=[] for giorno in (calendar.day_name): #giorno=giorno.decode('utf-8') giorni.append(( giorno, giorno)) return giorni # yield 'Tutti','Tutti' class Giorno(models.Model): name = models.CharField(max_length=20,choices=giorno_giorno(),unique=True,\ help_text=ugettext_lazy("weekday name")) def __str__(self): return self.name class Configure(models.Model): sezione = models.CharField(max_length=50,unique=True\ ,default='playlist',editable=False) active = models.BooleanField(ugettext_lazy("Activate Playlist"),default=True,\ help_text=ugettext_lazy("activate/deactivate the intere playlist class")) emission_starttime = models.TimeField(ugettext_lazy('Programmed start time'),null=True,blank=True,\ help_text=ugettext_lazy("The start time from wich the playlist will be active")) emission_endtime = models.TimeField(ugettext_lazy('Programmed start time'),null=True,blank=True,\ help_text=ugettext_lazy("The end time the playlist will be active")) def __str__(self): if self.emission_starttime is None: start="-" else: start=self.emission_starttime.isoformat() if self.emission_endtime is None: end="-" else: end=self.emission_endtime.isoformat() return self.sezione+" "+self.active.__str__()+" "+start+" "+end class Playlist(models.Model): playlist = models.CharField(ugettext_lazy('Playlist name'),max_length=200) file = DeletingFileField(ugettext_lazy('File'),upload_to='playlist',max_length=255,\ help_text=ugettext_lazy("The playlist file to upload, format should be extm3u, m3u, pls")) rec_date = models.DateTimeField(ugettext_lazy('Generation date'),\ help_text=ugettext_lazy("When the playlist was done (for reference only)")) active = models.BooleanField(ugettext_lazy("Active"),default=True,\ help_text=ugettext_lazy("Activate the playlist for emission")) def was_recorded_today(self): return self.rec_date.date() == datetime.date.today() was_recorded_today.short_description = ugettext_lazy('Generated today?') def __str__(self): #return self.playlist+" "+self.rec_date.isoformat()+" "+self.active.__str__() return self.playlist class Schedule(models.Model): # program = models.ForeignKey(Program, edit_inline=models.TABULAR,\ # num_in_admin=2,verbose_name='si riferisce al programma:',editable=False) playlist = models.ForeignKey(Playlist, verbose_name=\ ugettext_lazy('refer to playlist:'), on_delete=models.CASCADE) shuffle = models.BooleanField(ugettext_lazy("Shuffle Playlist on start"),default=True,\ help_text=ugettext_lazy("Every time the playlist will be scheduled it's order will be randomly changed")) length = models.FloatField(ugettext_lazy("Max time length (seconds)"),default=None,null=True,blank=True,\ help_text=ugettext_lazy("If this time is set the playlist will be truncated")) emission_date = models.DateTimeField(ugettext_lazy('Programmed date'),\ help_text=ugettext_lazy("This is the date and time when the playlist will be on air")) # da reinserire ! # start_date = models.DateField('Data inizio programmazione',null=True,blank=True) # end_date = models.DateField('Data fine programmazione',null=True,blank=True) # time = models.TimeField('Ora programmazione',null=True,blank=True) # giorni = models.ManyToManyField(Giorno,verbose_name='Giorni programmati',null=True,blank=True) emission_done = models.DateTimeField(ugettext_lazy('Emission done')\ ,null=True,editable=False ) # def emitted(self): # return self.emission_done != None # emitted.short_description = 'Trasmesso' def was_scheduled_today(self): return self.emission_date.date() == datetime.date.today() was_scheduled_today.short_description = ugettext_lazy('Programmed for today?') def file(self): return self.playlist.playlist file.short_description = ugettext_lazy('Linked Playlist') def __str__(self): return str(self.playlist) class PeriodicSchedule(models.Model): # program = models.ForeignKey(Program, edit_inline=models.TABULAR,\ # num_in_admin=2,verbose_name='si riferisce al programma:',editable=False) playlist = models.ForeignKey(Playlist,verbose_name=\ ugettext_lazy('refer to playlist:'), on_delete=models.CASCADE) shuffle = models.BooleanField(ugettext_lazy("Shuffle Playlist on start"),default=True,\ help_text=ugettext_lazy("Every time the playlist will be scheduled it's order will be randomly changed")) length = models.FloatField(ugettext_lazy("Max time length (seconds)"),default=None,null=True,blank=True,\ help_text=ugettext_lazy("If this time is set the playlist will be truncated")) start_date = models.DateField(ugettext_lazy('Programmed start date'),null=True,blank=True,\ help_text=ugettext_lazy("The playlist will be scheduled starting from this date")) end_date = models.DateField(ugettext_lazy('Programmed end date'),null=True,blank=True,\ help_text=ugettext_lazy("The playlist will be scheduled ending this date")) time = models.TimeField(ugettext_lazy('Programmed time'),null=True,blank=True,\ help_text=ugettext_lazy("This is the time when the playlist will be on air")) giorni = models.ManyToManyField(Giorno,verbose_name=ugettext_lazy('Programmed days'),blank=True,\ help_text=ugettext_lazy("The playlist will be scheduled those weekdays")) emission_done = models.DateTimeField(ugettext_lazy('Emission done')\ ,null=True,editable=False ) # def emitted(self): # return self.emission_done != None # emitted.short_description = 'Trasmesso' def file(self): return self.playlist.playlist file.short_description = ugettext_lazy('Linked Playlist') def __str__(self): return str(self.playlist) autoradio-autoradio-3.6-4/autoradio/playlists/views.py000066400000000000000000000000321454362722700232300ustar00rootroot00000000000000# Create your views here. autoradio-autoradio-3.6-4/autoradio/programs/000077500000000000000000000000001454362722700213345ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/__init__.py000066400000000000000000000000001454362722700234330ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/admin.py000066400000000000000000000361271454362722700230070ustar00rootroot00000000000000from django.contrib import admin from .models import Giorno, Configure, ProgramType, Show, Schedule, \ PeriodicSchedule,AperiodicSchedule,Episode,Enclosure,ScheduleDone from autoradio.programs.models import ParentCategory, ChildCategory, MediaCategory from django import forms from django.utils.translation import ugettext_lazy import autoradio.settings import autoradio.mime import magic ma = magic.open(magic.MAGIC_MIME_TYPE) ma.load() class MyEnclosureInlineFormset(forms.models.BaseInlineFormSet): def clean(self): import mutagen, os # get forms that actually have valid data count = 0 for form in self.forms: try: if form.cleaned_data: count += 1 file = form.cleaned_data.get('file',False) if file: if autoradio.settings.permit_no_playable_files: try: type = file.content_type in webmime_audio except: #here when the file is not uploaded (modify for example) return file if not type: raise forms.ValidationError(ugettext_lazy("Browser say that Content-Type is not audio")) if not os.path.splitext(file.name)[1] in websuffix_audio: raise forms.ValidationError(ugettext_lazy("Doesn't have proper extension: .mp3, .wav, .ogg, .oga, .flac")) try: mime = ma.file(file.temporary_file_path()) audio = mime in mymime_audio except: audio=False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file")) if autoradio.settings.require_tags_in_enclosure: #Check file if it is a known media file. The check is based on mutagen file test. try: audio = not mutagen.File(file.temporary_file_path()) is None except: audio = False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file: probably no tags present")) else: try: type = file.content_type in webmime_ogg except: #here when the file is not uploaded (modify for example) return file if not type: raise forms.ValidationError(ugettext_lazy("Browser say that Content-Type is not audio ogg vorbis")) if not os.path.splitext(file.name)[1] in websuffix_ogg: raise forms.ValidationError(ugettext_lazy("Doesn't have proper extension: .ogg, .oga")) try: mime = ma.file(file.temporary_file_path()) audio = mime in mymime_ogg except: audio=False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid ogg/oga vorbis audio file")) if autoradio.settings.require_tags_in_enclosure: #Check file if it is a known media file. The check is based on mutagen file test. try: mut=mutagen.File(file.temporary_file_path()) audio = not mut is None sample_rate=mut.info.sample_rate except: audio = False sample_rate=0 if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid ogg/oga vorbis audio file: probably no tags present")) if not sample_rate == 44100: raise forms.ValidationError(ugettext_lazy("Sample rate is Not 44100Hz: cannot use it in podcasting web interface")) return file else: raise forms.ValidationError(ugettext_lazy("Couldn't read uploaded file")) except AttributeError: # annoyingly, if a subform is invalid Django explicity raises # an AttributeError for cleaned_data pass if count < 1: raise forms.ValidationError(ugettext_lazy('You must have at least one Enclosure')) class MyEnclosureAdminForm(forms.ModelForm): """ Check file if it is a known media file. """ class Meta(object): model = Enclosure fields = '__all__' def clean_file(self): import mutagen, os file = self.cleaned_data.get('file',False) if file: if autoradio.settings.permit_no_playable_files: try: type = file.content_type in ["audio/mpeg","audio/flac","video/ogg"] except: return file if not type: raise forms.ValidationError(ugettext_lazy("Content-Type is not audio/mpeg or audio/flac or video/ogg")) if not os.path.splitext(file.name)[1] in [".mp3",".wav",".ogg",".oga",".flac", ".Mp3",".Wav",".Ogg",".Oga",".Flac", ".MP3",".WAV",".OGG",".OGA",".FLAC" ]: raise forms.ValidationError(ugettext_lazy("Doesn't have proper extension: .mp3, .wav, .ogg, .oga, .flac")) #Check file if it is a known media file. The check is based on mutagen file test. try: audio = not mutagen.File(file.temporary_file_path()) is None except: audio = False if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file")) return file else: try: type = file.content_type in ["video/ogg","audio/oga"] except: return file if not type: raise forms.ValidationError(ugettext_lazy("Content-Type is not audio/oga or video/ogg")) if not os.path.splitext(file.name)[1] in [".ogg",".oga",".Ogg",".Oga",".OGG"]: raise forms.ValidationError(ugettext_lazy("Doesn't have proper extension: .ogg, .oga")) #Check file if it is a known media file. The check is based on mutagen file test. try: mut=mutagen.File(file.temporary_file_path()) audio = not mut is None sample_rate=mut.info.sample_rate except: audio = False sample_rate=0 if not audio: raise forms.ValidationError(ugettext_lazy("Not a valid audio file")) if not sample_rate == 44100: raise forms.ValidationError(ugettext_lazy("Sample rate is Not 44100Hz: cannot use it in podcasting web interface")) return file else: raise forms.ValidationError(ugettext_lazy("Couldn't read uploaded file")) class CategoryInline(admin.StackedInline): model = ChildCategory extra = 3 class ParentCategoryAdmin(admin.ModelAdmin): list_display = ('name',) inlines = [CategoryInline,] class ChildCategoryAdmin(admin.ModelAdmin): list_display = ('parent', 'name') class MediaCategoryAdmin(admin.ModelAdmin): list_display = ('name',) admin.site.register(ParentCategory, ParentCategoryAdmin) admin.site.register(ChildCategory, ChildCategoryAdmin) admin.site.register(MediaCategory, MediaCategoryAdmin) class EnclosureInline(admin.StackedInline): model = Enclosure extra=1 max_num=10 fieldsets = ( (None, { 'fields': ('title', 'file',) }), ('Podcast options', { 'classes': ('collapse',), 'fields': ('mime', 'medium','expression','frame','bitrate',\ 'sample','channel','algo','hash','player','embed','width','height') }), ) formset = MyEnclosureInlineFormset class ScheduleInline(admin.StackedInline): #class ScheduleInline(admin.TabularInline): model = Schedule extra=2 max_num=10 class PeriodicScheduleInline(admin.StackedInline): model = PeriodicSchedule extra=2 class AperiodicScheduleInline(admin.StackedInline): model = AperiodicSchedule extra=2 class EpisodeInline(admin.StackedInline): model = Episode extra=1 # not supported #inline=(ScheduleInline,EnclosureInline,) fieldsets = ( (None, { 'fields': ('show', 'author', 'title_type', 'title', 'slug', 'description_type', 'description') }), ('podcast options', { 'classes': ('collapse',), 'fields': ('captions', 'category', 'domain', 'frequency', 'priority', 'status') }), ('iTunes options', { 'classes': ('collapse',), 'fields': ('subtitle', 'summary', ('minutes', 'seconds'), 'keywords', ('explicit', 'block')) }), ('Media RSS options', { 'classes': ('collapse',), 'fields': ('role', 'media_category', ('standard', 'rating'), 'image', 'text', ('deny', 'restriction')) }), ('Dublin Core options', { 'classes': ('collapse',), 'fields': (('start', 'end'), 'scheme', 'name') }), ('Google Media options', { 'classes': ('collapse',), 'fields': ('preview', ('preview_start_mins', 'preview_start_secs'), ('preview_end_mins', 'preview_end_secs'), 'host') }), ) class GiornoAdmin(admin.ModelAdmin): search_fields = ['name'] admin.site.register(Giorno, GiornoAdmin) class ConfigureAdmin(admin.ModelAdmin): list_display = ('sezione','radiostation','channel','active',\ 'emission_starttime'\ ,'emission_endtime') admin.site.register(Configure, ConfigureAdmin) class ProgramTypeAdmin(admin.ModelAdmin): list_display = ('code','type','subtype','description') admin.site.register(ProgramType, ProgramTypeAdmin) class ShowAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ("title",)} fieldsets = ( (None, {'fields': ('title','slug','length','type','production',\ 'organization','link','description','author')}), ('Podcast options', { 'classes': ('collapse',), 'fields': ('language','copyright','copyright_url',\ 'webmaster','category_show',\ 'domain','ttl','image','feedburner')}), ('iTunes options', { 'classes': ('collapse',), 'fields': ('subtitle','summary','category','explicit',\ 'block','redirect','keywords','itunes')}) ) list_display = ('title',) #list_filter = ['end_date',] search_fields = ['title',] # is better without EpisodeInline and start from Episode # inlines = [ # EpisodeInline,PeriodicScheduleInline,AperiodicScheduleInline # ] inlines = [ PeriodicScheduleInline,AperiodicScheduleInline ] admin.site.register(Show, ShowAdmin) class EpisodeAdmin(admin.ModelAdmin): inlines = [ ScheduleInline,EnclosureInline ] prepopulated_fields = {'slug': ("title",)} search_fields = ['title',] list_display = ('title', 'update', 'show') list_filter = ('show', 'update') radio_fields = {'title_type': admin.HORIZONTAL, 'description_type': admin.HORIZONTAL, 'status': admin.HORIZONTAL} fieldsets = ( (None, { 'fields': ('show', 'author', 'title_type', 'title', 'slug', 'description_type', 'description') }), ('podcast options', { 'classes': ('collapse',), 'fields': ('captions', 'category', 'domain', 'frequency', 'priority', 'status') }), ('iTunes options', { 'classes': ('collapse',), 'fields': ('subtitle', 'summary', ('minutes', 'seconds'), 'keywords', ('explicit', 'block')) }), ('Media RSS options', { 'classes': ('collapse',), 'fields': ('role', 'media_category', ('standard', 'rating'), 'image', 'text', ('deny', 'restriction')) }), ('Dublin Core options', { 'classes': ('collapse',), 'fields': (('start', 'end'), 'scheme', 'name') }), ('Google Media options', { 'classes': ('collapse',), 'fields': ('preview', ('preview_start_mins', 'preview_start_secs'), ('preview_end_mins', 'preview_end_secs'), 'host') }), ) admin.site.register(Episode, EpisodeAdmin) class ScheduleAdmin(admin.ModelAdmin): list_display = ('episode', 'emission_date'\ ,'was_scheduled_today') list_filter = ['emission_date'] search_fields = ['episode','emission_date'] date_hierarchy = 'emission_date' admin.site.register(Schedule, ScheduleAdmin) class PeriodicScheduleAdmin(admin.ModelAdmin): list_display = ('start_date','end_date','time') list_filter = ['start_date','end_date','time','giorni'] search_fields = ['playlist','giorni'] date_hierarchy = 'start_date' admin.site.register(PeriodicSchedule, PeriodicScheduleAdmin) class AperiodicScheduleAdmin(admin.ModelAdmin): list_display = ('emission_date','show') search_fields = ['show'] date_hierarchy = 'emission_date' admin.site.register(AperiodicSchedule, AperiodicScheduleAdmin) class ScheduleDoneAdmin(admin.ModelAdmin): list_display = ('emission_done','schedule','enclosure') search_fields = ['enclosure'] date_hierarchy = 'emission_done' admin.site.register(ScheduleDone, ScheduleDoneAdmin) class EnclosureAdmin(admin.ModelAdmin): list_display = ('episode','title',) list_filter = ['medium','mime','bitrate'] search_fields = ['title','file'] fieldsets = ( (None, { 'fields': ('episode','title', 'file',) }), ('Podcast options', { 'classes': ('collapse',), 'fields': ('mime', 'medium','expression','frame','bitrate',\ 'sample','channel','algo','hash','player','embed','width','height') }), ) form = MyEnclosureAdminForm admin.site.register(Enclosure, EnclosureAdmin) autoradio-autoradio-3.6-4/autoradio/programs/fixtures/000077500000000000000000000000001454362722700232055ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/fixtures/initial_data.json000066400000000000000000000372061454362722700265320ustar00rootroot00000000000000 [ {"pk": 1, "model": "programs.programtype", "fields": { "code":"1a", "type": "Notiziari", "subtype": "Telegiornale","description": "Trasmissione a carattere informativo con programmazione quotidiana all'interno di fasce orarie prestabilite"}}, {"pk": 2, "model": "programs.programtype", "fields": { "code":"1b", "type": "Notiziari","subtype": "Telegiornale sportivo" ,"description": "Trasmissione di informazione sportiva con programmazione quotidiana all'interno di fasce orarie prestabilite." }}, {"pk": 3, "model": "programs.programtype", "fields": { "code":"1c" ,"type": "Notiziari", "subtype":"Servizi teletext" }}, {"pk": 4, "model": "programs.programtype", "fields": { "code":"2a" ,"type": "Giochi", "subtype":"Telequiz","description":"Trasmissioni di quiz in diretta o registrati, in studio e con concorrenti, caratterizzati dal succedersi di domande e risposte con vincite di premi non simbolici." }}, {"pk": 5, "model": "programs.programtype", "fields": { "code":"2b" ,"type": "Giochi","subtype": "Giochi televisivi" ,"description":"Trasmissioni di giochi in studio con concorrenti o telespettaori che vi partecipano, con vincite di premi non simbolici o denaro." }}, {"pk": 6, "model": "programs.programtype", "fields": { "code":"3" , "type": "Talk Show", "subtype":"Talk Show" , "description":"Programmi con ospiti in studio (ed eventualmente anche pubblico) che dibattono argomenti vari con un intrattenitore che media tra i vari interventi per animare la conversazione." }}, {"pk": 7, "model": "programs.programtype", "fields": { "code":"4", "type": "Manifestazioni sportive","subtype": "Manifestazioni sportive","description": "Manifestazioni (in diretta o in differita) a carattere sportivo (sport riconosciuti dal CONI)." }}, {"pk": 8, "model": "programs.programtype", "fields": { "code":"5a", "type": "Pubblicit\u00e0","subtype": "Pubblicit\u00e0" }}, {"pk": 9, "model": "programs.programtype", "fields": { "code":"5b", "type": "Pubblicit\u00e0","subtype": "Telepromozioni" }}, {"pk": 10, "model": "programs.programtype", "fields": { "code":"5c", "type": "Pubblicit\u00e0", "subtype":"Sponsorizzazioni" }}, {"pk": 11, "model": "programs.programtype", "fields": { "code":"6", "type":"Televendite" ,"subtype":"Televendite" }}, {"pk": 12, "model": "programs.programtype", "fields": { "code":"7a","type": "Film", "subtype":"Film cinematografici", "description": "Produzioni filmiche destinate principalmente al circuito cinematografico e prodotte su pellicola." }}, {"pk": 13, "model": "programs.programtype", "fields": { "code":"7b", "type":"Film", "subtype":"Film TV", "description": "Produzioni filmiche su supporto magnetico, di durata massima di 200 minuti, eccezionalmente composte di due episodi." }}, {"pk": 14, "model": "programs.programtype", "fields": { "code":"8a", "type":"Fiction", "subtype":"Miniserie - sceneggiato", "description": "Fiction di produzione italiana che contenga un numero minimo di 5 puntate. Le puntate di circa 60 minuti hanno il finale aperto che si chiude con l'ultima puntata." }}, {"pk": 15, "model": "programs.programtype", "fields": { "code":"8b", "type":"Fiction", "subtype":"Telefilm", "description": "Serie costituita da episodi che non superano mai i 60 minuti che propongono storie autonome (con finale chiuso). La continuit\u00e0 narrativa \u00e8 assicurata dalla presenza di personaggi fissi, da una ambientazione che raramente varia e da caratteri strutturali comuni." }}, {"pk": 16, "model": "programs.programtype", "fields": { "code":"8c", "type":"Fiction", "subtype":"Situation comedies", "description": "Serie costituita da episodi 30 minuti con finale solitamente chiuso. Girate solitamente in interni, mettono in scena vicende soprattutto familiari con un impronta comico-grottesca." }}, {"pk": 17, "model": "programs.programtype", "fields": { "code":"8d", "type":"Fiction", "subtype":"Soap operas - telenovelas", "description": "Serial in puntate da 20 a 35 minuti con finale aperto." }}, {"pk": 18, "model": "programs.programtype", "fields": { "code":"8e","type": "Fiction", "subtype":"Comiche d'epoca", "description": "Genere usato per i film comici d'epoca." }}, {"pk": 19, "model": "programs.programtype", "fields": { "code":"9a", "type":"Documentari", "subtype":"Storia - geografia", "description": "Trasmissioni il cui scopo è documentare con filmati ed immagini la realt\u00e0 storico-geografica." }}, {"pk": 20, "model": "programs.programtype", "fields": { "code":"9b", "type":"Documentari", "subtype":"Scienza", "description": "Trasmissioni il cui scopo è documentare con filmati ed immagini la realt\u00e0 animale, vegetale, etc." }}, {"pk": 21, "model": "programs.programtype", "fields": { "code":"10a", "type":"Programmi informativi / approfondimento", "subtype":"Informazione parlamentare", "description": "Telegiornale informativo con collocazione periodica (quotidiana o settimanale) su temi che attengono quasi esclusivamente alla politica o il parlamento" }}, {"pk": 22, "model": "programs.programtype", "fields": { "code":"10b", "type":"Programmi informativi / approfondimento", "subtype":"Dichiarazioni parlamentari", "description": "Riprese in diretta di dibattiti in Parlamento, dichiarazioni del Pres. Del Consiglio, della repubblica, etc." }}, {"pk": 23, "model": "programs.programtype", "fields": { "code":"10c", "type":"Programmi informativi / approfondimento", "subtype":"Inchieste", "description": "Programma giornalistico di approfondimento (spesso anche con filmati) solitamente su singole tematiche." }}, {"pk": 24, "model": "programs.programtype", "fields": { "code":"10d", "type":"Programmi informativi / approfondimento", "subtype":"Rubriche di approfondimento delle testate giornalistiche", "description":"Programmi di approfondimento su tematiche di attualit\u00e0. Supplementi informativi alle edizioni dei TG a cura delle testate giornalistiche" }}, {"pk": 25, "model": "programs.programtype", "fields": { "code":"10e", "type":"Programmi informativi / approfondimento", "subtype":"Costume e societ\u00e0", "description": "Trasmissioni che documentano usi, costumi, tradizioni, viaggi, curiosit\u00e0, della societ\u00e0 moderna. Programmi che trattano del profilo e della vita di personaggi celebri scomparsi." }}, {"pk": 26, "model": "programs.programtype", "fields": { "code":"10f", "type":"Programmi informativi / approfondimento", "subtype":"Rubriche religiose", "description": "Programmi a carattere religioso, di qualunque 'credo', registrati in studio" }}, {"pk": 27, "model": "programs.programtype", "fields": { "code":"10g", "type":"Programmi informativi / approfondimento", "subtype":"Dibattiti", "description": "Programmi che prevedono un dibattito in studio o fuori studio per l'approfondimento di temi solitamente di attualit\u00e0 sociale o politica. Possono essere legati alla trasmissione di un film che li precede o li segue." }}, {"pk": 28, "model": "programs.programtype", "fields": { "code":"10h", "type":"Programmi informativi / approfondimento", "subtype":"Rubriche di approfondimento sportivo", "description": "Trasmissioni di approfondimento sportivo a programmazione periodica. Possono essere anche monografie di personaggi o episodi sportivi o fungere da contenitore di manifestazioni sportive." }}, {"pk": 29, "model": "programs.programtype", "fields": { "code":"10i", "type":"Programmi informativi / approfondimento", "subtype":"Teledidattica", "description": "Programmi puramente didattico-informativi. Programmi generalmente caratterizzati dal logo 'DSE', 'Video Sapere' e RAI Educational" }}, {"pk": 30, "model": "programs.programtype", "fields": { "code":"10j", "type":"Programmi informativi / approfondimento", "subtype":"Approfondimento culturale", "description": "Programmi, anche con eventuali dibattiti, a carattere culturale su temi di storia, geografia, scienza, ambiente, letteratura, arte, etc." }}, {"pk": 31, "model": "programs.programtype", "fields": { "code":"11a", "type":"Programmi culturali con parti autonome", "subtype":"Concerti", "description": "Programma il cui contenuto coincide con la messa in onda di concerti di musica leggera o sinfonici." }}, {"pk": 32, "model": "programs.programtype", "fields": { "code":"11b", "type":"Programmi culturali con parti autonome", "subtype":"Balletti","description": "Rappresentazione di uno spettacolo di danza classica" }}, {"pk": 33, "model": "programs.programtype", "fields": { "code":"11c", "type":"Programmi culturali con parti autonome", "subtype":"Lirica", "description":"Trasmissione il cui contenuto prevede l'esecuzione di 'Opere liriche'" }}, {"pk": 34, "model": "programs.programtype", "fields": { "code":"11d", "type":"Programmi culturali con parti autonome", "subtype":"Prosa", "description": "Rappresentazione di spettacoli di prosa teatrale o televisiva" }}, {"pk": 35, "model": "programs.programtype", "fields": { "code":"12", "type":"Cartoni animati per bambini","subtype":"Cartoni animati per bambini", "description": "Programma di animazione della durata massima di 60 min. destinato ad un pubblico infantile" }}, {"pk": 36, "model": "programs.programtype", "fields": { "code":"13a","type":"Intrattenimento","subtype":"Programmi musicali","description": "Programmi girati in studio che si occupano del panorama della musica leggera: clip musicali, classifiche, retrospettive. Possono fungere da contenitore di concerti." }}, {"pk": 37, "model": "programs.programtype", "fields": { "code":"13b","type":"Intrattenimento,Reality show", "subtype":"Programmi basati sulla trasmissione di riprese effettuate dal vivo ed in diretta", "description": "aventi come target esclusivo la riproduzione televisiva di scene di vita reale o comunque di attivit\u00e0 non preordinate svolte da parte di una o pi\u00f9 persone all'interno di uno studio televisivo o un ambiente predefinito" }}, {"pk": 38, "model": "programs.programtype", "fields": { "code":"13c","type":"Intrattenimento", "subtype":"Programmi di montaggio", "description": "Programmi basati sull'accostamento di immagini registrate, montate secondo una specifica linea interpretativa" }}, {"pk": 39, "model": "programs.programtype", "fields": { "code":"13d","type":"Intrattenimento","subtype":"Variet\u00e0", "description": "Trasmissioni di intrattenimento leggero. Le componenti che caratterizzano questo prodotto sono: un'impostazione di derivazione teatrale, una scenografia ad effetto, la presenza di balletti, di canzoni e di sketch nonche' di uno o pi\u00f9 conduttori." }}, {"pk": 40, "model": "programs.programtype", "fields": { "code":"13e","type":"Intrattenimento","subtype":"Astrologia - cartomanzia","description": "Programmi girati in studio e caratterizzati dalla presenza di un astrologo o cartomante, in genere in contatto telefonico con i telespettatori" }}, {"pk": 41, "model": "programs.programtype", "fields": { "code":"13f","type":"Intrattenimento","subtype":"Programma contenitore radiofonico" }}, {"pk": 42, "model": "programs.programtype", "fields": { "code":"13g","type":"Intrattenimento", "subtype":"Cartoni animati per adulti","description": "Programma di animazione della durata massima di 60 min. destinato ad un pubblico adulto" }}, {"pk": 43, "model": "programs.programtype", "fields": { "code":"13h","type":"Intrattenimento", "subtype":"Trasmissioni per bambini","description": "Trasmissioni destinate ad un pubblico infantile, condotte in studio o in esterno con o senza la partecipazione di bambini. Possono contenere giochi o quiz e spesso cartoni animati." }}, {"pk": 44, "model": "programs.programtype", "fields": { "code":"14a","type":"Attualit\u00e0","subtype":"Anteprima","description": "Programmi che hanno lo scopo di dare informazione o promuovere l'imminente programmazione cinematografica." }}, {"pk": 45, "model": "programs.programtype", "fields": { "code":"14b","type":"Attualit\u00e0", "subtype":"Promo","description": "Auto-promozione di eventi che saranno trasmessi sulla stessa rete o su altre reti dello stesso gruppo." }}, {"pk": 46, "model": "programs.programtype", "fields": { "code":"14c","type":"Attualit\u00e0", "subtype":"Rotocalchi","description": "Trasmissioni 'informative' a carattere di cronaca rosa e di curiosit\u00e0 varie." }}, {"pk": 47, "model": "programs.programtype", "fields": { "code":"14d","type":"Attualit\u00e0", "subtype":"Meteo","description": "Programma di previsioni metereologiche" }}, {"pk": 48, "model": "programs.programtype", "fields": { "code":"14e","type":"Attualit\u00e0","subtype":"Lotterie","description": "Estrazioni del Lotto" }}, {"pk": 49, "model": "programs.programtype", "fields": { "code":"14f","type":"Attualit\u00e0","subtype":"Rubriche di servizio","description": "Trasmissioni non condotte in studio che offrono informazioni su: modalit\u00e0 per il voto, viabilit\u00e0 e bollettini sul traffico, numeri telefonici utili." }}, {"pk": 50, "model": "programs.programtype", "fields": { "code":"14g","type":"Attualit\u00e0","subtype":"Trasmissioni di servizio","description": "Programmi condotti in studio con lo scopo di offrire un servizio socio-informativo." }}, {"pk": 51, "model": "programs.programtype", "fields": { "code":"14h","type":"Attualit\u00e0","subtype":"Inaugurazioni","description": "Trasmissioni, generalmente in diretta, che documentano inaugurazioni" }}, {"pk": 52, "model": "programs.programtype", "fields": { "code":"14i","type":"Attualit\u00e0","subtype":"Premiazioni","description": "Trasmissioni, generalmente in diretta, che documentano premi letterari e premiazioni" }}, {"pk": 53, "model": "programs.programtype", "fields": { "code":"14j","type":"Attualit\u00e0","subtype":"Manifestazioni di piazza","description": "Trasmissioni, generalmente in diretta, che documentano manifestazioni di piazza" }}, {"pk": 54, "model": "programs.programtype", "fields": { "code":"15a","type":"Eventi religiosi","subtype":"Santa Messa","description": "Trasmissioni, generalmente domenicali ed in diretta, che seguono la Santa Messa" }}, {"pk": 55, "model": "programs.programtype", "fields": { "code":"15b","type":"Eventi religiosi","subtype":"Eventi religiosi","description": "Trasmissioni, generalmente in diretta, che documentano manifestazioni religiose" }}, {"pk": 56, "model": "programs.programtype", "fields": { "code":"16a","type":"Programmi accessori", "subtype":"Annunci","description": "Programmi aventi carattere accessorio rispetto al palinsesto" }}, {"pk": 57, "model": "programs.programtype", "fields": { "code":"16b","type":"Programmi accessori", "subtype":"Sigle","description": "Programmi aventi carattere accessorio rispetto al palinsesto" }}, {"pk": 58, "model": "programs.programtype", "fields": { "code":"16c","type":"Programmi accessori", "subtype":"Intervalli","description": "Programmi aventi carattere accessorio rispetto al palinsesto" }}, {"pk": 59, "model": "programs.programtype", "fields": { "code":"16d","type":"Programmi accessori", "subtype":"Segnale orario","description": "Programmi aventi carattere accessorio rispetto al palinsesto" }}, {"pk": 60, "model": "programs.programtype", "fields": { "code":"17", "type":"Messaggi politici autogestiti gratuiti", "subtype":"Messaggi politici autogestiti gratuiti","description": "Messaggi politici autogestiti a titolo gratuito ai sensi dell'art. 3 della legge 22 Febbraio 2000 n. 28" }}, {"pk": 61, "model": "programs.programtype", "fields": { "code":"18","type":"Messaggi politici autogestiti a pagamento","subtype":"Messaggi politici autogestiti a pagamento","description": "Messaggi politici autogestiti a pagamento ai sensi dell'art. 3 della legge 22 Febbraio 2000 n. 28" }}, {"pk": 62, "model": "programs.programtype", "fields": { "code":"19","type":"Comunicazione politica","subtype":"Comunicazione politica","description": "Programmi di comunicazione politica ai sensi dell'art. 2 della legge 22 Febbraio 2000 n. 28" }}, {"pk": 63, "model": "programs.programtype", "fields": { "code":"20","type":"Immagini fisse o ripetitive","subtype":"Immagini fisse o ripetitive" }} ] autoradio-autoradio-3.6-4/autoradio/programs/managers.py000066400000000000000000000005601454362722700235040ustar00rootroot00000000000000from django.db.models import Manager import datetime class EpisodeManager(Manager): """Returns public posts that are not in the future.""" def __init__(self, *args, **kwargs): super(EpisodeManager, self).__init__(*args, **kwargs) def published(self): return self.get_queryset().filter(status__exact=2, date__lte=datetime.datetime.now()) autoradio-autoradio-3.6-4/autoradio/programs/migrations/000077500000000000000000000000001454362722700235105ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/migrations/0001_initial.py000066400000000000000000001160351454362722700261610ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9 on 2016-01-25 17:56 import autoradio.programs.models from django.conf import settings from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='AperiodicSchedule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('emission_date', models.DateTimeField(help_text='This is the date and time when the program is planned in palimsest', verbose_name='Programmed date')), ], ), migrations.CreateModel( name='ChildCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(blank=True, choices=[(b'Arts', ((b'Design', b'Design'), (b'Fashion & Beauty', b'Fashion & Beauty'), (b'Food', b'Food'), (b'Literature', b'Literature'), (b'Performing Arts', b'Performing Arts'), (b'Visual Arts', b'Visual Arts'))), (b'Business', ((b'Business News', b'Business News'), (b'Careers', b'Careers'), (b'Investing', b'Investing'), (b'Management & Marketing', b'Management & Marketing'), (b'Shopping', b'Shopping'))), (b'Education', ((b'Education Technology', b'Education Technology'), (b'Higher Education', b'Higher Education'), (b'K-12', b'K-12'), (b'Language Courses', b'Language Courses'), (b'Training', b'Training'))), (b'Games & Hobbies', ((b'Automotive', b'Automotive'), (b'Aviation', b'Aviation'), (b'Hobbies', b'Hobbies'), (b'Other Games', b'Other Games'), (b'Video Games', b'Video Games'))), (b'Government & Organizations', ((b'Local', b'Local'), (b'National', b'National'), (b'Non-Profit', b'Non-Profit'), (b'Regional', b'Regional'))), (b'Health', ((b'Alternative Health', b'Alternative Health'), (b'Fitness & Nutrition', b'Fitness & Nutrition'), (b'Self-Help', b'Self-Help'), (b'Sexuality', b'Sexuality'))), (b'Religion & Spirituality', ((b'Buddhism', b'Buddhism'), (b'Christianity', b'Christianity'), (b'Hinduism', b'Hinduism'), (b'Islam', b'Islam'), (b'Judaism', b'Judaism'), (b'Other', b'Other'), (b'Spirituality', b'Spirituality'))), (b'Science & Medicine', ((b'Medicine', b'Medicine'), (b'Natural Sciences', b'Natural Sciences'), (b'Social Sciences', b'Social Sciences'))), (b'Society & Culture', ((b'History', b'History'), (b'Personal Journals', b'Personal Journals'), (b'Philosophy', b'Philosophy'), (b'Places & Travel', b'Places & Travel'))), (b'Sports & Recreation', ((b'Amateur', b'Amateur'), (b'College & High School', b'College & High School'), (b'Outdoor', b'Outdoor'), (b'Professional', b'Professional'))), (b'Technology', ((b'Gadgets', b'Gadgets'), (b'Tech News', b'Tech News'), (b'Podcasting', b'Podcasting'), (b'Software How-To', b'Software How-To')))], help_text='Please choose a child category that corresponds to its respective parent category (e.g., "Design" is a child category of "Arts").
If no such child category exists for a parent category (e.g., Comedy, Kids & Family, Music, News & Politics, or TV & Film), simply leave this blank and save.', max_length=50)), ('slug', models.SlugField(blank=True, help_text='A slug is a URL-friendly nickname. For exmaple, a slug for "Fashion & Beauty" is "fashion-beauty".')), ], options={ 'ordering': ['parent', 'slug'], 'verbose_name': 'category (iTunes child)', 'verbose_name_plural': 'categories (iTunes child)', }, ), migrations.CreateModel( name='Configure', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('sezione', models.CharField(default=b'show', editable=False, max_length=50, unique=True)), ('active', models.BooleanField(default=True, help_text='activate/deactivate the intere program class', verbose_name='Active show')), ('emission_starttime', models.TimeField(blank=True, help_text='The start time from wich the programs will be active', null=True, verbose_name='Programmed start time')), ('emission_endtime', models.TimeField(blank=True, help_text='The end time the programs will be active', null=True, verbose_name='Programmed end time')), ('radiostation', models.CharField(default=b'Radio', help_text='The station name for the print of programs book', max_length=50, unique=True)), ('channel', models.CharField(default=b'103', help_text='The station channel for the print of programs book', max_length=80, unique=True)), ('mezzo', models.CharField(default=b'analogico terrestre', help_text='The station kind of emission for the print of programs book', max_length=50, unique=True)), ('type', models.CharField(default=b'radiofonica', help_text='The station type for the print of programs book', max_length=50, unique=True)), ], ), migrations.CreateModel( name='Enclosure', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(blank=True, default=None, help_text='Title is generally only useful with multiple enclosures.', max_length=255)), ('file', autoradio.programs.models.DeletingFileField(help_text='Either upload or use the "Player" text box below. If uploading, file must be less than or equal to 30 MB for a Google video sitemap.', max_length=255, upload_to=b'podcasts/episodes/files/')), ('mime', models.CharField(blank=True, choices=[(b'audio/ogg', b'.ogg (audio)'), (b'audio/mpeg', b'.mp3 (audio)'), (b'audio/x-m4a', b'.m4a (audio)'), (b'video/mp4', b'.mp4 (audio or video)'), (b'video/x-m4v', b'.m4v (video)'), (b'video/quicktime', b'.mov (video)'), (b'application/pdf', b'.pdf (document)'), (b'image/jpeg', b'.jpg, .jpeg, .jpe (image)')], max_length=255, verbose_name=b'Format')), ('medium', models.CharField(blank=True, choices=[(b'Audio', b'Audio'), (b'Video', b'Video'), (b'Document', b'Document'), (b'Image', b'Image'), (b'Executable', b'Executable')], max_length=255)), ('expression', models.CharField(blank=True, choices=[(b'Sample', b'Sample'), (b'Full', b'Full'), (b'Nonstop', b'Non-stop')], max_length=25)), ('frame', models.CharField(blank=True, choices=[(b'29.97', b'29.97')], help_text='Measured in frames per second (fps), often 29.97.', max_length=5, verbose_name=b'Frame rate')), ('bitrate', models.CharField(blank=True, choices=[(b'8', b'8'), (b'11.025', b'11.025'), (b'16', b'16'), (b'22.050', b'22.050'), (b'32', b'32'), (b'44.1', b'44.1'), (b'48', b'48'), (b'96', b'96')], help_text='Measured in kilobits per second (kbps), often 128 or 192.', max_length=5, verbose_name=b'Bit rate')), ('sample', models.CharField(blank=True, choices=[(b'24', b'24'), (b'48', b'48'), (b'64', b'64'), (b'96', b'96'), (b'128', b'128'), (b'160', b'160'), (b'196', b'196'), (b'320', b'320')], help_text='Measured in kilohertz (kHz), often 44.1.', max_length=5, verbose_name=b'Sample rate')), ('channel', models.CharField(blank=True, choices=[(b'2', b'2'), (b'1', b'1')], help_text='Number of channels; 2 for stereo, 1 for mono.', max_length=5)), ('algo', models.CharField(blank=True, choices=[(b'MD5', b'MD5'), (b'SHA-1', b'SHA-1')], max_length=50, verbose_name=b'Hash algorithm')), ('hash', models.CharField(blank=True, help_text='MD-5 or SHA-1 file hash.', max_length=255)), ('player', models.URLField(blank=True, help_text='URL of the player console that plays the media. Could be your own .swf, but most likely a YouTube URL, such as http://www.youtube.com/v/UZCfK8pVztw (not the permalink, which looks like http://www.youtube.com/watch?v=UZCfK8pVztw).')), ('embed', models.BooleanField(help_text='Check to allow Google to embed your external player in search results on Google Video.')), ('width', models.PositiveIntegerField(blank=True, help_text="Width of the browser window in
which the URL should be opened.
YouTube's default is 425.", null=True)), ('height', models.PositiveIntegerField(blank=True, help_text="Height of the browser window in
which the URL should be opened.
YouTube's default is 344.", null=True)), ], options={ 'ordering': ['mime', 'file'], }, ), migrations.CreateModel( name='Episode', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(help_text='Make it specific but avoid explicit language. Limit to 100 characters for a Google video sitemap.', max_length=255)), ('active', models.BooleanField(default=True, verbose_name='Active')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Recording date')), ('title_type', models.CharField(blank=True, choices=[(b'Plain', b'Plain text'), (b'HTML', b'HTML')], default=b'Plain', max_length=255, verbose_name=b'Title type')), ('slug', models.SlugField(help_text='Auto-generated from Title.', unique=True)), ('description_type', models.CharField(blank=True, choices=[(b'Plain', b'Plain text'), (b'HTML', b'HTML')], default=b'Plain', max_length=255, verbose_name=b'Description type')), ('description', models.TextField(help_text='Avoid explicit language. Google video sitempas allow 2,048 characters.')), ('captions', autoradio.programs.models.DeletingFileField(blank=True, help_text='For video podcasts. Good captioning choices include SubViewer, SubRip or TimedText.', max_length=255, upload_to=b'podcasts/episodes/captions/')), ('category', models.CharField(blank=True, help_text='Limited to one user-specified category for the sake of sanity.', max_length=255)), ('domain', models.URLField(blank=True, help_text='A URL that identifies a categorization taxonomy.')), ('frequency', models.CharField(blank=True, choices=[(b'always', b'Always'), (b'hourly', b'Hourly'), (b'daily', b'Daily'), (b'weekly', b'Weekly'), (b'monthly', b'Monthly'), (b'yearly', b'Yearly'), (b'never', b'Never')], default=b'never', help_text="The frequency with which the episode's data changes. For sitemaps.", max_length=10)), ('priority', models.DecimalField(blank=True, decimal_places=1, default=b'0.5', help_text='The relative priority of this episode compared to others. 1.0 is the most important. For sitemaps.', max_digits=2, null=True)), ('status', models.IntegerField(choices=[(1, b'Draft'), (2, b'Public'), (3, b'Private')], default=2)), ('update', models.DateTimeField(auto_now=True)), ('subtitle', models.CharField(blank=True, help_text='Looks best if only a few words like a tagline.', max_length=255)), ('summary', models.TextField(blank=True, help_text='Allows 4,000 characters. Description will be used if summary is blank.')), ('minutes', models.PositiveIntegerField(blank=True, null=True)), ('seconds', models.CharField(blank=True, choices=[(b'00', b'0'), (b'01', b'1'), (b'02', b'2'), (b'03', b'3'), (b'04', b'4'), (b'05', b'5'), (b'06', b'6'), (b'07', b'7'), (b'08', b'8'), (b'09', b'9'), (b'10', b'10'), (b'11', b'11'), (b'12', b'12'), (b'13', b'13'), (b'14', b'14'), (b'15', b'15'), (b'16', b'16'), (b'17', b'17'), (b'18', b'18'), (b'19', b'19'), (b'20', b'20'), (b'21', b'21'), (b'22', b'22'), (b'23', b'23'), (b'24', b'24'), (b'25', b'25'), (b'26', b'26'), (b'27', b'27'), (b'28', b'28'), (b'29', b'29'), (b'30', b'30'), (b'31', b'31'), (b'32', b'32'), (b'33', b'33'), (b'34', b'34'), (b'35', b'35'), (b'36', b'36'), (b'37', b'37'), (b'38', b'38'), (b'39', b'39'), (b'40', b'40'), (b'41', b'41'), (b'42', b'42'), (b'43', b'43'), (b'44', b'44'), (b'45', b'45'), (b'46', b'46'), (b'47', b'47'), (b'48', b'48'), (b'49', b'49'), (b'50', b'50'), (b'51', b'51'), (b'52', b'52'), (b'53', b'53'), (b'54', b'54'), (b'55', b'55'), (b'56', b'56'), (b'57', b'57'), (b'58', b'58'), (b'59', b'59')], max_length=2, null=True)), ('keywords', models.CharField(blank=True, help_text='A comma-delimited list of words for searches, up to 12; perhaps include misspellings.', max_length=255, null=True)), ('explicit', models.CharField(choices=[(b'Yes', b'Yes'), (b'No', b'No'), (b'Clean', b'Clean')], default=b'No', help_text='"Clean" will put the clean iTunes graphic by it.', max_length=255)), ('block', models.BooleanField(default=False, help_text='Check to block this episode from iTunes because
its content might cause the entire show to be
removed from iTunes.')), ('role', models.CharField(blank=True, choices=[(b'Actor', b'Actor'), (b'Adaptor', b'Adaptor'), (b'Anchor person', b'Anchor person'), (b'Animal Trainer', b'Animal Trainer'), (b'Animator', b'Animator'), (b'Announcer', b'Announcer'), (b'Armourer', b'Armourer'), (b'Art Director', b'Art Director'), (b'Artist/Performer', b'Artist/Performer'), (b'Assistant Camera', b'Assistant Camera'), (b'Assistant Chief Lighting Technician', b'Assistant Chief Lighting Technician'), (b'Assistant Director', b'Assistant Director'), (b'Assistant Producer', b'Assistant Producer'), (b'Assistant Visual Editor', b'Assistant Visual Editor'), (b'Author', b'Author'), (b'Broadcast Assistant', b'Broadcast Assistant'), (b'Broadcast Journalist', b'Broadcast Journalist'), (b'Camera Operator', b'Camera Operator'), (b'Carpenter', b'Carpenter'), (b'Casting', b'Casting'), (b'Causeur', b'Causeur'), (b'Chief Lighting Technician', b'Chief Lighting Technician'), (b'Choir', b'Choir'), (b'Choreographer', b'Choreographer'), (b'Clapper Loader', b'Clapper Loader'), (b'Commentary or Commentator', b'Commentary or Commentator'), (b'Commissioning Broadcaster', b'Commissioning Broadcaster'), (b'Composer', b'Composer'), (b'Computer programmer', b'Computer programmer'), (b'Conductor', b'Conductor'), (b'Consultant', b'Consultant'), (b'Continuity Checker', b'Continuity Checker'), (b'Correspondent', b'Correspondent'), (b'Costume Designer', b'Costume Designer'), (b'Dancer', b'Dancer'), (b'Dialogue Coach', b'Dialogue Coach'), (b'Director', b'Director'), (b'Director of Photography', b'Director of Photography'), (b'Distribution Company', b'Distribution Company'), (b'Draughtsman', b'Draughtsman'), (b'Dresser', b'Dresser'), (b'Dubber', b'Dubber'), (b'Editor/Producer (News)', b'Editor/Producer (News)'), (b'Editor-in-chief', b'Editor-in-chief'), (b'Editor-of-the-Day', b'Editor-of-the-Day'), (b'Ensemble', b'Ensemble'), (b'Executive Producer', b'Executive Producer'), (b'Expert', b'Expert'), (b'Fight Director', b'Floor Manager'), (b'Floor Manager', b'Floor Manager'), (b'Focus Puller', b'Focus Puller'), (b'Foley Artist', b'Foley Artist'), (b'Foley Editor', b'Foley Editor'), (b'Foley Mixer', b'Foley Mixer'), (b'Graphic Assistant', b'Graphic Assistant'), (b'Graphic Designer', b'Graphic Designer'), (b'Greensman', b'Greensman'), (b'Grip', b'Grip'), (b'Hairdresser', b'Hairdresser'), (b'Illustrator', b'Illustrator'), (b'Interviewed Guest', b'Interviewed Guest'), (b'Interviewer', b'Interviewer'), (b'Key Character', b'Key Character'), (b'Key Grip', b'Key Grip'), (b'Key Talents', b'Key Talents'), (b'Leadman', b'Leadman'), (b'Librettist', b'Librettist'), (b'Lighting director', b'Lighting director'), (b'Lighting Technician', b'Lighting Technician'), (b'Location Manager', b'Location Manager'), (b'Lyricist', b'Lyricist'), (b'Make Up Artist', b'Make Up Artist'), (b'Manufacturer', b'Manufacturer'), (b'Matte Artist', b'Matte Artist'), (b'Music Arranger', b'Music Arranger'), (b'Music Group', b'Music Group'), (b'Musician', b'Musician'), (b'News Reader', b'News Reader'), (b'Orchestra', b'Orchestra'), (b'Participant', b'Participant'), (b'Photographer', b'Photographer'), (b'Post-Production Editor', b'Post-Production Editor'), (b'Producer', b'Producer'), (b'Production Assistant', b'Production Assistant'), (b'Production Company', b'Production Company'), (b'Production Department', b'Production Department'), (b'Production Manager', b'Production Manager'), (b'Production Secretary', b'Production Secretary'), (b'Programme Production Researcher', b'Programme Production Researcher'), (b'Property Manager', b'Property Manager'), (b'Publishing Company', b'Publishing Company'), (b'Puppeteer', b'Puppeteer'), (b'Pyrotechnician', b'Pyrotechnician'), (b'Reporter', b'Reporter'), (b'Rigger', b'Rigger'), (b'Runner', b'Runner'), (b'Scenario', b'Scenario'), (b'Scenic Operative', b'Scenic Operative'), (b'Script Supervisor', b'Script Supervisor'), (b'Second Assistant Camera', b'Second Assistant Camera'), (b'Second Assistant Director', b'Second Assistant Director'), (b'Second Unit Director', b'Second Unit Director'), (b'Set Designer', b'Set Designer'), (b'Set Dresser', b'Set Dresser'), (b'Sign Language', b'Sign Language'), (b'Singer', b'Singer'), (b'Sound Designer', b'Sound Designer'), (b'Sound Mixer', b'Sound Mixer'), (b'Sound Recordist', b'Sound Recordist'), (b'Special Effects', b'Special Effects'), (b'Stunts', b'Stunts'), (b'Subtitles', b'Subtitles'), (b'Technical Director', b'Technical Director'), (b'Translation', b'Translation'), (b'Transportation Manager', b'Transportation Manager'), (b'Treatment / Programme Proposal', b'Treatment / Programme Proposal'), (b'Vision Mixer', b'Vision Mixer'), (b'Visual Editor', b'Visual Editor'), (b'Visual Effects', b'Visual Effects'), (b'Wardrobe', b'Wardrobe'), (b'Witness', b'Witness')], help_text='Role codes provided by the European Broadcasting Union.', max_length=255)), ('standard', models.CharField(blank=True, choices=[(b'Simple', b'Simple'), (b'MPAA', b'MPAA'), (b'V-chip', b'TV Parental Guidelines')], default=b'Simple', max_length=255)), ('rating', models.CharField(blank=True, choices=[(b'Simple', ((b'Adult', b'Adult'), (b'Nonadult', b'Non-adult'))), (b'MPAA', ((b'G', b'G: General Audiences'), (b'PG', b'PG: Parental Guidance Suggested'), (b'PG-13', b'PG-13: Parents Strongly Cautioned'), (b'R', b'R: Restricted'), (b'NC-17', b'NC-17: No One 17 and Under Admitted'))), (b'TV Parental Guidelines', ((b'TV-Y', b'TV-Y: All children'), (b'TV-Y7-FV', b'TV-Y7/TV-Y7-FV: Directed to older children'), (b'TV-G', b'TV-G: General audience'), (b'TV-PG', b'TV-PG: Parental guidance'), (b'TV-14', b'TV-14: Parents strongly cautioned'), (b'TV-MA', b'TV-MA: Mature audiences')))], default=b'Nonadult', help_text='If used, selection must match respective Scheme selection.', max_length=255)), ('image', models.ImageField(blank=True, help_text='A still image from a video file, but for episode artwork to display in iTunes, image must be saved to file\'s metadata before episode uploading!', upload_to=b'podcasts/episodes/img/')), ('text', models.TextField(blank=True, help_text='Media RSS text transcript. Must use tags. Please see the Media RSS 2.0 specification for syntax.')), ('deny', models.BooleanField(default=False, help_text='Check to deny episode to be shown to users from specified countries.')), ('restriction', models.CharField(blank=True, help_text='A space-delimited list of ISO 3166-1-coded countries.', max_length=255)), ('start', models.DateTimeField(blank=True, help_text='Start date and time that the media is valid.', null=True)), ('end', models.DateTimeField(blank=True, help_text='End date and time that the media is valid.', null=True)), ('scheme', models.CharField(blank=True, default=b'W3C-DTF', max_length=255)), ('name', models.CharField(blank=True, help_text='Any helper name to distinguish this time period.', max_length=255)), ('preview', models.BooleanField(default=False, help_text='Check to allow Google to show a preview of your media in search results.')), ('preview_start_mins', models.PositiveIntegerField(blank=True, help_text="Start time (minutes) of the media's preview,
shown on Google.com search results before
clicking through to see full video.", null=True, verbose_name=b'Preview start (minutes)')), ('preview_start_secs', models.CharField(blank=True, choices=[(b'00', b'0'), (b'01', b'1'), (b'02', b'2'), (b'03', b'3'), (b'04', b'4'), (b'05', b'5'), (b'06', b'6'), (b'07', b'7'), (b'08', b'8'), (b'09', b'9'), (b'10', b'10'), (b'11', b'11'), (b'12', b'12'), (b'13', b'13'), (b'14', b'14'), (b'15', b'15'), (b'16', b'16'), (b'17', b'17'), (b'18', b'18'), (b'19', b'19'), (b'20', b'20'), (b'21', b'21'), (b'22', b'22'), (b'23', b'23'), (b'24', b'24'), (b'25', b'25'), (b'26', b'26'), (b'27', b'27'), (b'28', b'28'), (b'29', b'29'), (b'30', b'30'), (b'31', b'31'), (b'32', b'32'), (b'33', b'33'), (b'34', b'34'), (b'35', b'35'), (b'36', b'36'), (b'37', b'37'), (b'38', b'38'), (b'39', b'39'), (b'40', b'40'), (b'41', b'41'), (b'42', b'42'), (b'43', b'43'), (b'44', b'44'), (b'45', b'45'), (b'46', b'46'), (b'47', b'47'), (b'48', b'48'), (b'49', b'49'), (b'50', b'50'), (b'51', b'51'), (b'52', b'52'), (b'53', b'53'), (b'54', b'54'), (b'55', b'55'), (b'56', b'56'), (b'57', b'57'), (b'58', b'58'), (b'59', b'59')], help_text="Start time (seconds) of the media's preview.", max_length=2, null=True, verbose_name=b'Preview start (seconds)')), ('preview_end_mins', models.PositiveIntegerField(blank=True, help_text="End time (minutes) of the media's preview,
shown on Google.com search results before
clicking through to see full video.", null=True, verbose_name=b'Preview end (minutes)')), ('preview_end_secs', models.CharField(blank=True, choices=[(b'00', b'0'), (b'01', b'1'), (b'02', b'2'), (b'03', b'3'), (b'04', b'4'), (b'05', b'5'), (b'06', b'6'), (b'07', b'7'), (b'08', b'8'), (b'09', b'9'), (b'10', b'10'), (b'11', b'11'), (b'12', b'12'), (b'13', b'13'), (b'14', b'14'), (b'15', b'15'), (b'16', b'16'), (b'17', b'17'), (b'18', b'18'), (b'19', b'19'), (b'20', b'20'), (b'21', b'21'), (b'22', b'22'), (b'23', b'23'), (b'24', b'24'), (b'25', b'25'), (b'26', b'26'), (b'27', b'27'), (b'28', b'28'), (b'29', b'29'), (b'30', b'30'), (b'31', b'31'), (b'32', b'32'), (b'33', b'33'), (b'34', b'34'), (b'35', b'35'), (b'36', b'36'), (b'37', b'37'), (b'38', b'38'), (b'39', b'39'), (b'40', b'40'), (b'41', b'41'), (b'42', b'42'), (b'43', b'43'), (b'44', b'44'), (b'45', b'45'), (b'46', b'46'), (b'47', b'47'), (b'48', b'48'), (b'49', b'49'), (b'50', b'50'), (b'51', b'51'), (b'52', b'52'), (b'53', b'53'), (b'54', b'54'), (b'55', b'55'), (b'56', b'56'), (b'57', b'57'), (b'58', b'58'), (b'59', b'59')], help_text="End time (seconds) of the media's preview.", max_length=2, null=True, verbose_name=b'Preview end (seconds)')), ('host', models.BooleanField(default=False, help_text='Check to allow Google to host your media after it expires. Must set expiration date in Dublin Core.')), ('author', models.ManyToManyField(help_text='Remember to save the user\'s name and e-mail address in the User application.', related_name='episode_authors', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['-date', 'slug'], }, ), migrations.CreateModel( name='Giorno', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(choices=[('Monday', 'Monday'), ('Tuesday', 'Tuesday'), ('Wednesday', 'Wednesday'), ('Thursday', 'Thursday'), ('Friday', 'Friday'), ('Saturday', 'Saturday'), ('Sunday', 'Sunday')], help_text='weekday name', max_length=20, unique=True)), ], ), migrations.CreateModel( name='MediaCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(choices=[(b'Action & Adventure', b'Action & Adventure'), (b'Ads & Promotional', b'Ads & Promotional'), (b'Anime & Animation', b'Anime & Animation'), (b'Art & Experimental', b'Art & Experimental'), (b'Business', b'Business'), (b'Children & Family', b'Children & Family'), (b'Comedy', b'Comedy'), (b'Dance', b'Dance'), (b'Documentary', b'Documentary'), (b'Drama', b'Drama'), (b'Educational', b'Educational'), (b'Faith & Spirituality', b'Faith & Spirituality'), (b'Health & Fitness', b'Health & Fitness'), (b'Foreign', b'Foreign'), (b'Gaming', b'Gaming'), (b'Gay & Lesbian', b'Gay & Lesbian'), (b'Home Video', b'Home Video'), (b'Horror', b'Horror'), (b'Independent', b'Independent'), (b'Mature & Adult', b'Mature & Adult'), (b'Movie (feature)', b'Movie (feature)'), (b'Movie (short)', b'Movie (short)'), (b'Movie Trailer', b'Movie Trailer'), (b'Music & Musical', b'Music & Musical'), (b'Nature', b'Nature'), (b'News', b'News'), (b'Political', b'Political'), (b'Religious', b'Religious'), (b'Romance', b'Romance'), (b'Independent', b'Independent'), (b'Sci-Fi & Fantasy', b'Sci-Fi & Fantasy'), (b'Science & Technology', b'Science & Technology'), (b'Special Interest', b'Special Interest'), (b'Sports', b'Sports'), (b'Stock Footage', b'Stock Footage'), (b'Thriller', b'Thriller'), (b'Travel', b'Travel'), (b'TV Show', b'TV Show'), (b'Western', b'Western')], max_length=50)), ('slug', models.SlugField(blank=True, help_text='A slug is a URL-friendly nickname. For example, a slug for "Games & Hobbies" is "games-hobbies".')), ], options={ 'ordering': ['slug'], 'verbose_name': 'category (Media RSS)', 'verbose_name_plural': 'categories (Media RSS)', }, ), migrations.CreateModel( name='ParentCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(choices=[(b'Arts', b'Arts'), (b'Business', b'Business'), (b'Comedy', b'Comedy'), (b'Education', b'Education'), (b'Games & Hobbies', b'Games & Hobbies'), (b'Government & Organizations', b'Government & Organizations'), (b'Health', b'Health'), (b'Kids & Family', b'Kids & Family'), (b'Music', b'Music'), (b'News & Politics', b'News & Politics'), (b'Religion & Spirituality', b'Religion & Spirituality'), (b'Science & Medicine', b'Science & Medicine'), (b'Society & Culture', b'Society & Culture'), (b'Sports & Recreation', b'Sports & Recreation'), (b'Technology', b'Technology'), (b'TV & Film', b'TV & Film')], help_text='After saving this parent category, please map it to one or more Child Categories below.', max_length=50)), ('slug', models.SlugField(blank=True, help_text='A slug is a URL-friendly nickname. For example, a slug for "Games & Hobbies" is "games-hobbies".')), ], options={ 'ordering': ['slug'], 'verbose_name': 'category (iTunes parent)', 'verbose_name_plural': 'categories (iTunes parent)', }, ), migrations.CreateModel( name='PeriodicSchedule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('start_date', models.DateField(blank=True, help_text='The program will be in palimpsest starting from this date', null=True, verbose_name='Programmed start date')), ('end_date', models.DateField(blank=True, help_text='The program will be in palimpsest ending this date', null=True, verbose_name='Programmed end date')), ('time', models.TimeField(blank=True, help_text='This is the time when the program is planned in palimpsest', null=True, verbose_name='Programmed time')), ('giorni', models.ManyToManyField(blank=True, help_text='The program will be in palimpsest those weekdays', to='programs.Giorno', verbose_name='Programmed days')), ], ), migrations.CreateModel( name='ProgramType', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(default=None, max_length=4, unique=True, verbose_name='Code')), ('type', models.CharField(default=None, max_length=200, verbose_name='Type')), ('subtype', models.CharField(default=None, max_length=254, verbose_name='SubType')), ('description', models.TextField(blank=True, default=None, null=True, verbose_name='Description')), ], ), migrations.CreateModel( name='Schedule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('emission_date', models.DateTimeField(help_text='This is the date and time when the program will be on air', verbose_name='programmed date')), ('episode', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Episode', verbose_name='Linked episode:')), ], ), migrations.CreateModel( name='ScheduleDone', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('emission_done', models.DateTimeField(editable=False, null=True, verbose_name='emission done')), ('enclosure', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Enclosure', verbose_name='Linked enclosure:')), ('schedule', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Schedule', verbose_name='Linked schedule:')), ], ), migrations.CreateModel( name='Show', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(help_text='show title', max_length=255)), ('active', models.BooleanField(default=True, help_text='Activate the show for emission', verbose_name='Active')), ('slug', models.SlugField(help_text='Auto-generated from Title.', unique=True)), ('length', models.FloatField(blank=True, default=None, help_text='Time lenght how you want to see it in the palimpsest', null=True, verbose_name='Time length (seconds)')), ('production', models.CharField(blank=True, choices=[('autoproduction', 'autoproduction'), ('eteroproduction', 'eteroproduction')], default=None, help_text='The type of production', max_length=30, null=True, verbose_name='Production')), ('organization', models.CharField(help_text='Name of the organization, company or Web site producing the podcast.', max_length=255)), ('link', models.URLField(help_text='URL of either the main website or the podcast section of the main website.')), ('description', models.TextField(help_text='Describe subject matter, media format, episode schedule and other relevant information while incorporating keywords.')), ('language', models.CharField(blank=True, default=b'en-us', help_text='Default is American English. See ISO 639-1 and ISO 3166-1 for more language codes.', max_length=5)), ('copyright', models.CharField(choices=[(b'Public domain', b'Public domain'), (b'Creative Commons: Attribution (by)', b'Creative Commons: Attribution (by)'), (b'Creative Commons: Attribution-Share Alike (by-sa)', b'Creative Commons: Attribution-Share Alike (by-sa)'), (b'Creative Commons: Attribution-No Derivatives (by-nd)', b'Creative Commons: Attribution-No Derivatives (by-nd)'), (b'Creative Commons: Attribution-Non-Commercial (by-nc)', b'Creative Commons: Attribution-Non-Commercial (by-nc)'), (b'Creative Commons: Attribution-Non-Commercial-Share Alike (by-nc-sa)', b'Creative Commons: Attribution-Non-Commercial-Share Alike (by-nc-sa)'), (b'Creative Commons: Attribution-Non-Commercial-No Dreivatives (by-nc-nd)', b'Creative Commons: Attribution-Non-Commercial-No Dreivatives (by-nc-nd)'), (b'All rights reserved', b'All rights reserved')], default=b'All rights reserved', help_text='See Creative Commons licenses for more information.', max_length=255)), ('copyright_url', models.URLField(blank=True, help_text='A URL pointing to additional copyright information. Consider a Creative Commons license URL.', verbose_name=b'Copyright URL')), ('category_show', models.CharField(blank=True, help_text='Limited to one user-specified category for the sake of sanity.', max_length=255, verbose_name=b'Category')), ('domain', models.URLField(blank=True, help_text='A URL that identifies a categorization taxonomy.')), ('ttl', models.PositiveIntegerField(blank=True, help_text='"Time to Live," the number of minutes a channel can be cached before refreshing.', null=True, verbose_name=b'TTL')), ('image', models.ImageField(blank=True, help_text='An attractive, original square JPEG (.jpg) or PNG (.png) image of 600x600 pixels. Image will be scaled down to 50x50 pixels at smallest in iTunes.', upload_to=b'podcasts/shows/img/')), ('feedburner', models.URLField(blank=True, help_text='Fill this out after saving this show and at least one episode. URL should look like "http://feeds.feedburner.com/TitleOfShow". See documentation for more.', verbose_name=b'FeedBurner URL')), ('subtitle', models.CharField(blank=True, help_text='Looks best if only a few words, like a tagline.', max_length=255)), ('summary', models.TextField(blank=True, help_text='Allows 4,000 characters. Description will be used if summary is blank.')), ('explicit', models.CharField(blank=True, choices=[(b'Yes', b'Yes'), (b'No', b'No'), (b'Clean', b'Clean')], default=b'No', help_text='"Clean" will put the clean iTunes graphic by it.', max_length=255)), ('block', models.BooleanField(default=False, help_text='Check to block this show from iTunes.
Show will remain blocked until unchecked.')), ('redirect', models.URLField(blank=True, help_text="The show's new URL feed if changing the URL of the current show feed. Must continue old feed for at least two weeks and write a 301 redirect for old feed.")), ('keywords', models.CharField(blank=True, help_text='A comma-demlimited list of up to 12 words for iTunes searches. Perhaps include misspellings of the title.', max_length=255)), ('itunes', models.URLField(blank=True, help_text='Fill this out after saving this show and at least one episode. URL should look like "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=000000000". See documentation for more.', verbose_name=b'iTunes Store URL')), ('author', models.ManyToManyField(help_text='Remember to save the user\'s name and e-mail address in the User application.
', related_name='display_authors', to=settings.AUTH_USER_MODEL)), ('category', models.ManyToManyField(blank=True, help_text='If selecting a category group with no child category (e.g., Comedy, Kids & Family, Music, News & Politics or TV & Film), save that parent category with a blank child category.
Selecting multiple category groups makes the podcast more likely to be found by users.
', related_name='show_categories', to='programs.ChildCategory')), ('type', models.ForeignKey(help_text='The categorization that follow the italian law (you have to use it to produce the programs book', on_delete=django.db.models.deletion.CASCADE, to='programs.ProgramType', verbose_name='Program Type')), ('webmaster', models.ForeignKey(blank=True, help_text='Remember to save the user\'s name and e-mail address in the User application.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='display_webmaster', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['organization', 'slug'], }, ), migrations.AddField( model_name='periodicschedule', name='show', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Show', verbose_name='refer to show:'), ), migrations.AddField( model_name='episode', name='media_category', field=models.ManyToManyField(blank=True, related_name='episode_categories', to='programs.MediaCategory'), ), migrations.AddField( model_name='episode', name='show', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Show'), ), migrations.AddField( model_name='enclosure', name='episode', field=models.ForeignKey(help_text='Include any number of media files; for example, perhaps include an iPhone-optimized, AppleTV-optimized and Flash Video set of video files. Note that the iTunes feed only accepts the first file. More uploading is available after clicking "Save and continue editing."', on_delete=django.db.models.deletion.CASCADE, to='programs.Episode'), ), migrations.AddField( model_name='childcategory', name='parent', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='child_category_parents', to='programs.ParentCategory'), ), migrations.AddField( model_name='aperiodicschedule', name='show', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programs.Show', verbose_name='refer to Show:'), ), ] autoradio-autoradio-3.6-4/autoradio/programs/migrations/0002_fixture.py000066400000000000000000000057731454362722700262250ustar00rootroot00000000000000# -*- coding: utf-8 -*- from django.db import models, migrations from django.core import serializers import os fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) #fixture_filename = 'initial_data.json' def load_fixture(apps, schema_editor): #print "" #print "Insert password for user 'autoradio' (administrator superuser)" #call_command("createsuperuser",username="autoradio",email="autoradio@casa.it") from django.core.management import call_command call_command("createsuperuser",username="autoradio",email="autoradio@casa.it",interactive=False) from django.contrib.auth.models import User u = User.objects.get(username__exact='autoradio') u.set_password('autoradio') u.save() for fixture_filename in os.listdir(fixture_dir): if fixture_filename[-5:] == ".json": fixture_file = os.path.join(fixture_dir, fixture_filename) print("load fixture from file: ",fixture_file) fixture = open(fixture_file, 'rb') objects = serializers.deserialize('json', fixture, ignorenonexistent=True) for obj in objects: obj.save() fixture.close() #def load_fixture(apps, schema_editor): # call_command('loaddata', 'initial_data', app_label='stations') def unload_fixture(apps, schema_editor): "Brutally deleting all entries for this model..." MyModel = apps.get_model("programs", "MediaCategory") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "ParentCategory") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "ChildCategory") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Giorno") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Configure") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "ProgramType") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Show") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Episode") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Enclosure") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "Schedule") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "ScheduleDone") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "PeriodicSchedule") MyModel.objects.all().delete() MyModel = apps.get_model("programs", "AperiodicSchedule") MyModel.objects.all().delete() # MyModel = apps.get_model("stations", "UserProfile") # MyModel.objects.get(user=apps.get_model("auth", "User").objects.get(username="autoradio")).delete() # apps.get_model("auth", "User").objects.get(username="autoradio").delete() class Migration(migrations.Migration): dependencies = [ ('programs', '0001_initial'), ] operations = [ migrations.RunPython(load_fixture, reverse_code=unload_fixture), ] autoradio-autoradio-3.6-4/autoradio/programs/migrations/__init__.py000066400000000000000000000000001454362722700256070ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/models.py000066400000000000000000001237001454362722700231740ustar00rootroot00000000000000 from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy from autoradio.programs.managers import EpisodeManager import datetime import calendar from django.db.models import Q from django import VERSION as djversion if ((djversion[0] == 1 and djversion[1] >= 3) or djversion[0] > 1): from django.db import models from django.db.models import signals class DeletingFileField(models.FileField): """ FileField subclass that deletes the refernced file when the model object itself is deleted. WARNING: Be careful using this class - it can cause data loss! This class makes at attempt to see if the file's referenced elsewhere, but it can get it wrong in any number of cases. """ def contribute_to_class(self, cls, name): super(DeletingFileField, self).contribute_to_class(cls, name) signals.post_delete.connect(self.delete_file, sender=cls) def delete_file(self, instance, sender, **kwargs): file = getattr(instance, self.attname) # If no other object of this type references the file, # and it's not the default value for future objects, # delete it from the backend. if file and file.name != self.default and \ not sender._default_manager.filter(**{self.name: file.name}): file.delete(save=False) elif file: # Otherwise, just close the file, so it doesn't tie up resources. file.close() else: DeletingFileField=models.FileField class MediaCategory(models.Model): """Category model for Media RSS""" MEDIA_CATEGORY_CHOICES = ( ('Action & Adventure', 'Action & Adventure'), ('Ads & Promotional', 'Ads & Promotional'), ('Anime & Animation', 'Anime & Animation'), ('Art & Experimental', 'Art & Experimental'), ('Business', 'Business'), ('Children & Family', 'Children & Family'), ('Comedy', 'Comedy'), ('Dance', 'Dance'), ('Documentary', 'Documentary'), ('Drama', 'Drama'), ('Educational', 'Educational'), ('Faith & Spirituality', 'Faith & Spirituality'), ('Health & Fitness', 'Health & Fitness'), ('Foreign', 'Foreign'), ('Gaming', 'Gaming'), ('Gay & Lesbian', 'Gay & Lesbian'), ('Home Video', 'Home Video'), ('Horror', 'Horror'), ('Independent', 'Independent'), ('Mature & Adult', 'Mature & Adult'), ('Movie (feature)', 'Movie (feature)'), ('Movie (short)', 'Movie (short)'), ('Movie Trailer', 'Movie Trailer'), ('Music & Musical', 'Music & Musical'), ('Nature', 'Nature'), ('News', 'News'), ('Political', 'Political'), ('Religious', 'Religious'), ('Romance', 'Romance'), ('Independent', 'Independent'), ('Sci-Fi & Fantasy', 'Sci-Fi & Fantasy'), ('Science & Technology', 'Science & Technology'), ('Special Interest', 'Special Interest'), ('Sports', 'Sports'), ('Stock Footage', 'Stock Footage'), ('Thriller', 'Thriller'), ('Travel', 'Travel'), ('TV Show', 'TV Show'), ('Western', 'Western'), ) name = models.CharField(max_length=50, choices=MEDIA_CATEGORY_CHOICES) slug = models.SlugField(blank=True, unique=False, help_text=ugettext_lazy('A slug is a URL-friendly nickname. For example, a slug for "Games & Hobbies" is "games-hobbies".')) class Meta(object): ordering = ['slug'] verbose_name = 'category (Media RSS)' verbose_name_plural = 'categories (Media RSS)' def __str__(self): return u'%s' % (self.name) class ParentCategory(models.Model): """Parent Category model.""" PARENT_CHOICES = ( ('Arts', 'Arts'), ('Business', 'Business'), ('Comedy', 'Comedy'), ('Education', 'Education'), ('Games & Hobbies', 'Games & Hobbies'), ('Government & Organizations', 'Government & Organizations'), ('Health', 'Health'), ('Kids & Family', 'Kids & Family'), ('Music', 'Music'), ('News & Politics', 'News & Politics'), ('Religion & Spirituality', 'Religion & Spirituality'), ('Science & Medicine', 'Science & Medicine'), ('Society & Culture', 'Society & Culture'), ('Sports & Recreation', 'Sports & Recreation'), ('Technology', 'Technology'), ('TV & Film', 'TV & Film'), ) name = models.CharField(max_length=50, choices=PARENT_CHOICES, help_text=ugettext_lazy('After saving this parent category, please map it to one or more Child Categories below.')) slug = models.SlugField(blank=True, unique=False, help_text=ugettext_lazy('A slug is a URL-friendly nickname. For example, a slug for "Games & Hobbies" is "games-hobbies".')) class Meta(object): ordering = ['slug'] verbose_name = 'category (iTunes parent)' verbose_name_plural = 'categories (iTunes parent)' def __str__(self): return u'%s' % (self.name) class ChildCategory(models.Model): """Child Category model.""" CHILD_CHOICES = ( ('Arts', ( ('Design', 'Design'), ('Fashion & Beauty', 'Fashion & Beauty'), ('Food', 'Food'), ('Literature', 'Literature'), ('Performing Arts', 'Performing Arts'), ('Visual Arts', 'Visual Arts'), ) ), ('Business', ( ('Business News', 'Business News'), ('Careers', 'Careers'), ('Investing', 'Investing'), ('Management & Marketing', 'Management & Marketing'), ('Shopping', 'Shopping'), ) ), ('Education', ( ('Education Technology', 'Education Technology'), ('Higher Education', 'Higher Education'), ('K-12', 'K-12'), ('Language Courses', 'Language Courses'), ('Training', 'Training'), ) ), ('Games & Hobbies', ( ('Automotive', 'Automotive'), ('Aviation', 'Aviation'), ('Hobbies', 'Hobbies'), ('Other Games', 'Other Games'), ('Video Games', 'Video Games'), ) ), ('Government & Organizations', ( ('Local', 'Local'), ('National', 'National'), ('Non-Profit', 'Non-Profit'), ('Regional', 'Regional'), ) ), ('Health', ( ('Alternative Health', 'Alternative Health'), ('Fitness & Nutrition', 'Fitness & Nutrition'), ('Self-Help', 'Self-Help'), ('Sexuality', 'Sexuality'), ) ), ('Religion & Spirituality', ( ('Buddhism', 'Buddhism'), ('Christianity', 'Christianity'), ('Hinduism', 'Hinduism'), ('Islam', 'Islam'), ('Judaism', 'Judaism'), ('Other', 'Other'), ('Spirituality', 'Spirituality'), ) ), ('Science & Medicine', ( ('Medicine', 'Medicine'), ('Natural Sciences', 'Natural Sciences'), ('Social Sciences', 'Social Sciences'), ) ), ('Society & Culture', ( ('History', 'History'), ('Personal Journals', 'Personal Journals'), ('Philosophy', 'Philosophy'), ('Places & Travel', 'Places & Travel'), ) ), ('Sports & Recreation', ( ('Amateur', 'Amateur'), ('College & High School', 'College & High School'), ('Outdoor', 'Outdoor'), ('Professional', 'Professional'), ) ), ('Technology', ( ('Gadgets', 'Gadgets'), ('Tech News', 'Tech News'), ('Podcasting', 'Podcasting'), ('Software How-To', 'Software How-To'), ) ), ) parent = models.ForeignKey(ParentCategory, related_name='child_category_parents', on_delete=models.CASCADE) name = models.CharField(max_length=50, blank=True, choices=CHILD_CHOICES, help_text=ugettext_lazy('Please choose a child category that corresponds to its respective parent category (e.g., "Design" is a child category of "Arts").
If no such child category exists for a parent category (e.g., Comedy, Kids & Family, Music, News & Politics, or TV & Film), simply leave this blank and save.')) slug = models.SlugField(blank=True, unique=False, help_text=ugettext_lazy('A slug is a URL-friendly nickname. For exmaple, a slug for "Fashion & Beauty" is "fashion-beauty".')) class Meta(object): ordering = ['parent', 'slug'] verbose_name = 'category (iTunes child)' verbose_name_plural = 'categories (iTunes child)' def __str__(self): if self.name!='': return u'%s > %s' % (self.parent, self.name) else: return u'%s' % (self.parent) def giorno_giorno(): giorni=[] for giorno in (calendar.day_name): #giorno=giorno.decode('utf-8') giorni.append(( giorno, giorno)) return giorni # yield 'Tutti','Tutti' class Giorno(models.Model): name = models.CharField(max_length=20,choices=giorno_giorno(),unique=True,\ help_text=ugettext_lazy("weekday name")) def __str__(self): return self.name class Configure(models.Model): sezione = models.CharField(max_length=50,unique=True\ ,default='show',editable=False) active = models.BooleanField(ugettext_lazy("Active show"),default=True,\ help_text=ugettext_lazy("activate/deactivate the intere program class")) emission_starttime = models.TimeField(ugettext_lazy('Programmed start time'),null=True,blank=True,\ help_text=ugettext_lazy("The start time from wich the programs will be active")) emission_endtime = models.TimeField(ugettext_lazy('Programmed end time'),null=True,blank=True,\ help_text=ugettext_lazy("The end time the programs will be active")) radiostation = models.CharField(max_length=50,unique=True, default='Radio',editable=True,\ help_text=ugettext_lazy("The station name for the print of programs book")) channel = models.CharField(max_length=80,unique=True, default='103', editable=True,\ help_text=ugettext_lazy("The station channel for the print of programs book")) mezzo = models.CharField(max_length=50,unique=True, default='analogico terrestre', editable=True,\ help_text=ugettext_lazy("The station kind of emission for the print of programs book")) type = models.CharField(max_length=50,unique=True, default='radiofonica', editable=True,\ help_text=ugettext_lazy("The station type for the print of programs book")) def __str__(self): if self.emission_starttime is None: emission_starttime = "-" else: emission_starttime = self.emission_starttime.isoformat() if self.emission_endtime is None: emission_endtime = "-" else: emission_endtime = self.emission_endtime.isoformat() return self.sezione+" "+self.active.__str__()+" "\ +emission_starttime+" "\ +emission_endtime class ProgramType(models.Model): code = models.CharField(ugettext_lazy("Code"),max_length=4,default=None,null=False,blank=False,unique=True) type = models.CharField(ugettext_lazy("Type"),max_length=200,default=None,null=False,blank=False) subtype = models.CharField(ugettext_lazy("SubType"),max_length=254,default=None,null=False,blank=False) description = models.TextField(ugettext_lazy("Description"),default=None,null=True,blank=True) def __str__(self): return self.type+"/"+self.subtype def Production(): for production in (ugettext_lazy("autoproduction"),ugettext_lazy("eteroproduction")): yield production, production class Show(models.Model): """Show model.""" title = models.CharField(max_length=255,help_text=ugettext_lazy("show title")) active = models.BooleanField(ugettext_lazy("Active"),default=True,help_text=ugettext_lazy("Activate the show for emission")) slug = models.SlugField(unique=True, help_text=ugettext_lazy('Auto-generated from Title.')) length = models.FloatField(ugettext_lazy("Time length (seconds)"),default=None,null=True,blank=True, help_text=ugettext_lazy('Time lenght how you want to see it in the palimpsest')) type = models.ForeignKey(ProgramType, verbose_name= ugettext_lazy('Program Type'), help_text=ugettext_lazy('The categorization that follow the italian law (you have to use it to produce the programs book') , on_delete=models.CASCADE) production = models.CharField(ugettext_lazy("Production"),max_length=30,choices=Production(),default=None,null=True,blank=True, help_text=ugettext_lazy('The type of production')) COPYRIGHT_CHOICES = ( ('Public domain', 'Public domain'), ('Creative Commons: Attribution (by)', 'Creative Commons: Attribution (by)'), ('Creative Commons: Attribution-Share Alike (by-sa)', 'Creative Commons: Attribution-Share Alike (by-sa)'), ('Creative Commons: Attribution-No Derivatives (by-nd)', 'Creative Commons: Attribution-No Derivatives (by-nd)'), ('Creative Commons: Attribution-Non-Commercial (by-nc)', 'Creative Commons: Attribution-Non-Commercial (by-nc)'), ('Creative Commons: Attribution-Non-Commercial-Share Alike (by-nc-sa)', 'Creative Commons: Attribution-Non-Commercial-Share Alike (by-nc-sa)'), ('Creative Commons: Attribution-Non-Commercial-No Dreivatives (by-nc-nd)', 'Creative Commons: Attribution-Non-Commercial-No Dreivatives (by-nc-nd)'), ('All rights reserved', 'All rights reserved'), ) EXPLICIT_CHOICES = ( ('Yes', 'Yes'), ('No', 'No'), ('Clean', 'Clean'), ) # RSS 2.0 organization = models.CharField(max_length=255, help_text=ugettext_lazy('Name of the organization, company or Web site producing the podcast.')) link = models.URLField(help_text=ugettext_lazy('URL of either the main website or the podcast section of the main website.')) description = models.TextField(help_text=ugettext_lazy('Describe subject matter, media format, episode schedule and other relevant information while incorporating keywords.')) language = models.CharField(max_length=5, default='en-us', help_text=ugettext_lazy('Default is American English. See ISO 639-1 and ISO 3166-1 for more language codes.'), blank=True) copyright = models.CharField(max_length=255, default='All rights reserved', choices=COPYRIGHT_CHOICES, help_text=ugettext_lazy('See Creative Commons licenses for more information.')) copyright_url = models.URLField('Copyright URL', blank=True, help_text=ugettext_lazy('A URL pointing to additional copyright information. Consider a Creative Commons license URL.')) author = models.ManyToManyField(User, related_name='display_authors', help_text=ugettext_lazy('Remember to save the user\'s name and e-mail address in the User application.
')) webmaster = models.ForeignKey(User, related_name='display_webmaster', blank=True, null=True, help_text=ugettext_lazy('Remember to save the user\'s name and e-mail address in the User application.') , on_delete=models.CASCADE) category_show = models.CharField('Category', max_length=255, blank=True, help_text=ugettext_lazy('Limited to one user-specified category for the sake of sanity.')) domain = models.URLField(blank=True, help_text=ugettext_lazy('A URL that identifies a categorization taxonomy.')) ttl = models.PositiveIntegerField('TTL', help_text=ugettext_lazy('"Time to Live," the number of minutes a channel can be cached before refreshing.'), blank=True, null=True) image = models.ImageField(upload_to='podcasts/shows/img/', help_text=ugettext_lazy('An attractive, original square JPEG (.jpg) or PNG (.png) image of 600x600 pixels. Image will be scaled down to 50x50 pixels at smallest in iTunes.'), blank=True) feedburner = models.URLField('FeedBurner URL', help_text=ugettext_lazy('Fill this out after saving this show and at least one episode. URL should look like "http://feeds.feedburner.com/TitleOfShow". See documentation for more.'), blank=True) # iTunes subtitle = models.CharField(max_length=255, help_text=ugettext_lazy('Looks best if only a few words, like a tagline.'), blank=True) summary = models.TextField(help_text=ugettext_lazy('Allows 4,000 characters. Description will be used if summary is blank.'), blank=True) category = models.ManyToManyField(ChildCategory, related_name='show_categories', help_text=ugettext_lazy('If selecting a category group with no child category (e.g., Comedy, Kids & Family, Music, News & Politics or TV & Film), save that parent category with a blank child category.
Selecting multiple category groups makes the podcast more likely to be found by users.
'), blank=True) explicit = models.CharField(max_length=255, default='No', choices=EXPLICIT_CHOICES, help_text=ugettext_lazy('"Clean" will put the clean iTunes graphic by it.'), blank=True) block = models.BooleanField(default=False, help_text=ugettext_lazy('Check to block this show from iTunes.
Show will remain blocked until unchecked.')) redirect = models.URLField(help_text=ugettext_lazy('The show\'s new URL feed if changing the URL of the current show feed. Must continue old feed for at least two weeks and write a 301 redirect for old feed.'), blank=True) keywords = models.CharField(max_length=255, help_text=ugettext_lazy('A comma-demlimited list of up to 12 words for iTunes searches. Perhaps include misspellings of the title.'), blank=True) itunes = models.URLField('iTunes Store URL', help_text=ugettext_lazy('Fill this out after saving this show and at least one episode. URL should look like "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=000000000". See documentation for more.'), blank=True) class Meta(object): ordering = ['organization', 'slug'] def __str__(self): return u'%s' % (self.title) #@models.permalink #def get_absolute_url(self): # return ('podcast_episodes', (), { 'slug': self.slug }) def get_absolute_url(self): from django.urls import reverse return reverse('podcast_episodes', args=[str(self.slug)]) class Episode(models.Model): STATUS_CHOICES = ( (1, 'Draft'), (2, 'Public'), (3, 'Private'), ) SECONDS_CHOICES = tuple(('%02d' % x, str(x)) for x in range(60)) EXPLICIT_CHOICES = ( ('Yes', 'Yes'), ('No', 'No'), ('Clean', 'Clean'), ) TYPE_CHOICES = ( ('Plain', 'Plain text'), ('HTML', 'HTML'), ) ROLE_CHOICES = ( ('Actor', 'Actor'), ('Adaptor', 'Adaptor'), ('Anchor person', 'Anchor person'), ('Animal Trainer', 'Animal Trainer'), ('Animator', 'Animator'), ('Announcer', 'Announcer'), ('Armourer', 'Armourer'), ('Art Director', 'Art Director'), ('Artist/Performer', 'Artist/Performer'), ('Assistant Camera', 'Assistant Camera'), ('Assistant Chief Lighting Technician', 'Assistant Chief Lighting Technician'), ('Assistant Director', 'Assistant Director'), ('Assistant Producer', 'Assistant Producer'), ('Assistant Visual Editor', 'Assistant Visual Editor'), ('Author', 'Author'), ('Broadcast Assistant', 'Broadcast Assistant'), ('Broadcast Journalist', 'Broadcast Journalist'), ('Camera Operator', 'Camera Operator'), ('Carpenter', 'Carpenter'), ('Casting', 'Casting'), ('Causeur', 'Causeur'), ('Chief Lighting Technician', 'Chief Lighting Technician'), ('Choir', 'Choir'), ('Choreographer', 'Choreographer'), ('Clapper Loader', 'Clapper Loader'), ('Commentary or Commentator', 'Commentary or Commentator'), ('Commissioning Broadcaster', 'Commissioning Broadcaster'), ('Composer', 'Composer'), ('Computer programmer', 'Computer programmer'), ('Conductor', 'Conductor'), ('Consultant', 'Consultant'), ('Continuity Checker', 'Continuity Checker'), ('Correspondent', 'Correspondent'), ('Costume Designer', 'Costume Designer'), ('Dancer', 'Dancer'), ('Dialogue Coach', 'Dialogue Coach'), ('Director', 'Director'), ('Director of Photography', 'Director of Photography'), ('Distribution Company', 'Distribution Company'), ('Draughtsman', 'Draughtsman'), ('Dresser', 'Dresser'), ('Dubber', 'Dubber'), ('Editor/Producer (News)', 'Editor/Producer (News)'), ('Editor-in-chief', 'Editor-in-chief'), ('Editor-of-the-Day', 'Editor-of-the-Day'), ('Ensemble', 'Ensemble'), ('Executive Producer', 'Executive Producer'), ('Expert', 'Expert'), ('Fight Director', 'Floor Manager'), ('Floor Manager', 'Floor Manager'), ('Focus Puller', 'Focus Puller'), ('Foley Artist', 'Foley Artist'), ('Foley Editor', 'Foley Editor'), ('Foley Mixer', 'Foley Mixer'), ('Graphic Assistant', 'Graphic Assistant'), ('Graphic Designer', 'Graphic Designer'), ('Greensman', 'Greensman'), ('Grip', 'Grip'), ('Hairdresser', 'Hairdresser'), ('Illustrator', 'Illustrator'), ('Interviewed Guest', 'Interviewed Guest'), ('Interviewer', 'Interviewer'), ('Key Character', 'Key Character'), ('Key Grip', 'Key Grip'), ('Key Talents', 'Key Talents'), ('Leadman', 'Leadman'), ('Librettist', 'Librettist'), ('Lighting director', 'Lighting director'), ('Lighting Technician', 'Lighting Technician'), ('Location Manager', 'Location Manager'), ('Lyricist', 'Lyricist'), ('Make Up Artist', 'Make Up Artist'), ('Manufacturer', 'Manufacturer'), ('Matte Artist', 'Matte Artist'), ('Music Arranger', 'Music Arranger'), ('Music Group', 'Music Group'), ('Musician', 'Musician'), ('News Reader', 'News Reader'), ('Orchestra', 'Orchestra'), ('Participant', 'Participant'), ('Photographer', 'Photographer'), ('Post-Production Editor', 'Post-Production Editor'), ('Producer', 'Producer'), ('Production Assistant', 'Production Assistant'), ('Production Company', 'Production Company'), ('Production Department', 'Production Department'), ('Production Manager', 'Production Manager'), ('Production Secretary', 'Production Secretary'), ('Programme Production Researcher', 'Programme Production Researcher'), ('Property Manager', 'Property Manager'), ('Publishing Company', 'Publishing Company'), ('Puppeteer', 'Puppeteer'), ('Pyrotechnician', 'Pyrotechnician'), ('Reporter', 'Reporter'), ('Rigger', 'Rigger'), ('Runner', 'Runner'), ('Scenario', 'Scenario'), ('Scenic Operative', 'Scenic Operative'), ('Script Supervisor', 'Script Supervisor'), ('Second Assistant Camera', 'Second Assistant Camera'), ('Second Assistant Director', 'Second Assistant Director'), ('Second Unit Director', 'Second Unit Director'), ('Set Designer', 'Set Designer'), ('Set Dresser', 'Set Dresser'), ('Sign Language', 'Sign Language'), ('Singer', 'Singer'), ('Sound Designer', 'Sound Designer'), ('Sound Mixer', 'Sound Mixer'), ('Sound Recordist', 'Sound Recordist'), ('Special Effects', 'Special Effects'), ('Stunts', 'Stunts'), ('Subtitles', 'Subtitles'), ('Technical Director', 'Technical Director'), ('Translation', 'Translation'), ('Transportation Manager', 'Transportation Manager'), ('Treatment / Programme Proposal', 'Treatment / Programme Proposal'), ('Vision Mixer', 'Vision Mixer'), ('Visual Editor', 'Visual Editor'), ('Visual Effects', 'Visual Effects'), ('Wardrobe', 'Wardrobe'), ('Witness', 'Witness'), ) STANDARD_CHOICES = ( ('Simple', 'Simple'), ('MPAA', 'MPAA'), ('V-chip', 'TV Parental Guidelines'), ) RATING_CHOICES = ( ('Simple', ( ('Adult', 'Adult'), ('Nonadult', 'Non-adult'), ) ), ('MPAA', ( ('G', 'G: General Audiences'), ('PG', 'PG: Parental Guidance Suggested'), ('PG-13', 'PG-13: Parents Strongly Cautioned'), ('R', 'R: Restricted'), ('NC-17', 'NC-17: No One 17 and Under Admitted'), ) ), ('TV Parental Guidelines', ( ('TV-Y', 'TV-Y: All children'), ('TV-Y7-FV', 'TV-Y7/TV-Y7-FV: Directed to older children'), ('TV-G', 'TV-G: General audience'), ('TV-PG', 'TV-PG: Parental guidance'), ('TV-14', 'TV-14: Parents strongly cautioned'), ('TV-MA', 'TV-MA: Mature audiences'), ) ), ) FREQUENCY_CHOICES = ( ('always', 'Always'), ('hourly', 'Hourly'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('yearly', 'Yearly'), ('never', 'Never'), ) # RSS 2.0 show = models.ForeignKey(Show , on_delete=models.CASCADE) title = models.CharField(max_length=255, help_text=ugettext_lazy('Make it specific but avoid explicit language. Limit to 100 characters for a Google video sitemap.')) active = models.BooleanField(ugettext_lazy("Active"),default=True) date = models.DateTimeField(ugettext_lazy('Recording date'),auto_now_add=True) title_type = models.CharField('Title type', max_length=255, blank=True, default='Plain', choices=TYPE_CHOICES) slug = models.SlugField(unique=True, help_text=ugettext_lazy('Auto-generated from Title.')) author = models.ManyToManyField(User, related_name='episode_authors', help_text=ugettext_lazy('Remember to save the user\'s name and e-mail address in the User application.')) description_type = models.CharField('Description type', max_length=255, blank=True, default='Plain', choices=TYPE_CHOICES) description = models.TextField(help_text=ugettext_lazy('Avoid explicit language. Google video sitempas allow 2,048 characters.')) captions = DeletingFileField(upload_to='podcasts/episodes/captions/', help_text=ugettext_lazy('For video podcasts. Good captioning choices include SubViewer, SubRip or TimedText.'), blank=True,max_length=255) category = models.CharField(max_length=255, blank=True, help_text=ugettext_lazy('Limited to one user-specified category for the sake of sanity.')) domain = models.URLField(blank=True, help_text=ugettext_lazy('A URL that identifies a categorization taxonomy.')) frequency = models.CharField(max_length=10, choices=FREQUENCY_CHOICES, blank=True, help_text=ugettext_lazy('The frequency with which the episode\'s data changes. For sitemaps.'), default='never') priority = models.DecimalField(max_digits=2, decimal_places=1, blank=True, null=True, help_text=ugettext_lazy('The relative priority of this episode compared to others. 1.0 is the most important. For sitemaps.'), default='0.5') status = models.IntegerField(choices=STATUS_CHOICES, default=2) update = models.DateTimeField(auto_now=True) # iTunes subtitle = models.CharField(max_length=255, help_text=ugettext_lazy('Looks best if only a few words like a tagline.'), blank=True) summary = models.TextField(help_text=ugettext_lazy('Allows 4,000 characters. Description will be used if summary is blank.'), blank=True) minutes = models.PositiveIntegerField(blank=True, null=True) seconds = models.CharField(max_length=2, blank=True, null=True, choices=SECONDS_CHOICES) keywords = models.CharField(max_length=255, help_text=ugettext_lazy('A comma-delimited list of words for searches, up to 12; perhaps include misspellings.'), blank=True, null=True) explicit = models.CharField(max_length=255, choices=EXPLICIT_CHOICES, help_text=ugettext_lazy('"Clean" will put the clean iTunes graphic by it.'), default='No') block = models.BooleanField(help_text=ugettext_lazy('Check to block this episode from iTunes because
its content might cause the entire show to be
removed from iTunes.'), default=False) # Media RSS role = models.CharField(max_length=255, blank=True, choices=ROLE_CHOICES, help_text=ugettext_lazy('Role codes provided by the European Broadcasting Union.')) media_category = models.ManyToManyField(MediaCategory, related_name='episode_categories', blank=True) standard = models.CharField(max_length=255, blank=True, choices=STANDARD_CHOICES, default='Simple') rating = models.CharField(max_length=255, blank=True, choices=RATING_CHOICES, help_text=ugettext_lazy('If used, selection must match respective Scheme selection.'), default='Nonadult') image = models.ImageField(upload_to='podcasts/episodes/img/', help_text=ugettext_lazy('A still image from a video file, but for episode artwork to display in iTunes, image must be saved to file\'s metadata before episode uploading!'), blank=True) text = models.TextField(blank=True, help_text=ugettext_lazy('Media RSS text transcript. Must use tags. Please see the Media RSS 2.0 specification for syntax.')) deny = models.BooleanField(default=False, help_text=ugettext_lazy('Check to deny episode to be shown to users from specified countries.')) restriction = models.CharField(max_length=255, blank=True, help_text=ugettext_lazy('A space-delimited list of ISO 3166-1-coded countries.')) # Dublin Core start = models.DateTimeField(blank=True, null=True, help_text=ugettext_lazy('Start date and time that the media is valid.')) end = models.DateTimeField(blank=True, null=True, help_text=ugettext_lazy('End date and time that the media is valid.')) scheme = models.CharField(max_length=255, blank=True, default='W3C-DTF') name = models.CharField(max_length=255, blank=True, help_text=ugettext_lazy('Any helper name to distinguish this time period.')) # Google Media preview = models.BooleanField(default=False, help_text=ugettext_lazy("Check to allow Google to show a preview of your media in search results.")) preview_start_mins = models.PositiveIntegerField('Preview start (minutes)', blank=True, null=True, help_text=ugettext_lazy('Start time (minutes) of the media\'s preview,
shown on Google.com search results before
clicking through to see full video.')) preview_start_secs = models.CharField('Preview start (seconds)', max_length=2, blank=True, null=True, choices=SECONDS_CHOICES, help_text=ugettext_lazy('Start time (seconds) of the media\'s preview.')) preview_end_mins = models.PositiveIntegerField('Preview end (minutes)', blank=True, null=True, help_text=ugettext_lazy('End time (minutes) of the media\'s preview,
shown on Google.com search results before
clicking through to see full video.')) preview_end_secs = models.CharField('Preview end (seconds)', max_length=2, blank=True, null=True, choices=SECONDS_CHOICES, help_text=ugettext_lazy('End time (seconds) of the media\'s preview.')) host = models.BooleanField(default=False, help_text=ugettext_lazy('Check to allow Google to host your media after it expires. Must set expiration date in Dublin Core.')) # Behind the scenes objects = EpisodeManager() class Meta(object): ordering = ['-date', 'slug'] def __str__(self): return u'%s' % (self.title) #@models.permalink #def get_absolute_url(self): # return ('podcast_episode', (), { 'show_slug': self.show.slug, 'episode_slug': self.slug }) def get_absolute_url(self): from django.urls import reverse return reverse('podcast_episode', args=[str(self.show.slug),str(self.slug)]) def seconds_total(self): try: return (((float(self.minutes)) * 60) + (float(self.seconds))) except: return 0 def was_recorded_today(self): return self.rec_date.date() == datetime.date.today() was_recorded_today.short_description = ugettext_lazy('Recorded today?') def __str__(self): return self.title class Enclosure(models.Model): """Enclosure model.""" MIME_CHOICES = ( ('audio/ogg', '.ogg (audio)'), ('audio/mpeg', '.mp3 (audio)'), ('audio/x-m4a', '.m4a (audio)'), ('video/mp4', '.mp4 (audio or video)'), ('video/x-m4v', '.m4v (video)'), ('video/quicktime', '.mov (video)'), ('application/pdf', '.pdf (document)'), ('image/jpeg', '.jpg, .jpeg, .jpe (image)') ) MEDIUM_CHOICES = ( ('Audio', 'Audio'), ('Video', 'Video'), ('Document', 'Document'), ('Image', 'Image'), ('Executable', 'Executable'), ) EXPRESSION_CHOICES = ( ('Sample', 'Sample'), ('Full', 'Full'), ('Nonstop', 'Non-stop'), ) ALGO_CHOICES = ( ('MD5', 'MD5'), ('SHA-1', 'SHA-1'), ) FRAME_CHOICES = (( '29.97','29.97'),) BITRATE_CHOICES = ( ( "8","8"), ("11.025","11.025"), ("16","16"), ("22.050","22.050"), ("32","32"), ("44.1","44.1"), ("48","48"), ("96","96") ) SAMPLE_CHOICHES = ( ("24","24"), ("48","48"), ("64","64"), ("96","96"), ("128","128"), ("160","160"), ("196","196"), ("320","320") ) CHANNEL_CHOICES = ( ("2","2"), ("1","1") ) title = models.CharField(max_length=255, blank=True, default=None, help_text=ugettext_lazy('Title is generally only useful with multiple enclosures.')) file = DeletingFileField(upload_to='podcasts/episodes/files/', help_text=ugettext_lazy('Either upload or use the "Player" text box below. If uploading, file must be less than or equal to 30 MB for a Google video sitemap.'),blank=False, null=False,max_length=255) mime = models.CharField('Format', max_length=255, choices=MIME_CHOICES, blank=True) medium = models.CharField(max_length=255, blank=True, choices=MEDIUM_CHOICES) expression = models.CharField(max_length=25, choices=EXPRESSION_CHOICES, blank=True) frame = models.CharField('Frame rate', max_length=5, help_text=ugettext_lazy('Measured in frames per second (fps), often 29.97.'),choices=FRAME_CHOICES,blank=True) bitrate = models.CharField('Bit rate', max_length=5, blank=True, help_text=ugettext_lazy('Measured in kilobits per second (kbps), often 128 or 192.'),choices=BITRATE_CHOICES) sample = models.CharField('Sample rate', max_length=5, blank=True, help_text=ugettext_lazy('Measured in kilohertz (kHz), often 44.1.'),choices=SAMPLE_CHOICHES) channel = models.CharField(max_length=5, blank=True, help_text=ugettext_lazy('Number of channels; 2 for stereo, 1 for mono.'),choices=CHANNEL_CHOICES) algo = models.CharField('Hash algorithm', max_length=50, blank=True, choices=ALGO_CHOICES) hash = models.CharField(max_length=255, blank=True, help_text=ugettext_lazy('MD-5 or SHA-1 file hash.')) player = models.URLField(help_text=ugettext_lazy('URL of the player console that plays the media. Could be your own .swf, but most likely a YouTube URL, such as http://www.youtube.com/v/UZCfK8pVztw (not the permalink, which looks like http://www.youtube.com/watch?v=UZCfK8pVztw).'), blank=True) embed = models.BooleanField(help_text=ugettext_lazy('Check to allow Google to embed your external player in search results on Google Video.'), blank=True) width = models.PositiveIntegerField(blank=True, null=True, help_text=ugettext_lazy("Width of the browser window in
which the URL should be opened.
YouTube's default is 425.")) height = models.PositiveIntegerField(blank=True, null=True, help_text=ugettext_lazy("Height of the browser window in
which the URL should be opened.
YouTube's default is 344.")) episode = models.ForeignKey(Episode, help_text=ugettext_lazy('Include any number of media files; for example, perhaps include an iPhone-optimized, AppleTV-optimized and Flash Video set of video files. Note that the iTunes feed only accepts the first file. More uploading is available after clicking "Save and continue editing."'), on_delete=models.CASCADE) class Meta(object): ordering = ['mime', 'file'] def save(self, *args, **kwargs): """ Return a default title numbered by enclosure number a missing title is not a good idea for rss and web interface """ if self.title == "": self.title = "Part "+str(Enclosure.objects.filter(Q(episode=self.episode)).all().count()+1) super(Enclosure, self).save(*args, **kwargs) def __str__(self): return u'%s' % (self.file) class Schedule(models.Model): # program = models.ForeignKey(Program, edit_inline=models.TABULAR,\ # num_in_admin=2,verbose_name='si riferisce al programma:',editable=False) episode = models.ForeignKey(Episode, \ verbose_name=ugettext_lazy('Linked episode:'), on_delete=models.CASCADE) emission_date = models.DateTimeField(ugettext_lazy('programmed date'),\ help_text=ugettext_lazy("This is the date and time when the program will be on air")) # def emitted(self): # return self.emission_done != None # emitted.short_description = 'Trasmesso' def was_scheduled_today(self): return self.emission_date.date() == datetime.date.today() was_scheduled_today.short_description = ugettext_lazy('Scheduled for today?') def refepisode(self): return self.episode.title refepisode.short_description = ugettext_lazy('Linked episode:') def __str__(self): return str(self.episode.title) class ScheduleDone(models.Model): schedule = models.ForeignKey(Schedule, \ verbose_name=ugettext_lazy('Linked schedule:'), on_delete=models.CASCADE) enclosure = models.ForeignKey(Enclosure, \ verbose_name=ugettext_lazy('Linked enclosure:'), on_delete=models.CASCADE) emission_done = models.DateTimeField(ugettext_lazy('emission done')\ ,null=True,editable=False ) def __str__(self): return str(self.emission_done) class PeriodicSchedule(models.Model): # program = models.ForeignKey(Program, edit_inline=models.TABULAR,\ # num_in_admin=2,verbose_name='si riferisce al programma:',editable=False) show = models.ForeignKey(Show,verbose_name=\ ugettext_lazy('refer to show:'), on_delete=models.CASCADE) start_date = models.DateField(ugettext_lazy('Programmed start date'),null=True,blank=True,\ help_text=ugettext_lazy("The program will be in palimpsest starting from this date")) end_date = models.DateField(ugettext_lazy('Programmed end date'),null=True,blank=True,\ help_text=ugettext_lazy("The program will be in palimpsest ending this date")) time = models.TimeField(ugettext_lazy('Programmed time'),null=True,blank=True,\ help_text=ugettext_lazy("This is the time when the program is planned in palimpsest")) giorni = models.ManyToManyField(Giorno,verbose_name=ugettext_lazy('Programmed days'),blank=True,\ help_text=ugettext_lazy("The program will be in palimpsest those weekdays")) def __str__(self): return str(self.show) class AperiodicSchedule(models.Model): # program = models.ForeignKey(Program, edit_inline=models.TABULAR,\ # num_in_admin=2,verbose_name='si riferisce al programma:',editable=False) show = models.ForeignKey(Show, verbose_name=\ ugettext_lazy('refer to Show:'), on_delete=models.CASCADE) emission_date = models.DateTimeField(ugettext_lazy('Programmed date'),\ help_text=ugettext_lazy("This is the date and time when the program is planned in palimsest")) def was_scheduled_today(self): return self.emission_date.date() == datetime.date.today() was_scheduled_today.short_description = ugettext_lazy('Programmed for today?') def __str__(self): return str(self.show) autoradio-autoradio-3.6-4/autoradio/programs/static/000077500000000000000000000000001454362722700226235ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/static/programs/000077500000000000000000000000001454362722700244555ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/static/programs/css/000077500000000000000000000000001454362722700252455ustar00rootroot00000000000000autoradio-autoradio-3.6-4/autoradio/programs/static/programs/css/base.css000066400000000000000000000223761454362722700267030ustar00rootroot00000000000000/* djangoproject.com by Wilson Miner (wilson@lawrence.com) Copyright (c) 2005 Lawrence Journal-World. Please don't steal. */ /* SETUP */ body { margin:0; padding:0; background:#092e20; color:white; } body, th, td { font:12px/1.4em Verdana,sans-serif; } #container { position:relative; min-width:55em; max-width:100em; } #homepage #container { max-width:100em; } /* LINKS */ a {text-decoration: none;} a img {border: none;} a:link, a:visited { color:#ffc757; } #content-main a:link, #content-main a:visited { color:#ab5603; text-decoration:underline; } #content-secondary a:link, #content-secondary a:visited { color:#ffc757; text-decoration:none; } a:hover { color:#ffe761; } #content-main a:hover { background-color:#E0FFB8; color:#234f32; text-decoration:none; } #content-secondary a:hover { color:#ffe761; background:none; } #content-main h2 a, #content-main h3 a { text-decoration:none !important; } /* HEADER */ #header { position:relative; height:6.5em; background:#092e20; } #header h1#logo { margin:0; width:111px; height:41px; position:absolute; bottom:10px; left:25px; } /* NAV */ #nav-global { position:absolute; margin:0; bottom:0; right:0; font-family:"Trebuchet MS",sans-serif; white-space:nowrap; } #nav-global li { display:block; float:left; list-style-type:none; margin:0; padding:0; } #nav-global a { display:block; float:left; padding:5em 16px 10px 16px; background:#092e20; } #nav-global a:hover { color:white; background:#234f32; } #homepage #nav-homepage a, #overview #nav-overview a, #download #nav-download a, #documentation #nav-documentation a, #weblog #nav-weblog a, #community #nav-community a, #blogroll #nav-blogroll a, #code #nav-code a { color:white; background:#092e20 url(../img/site/nav_bg.gif) bottom repeat-x; } /* COLUMNS */ #columnwrap { background:#234f32; padding-bottom:10px; } #subwrap { background:#326342; width:73%; float:left; padding-bottom:10px; } #content-main { float:left; width:70%; background:white; color:black; padding-bottom:10px; } #generic #content-main, #code #content-main { width:100%; } #content-main * { margin-left:22px; margin-right:24px; } #content-main * * { margin-left:0; margin-right:0; } .sidebar { font-size:92%; } .sidebar * { margin-left:14px; margin-right:14px; } .sidebar * * { margin-left:0; margin-right:0; } #content-extra { float:right; width:27%; } #content-related { float:right; width:30%;} #content-secondary { clear:both; background:#487858; margin-left:0; margin-right:0; margin-top:15px; margin-bottom:-10px; padding:10px 24px; color:white; } .subcol-primary, .subcol-secondary { width:40%; float:left; padding-bottom:1.2em; } .subcol-primary { margin-right:1%; } /* CONTENT */ h1,h2,h3 { margin-top:.8em; font-family:"Trebuchet MS",sans-serif; font-weight:normal; } h1 { font-size:218%; margin-top:.6em; margin-bottom:.6em; color:#092e20; line-height:1.1em; } h2 { font-size:150%; margin-top:1em; margin-bottom:.2em; line-height:1.2em; color:#092e20; } #homepage h2 { font-size:140%; } h3 { font-size:125%; font-weight:bold; margin-bottom:.2em; color:#487858; } h4 { font-size:100%; font-weight:bold; margin-bottom:-3px; margin-top:1.2em; text-transform:uppercase; letter-spacing:1px; } h4 pre, h4 tt, h4 .literal { text-transform:none; } h5 { font-size:1em; font-weight:bold; margin-top:1.5em; margin-bottom:3px; } p, ul, dl { margin-top:.6em; margin-bottom:.8em; } hr { color:#ccc; background-color:#ccc; height:1px; border:0; } p.date { color:#487858; margin-top:-.2em; } p.more { margin-top:-.4em; } .sidebar p.date { color:#90ba9e; } #content-secondary h2, .sidebar h2 { color:white; } #content-secondary h3, .sidebar h3 { color:#9aef3f; } #content-secondary h2:first-child { margin-top:.6em; } .sidebar h2:first-child { margin-top:.8em; } #content-main h2, #content-main h3 { margin-top:1.2em; } h2.deck { margin-top:-.5em !important; margin-bottom:.6em; color:#487858; } ins { text-decoration: none; } ins a { text-decoration: none; } /* LISTS */ ul { padding-left:2em; } ol { padding-left:30px; } ul li { list-style-type:square; margin-bottom:.4em; } ul ul { padding-left:1.2em; } ul ul ul { padding-left:1em; } ul.linklist, ul.toc { padding-left:0; } ul.toc ul { margin-left:.6em; } ul.toc ul li { list-style-type:square; } ul.toc ul ul li { list-style-type:disc; } ul.linklist li, ul.toc li { list-style-type:none; } dt { font-weight:bold; margin-top:.5em; font-size:1.1em; } dd { margin-bottom:.8em; } /* RSS */ a.rss { font:bold 10px Verdana, sans-serif; padding:0 .2em; border: 1px solid; text-decoration:none; background:#f60;color: #fff; border-color:#ffc8a4 #7d3302 #3f1a01 #ff9a57; margin:0 3px; vertical-align:middle; } #content-main a.rss { color:#fff; text-decoration:none; } a.rss:hover, a.rss:link, a.rss:visited { color:#fff; text-decoration:none; } /* BLOCKQUOTES */ #weblog blockquote { padding-left:0.8em; padding-right:1em; font:125%/1.2em "Trebuchet MS", sans-serif; color:#234f32; border-left:2px solid #94da3a; } .sidebar blockquote { margin-top:1.5em; margin-bottom:1.5em; } .sidebar blockquote p { font:italic 175%/1.2em "Trebuchet MS",sans-serif; color:#94da3a; } .sidebar blockquote cite { display:block; font-style:normal; line-height:1.2em; margin-top:-.8em; color:#94da3a; } .sidebar cite strong { font-weight:normal; color:white; } /* CODE BLOCKS */ .literal { white-space:nowrap; } .literal, .literal-block { color:#234f32; } .sidebar .literal { color:white; background:transparent; font-size:11px; } pre, .literal-block { font-size:medium; background:#E0FFB8; border:1px solid #94da3a; border-width:1px 0; margin: 1em 0; padding: .3em .4em; overflow: auto; } dt .literal, table .literal { background:none; } textarea.codedump { font-size:10px; color:#234f32; width:100%; background:#E0FFB8; border:1px solid #94da3a; border-width:1px 0; padding: .3em .4em; } /* NOTES & ADMONITIONS */ .note, .admonition, .caution { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; } .admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;} .admonition .last { margin-bottom:0 !important; } .admonition-philosophy { padding-left:65px; background:url(../img/doc/icons/docicons-philosophy.gif) .8em .8em no-repeat;} .admonition-note, .caution { padding-left:65px; background:url(../img/doc/icons/docicons-note.gif) .8em .8em no-repeat;} .admonition-behind-the-scenes { padding-left:65px; background:url(../img/doc/icons/docicons-behindscenes.gif) .8em .8em no-repeat;} /* DOCS */ #documentation h2, #documentation h3, #documentation h4 { margin-top:1.4em; } #documentation dd { margin-left:1em; } #content-main table { color:#000; } table.docutils { border-collapse:collapse; } table.docutils thead th { border-bottom:2px solid #dfdfdf; text-align:left; } table.docutils td, table.docutils th { border-bottom:1px solid #dfdfdf; padding:4px 2px;} table.docutils td p { margin-top:0; margin-bottom:.5em; } #documentation #content-related .literal { background:transparent !important; } /* BILLBOARDS */ #billboard { background:#94da3a url(../img/site/bbdsm_bg.gif) repeat-x; border-bottom:6px solid #092e20; } #billboard h2 { margin:0; } #generic #billboard { display:none; } #homepage #billboard { background-image: url(../img/site/bbd_bg.gif); } #homepage #billboard h2 { margin:0; text-indent:-5000px; height:80px; width:633px; background:url(../img/site/bbd_homepage.gif) no-repeat; } #overview #billboard h2 { margin:0; text-indent:-5000px; height:60px; width:203px; background:url(../img/site/bbd_overview.gif) no-repeat; } #download #billboard h2 { margin:0; text-indent:-5000px; height:60px; width:203px; background:url(../img/site/bbd_download.gif) no-repeat; } #documentation #billboard h2 a { display:block; margin:0; text-indent:-5000px; height:60px; width:226px; background:url(../img/site/bbd_documentation.gif) no-repeat; } #weblog #billboard h2 a { display:block; margin:0; text-indent:-5000px; height:60px; width:226px; background:url(../img/site/bbd_weblog.gif) no-repeat; } #community #billboard h2 { display:block; margin:0; text-indent:-5000px; height:60px; width:226px; background:url(../img/site/bbd_community.gif) no-repeat; } #blogroll #billboard h2 { display:block; margin:0; text-indent:-5000px; height:60px; width:168px; background:url(../img/site/bbd_blogroll.gif) no-repeat; } #code #billboard h2 a { display:block; margin:0; text-indent:-5000px; height:60px; width:184px; background:url(../img/site/bbd_code.gif) no-repeat; } /* FOOTER */ #footer { clear:both; color:#487858; padding:10px 20px; font-size:90%; } /* COMMENTS */ .comment { margin:15px 0; } div.comment p { margin-left:1em; } #weblog div.comment p.date { margin-bottom:.2em; color:#94da3a; } /* MISC */ .small { font-size:90%; } h3 .small { font-size:80%; } .quiet { font-weight:normal; } .clear { clear:both; } #content-main .quiet { color:#487858; } #content-secondary .quiet { color:#90ba9e; } /* CLEARFIX KLUDGE */ #columnwrap:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } #columnwrap { display: inline-block; } /* Hides from IE-mac \*/ * html #columnwrap { height: 1%; } #columnwrap { display: block; } /* End hide from IE-mac */ #subwrap:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } #subwrap { display: inline-block; } /* Hides from IE-mac \*/ * html #subwrap { height: 1%; } #subwrap { display: block; } /* End hide from IE-mac */om IE-mac */ autoradio-autoradio-3.6-4/autoradio/programs/static/programs/css/player.css000066400000000000000000000047401454362722700272600ustar00rootroot00000000000000body { margin: 0; padding: 0; border: 0; font-family: arial, helvetica, sans-serif; font-size: 100%; background: #234f32; } div#header-wrap, div#footer-wrap { background: #092e20; } div#content-wrap { background: #234f32; width: 960px; margin: 0 auto; } div#header, div#content, div#footer { width: 960px; margin: 0 auto; color: #fff; } div#header, div#content { text-shadow: #000 0 0 0; } div#return-wrap { background: #92cc47; } div#return { margin: 0 auto; width: 960px; color: #386a42; } div#return p { margin: 0; padding: 8px 16px; font-size: .85em; font-weight: bold; } div#return a { color: #386a42; } div#return a:hover { color: #092e20; background: none; } div#content { background: #fff; color: #222; overflow: auto; width: 100%; } div#footer { padding: 1em 0; } h1, h2, h3, h4, h5, h6, p, dl, dt, dd, img { margin: 0; padding: 16px; border: 0; display: block; } h1 { margin: 0 16px; padding: 1em 0 0; font-size: 2em; width: 375px; height: 95px; text-indent: -9999px; } h2 { font-size: 1.25em; } h2 a { color: #092e20; } h2 a:hover { background: #e0ffb8; color: #574f32; text-decoration: none; } h3 { padding: 0 16px 8px; font-size: 1em; color: #444; font-weight: normal; } h4, h5 { padding: 0 16px 8px; } ul, li { margin: 0; padding: 0; list-style: none; } ul { margin: 0 8px 16px; } li { margin-left: 24px; list-style: square; font-size: .85em; line-height: 24px; } dl, dt, dd { padding: 8px 0; color: #000; } dt, dd { font-size: .8em; padding: 0 16px 8px; } dt { font-weight: bold; float: left; text-align: right; width: 80px; } dd { margin-left: 100px; } #content p { padding: 0 16px 16px; font-size: .8em; line-height: 1.25em; } #content p.back { padding: 16px 16px 0; } #footer p { padding: 0 16px; font-size: .7em; color: #467856; font-family: verdana, tahoma, sans-serif; } #footer a { color: #f7c757; text-decoration: none; } #footer a:hover { color: #f2e761; background: none; } div.image { float: right; margin: 0 16px 16px; border: 1px solid #94da3a; padding: 7px; background: #e0ffb8; } div.image img { padding: 0; } a { color: #b25603; } a:hover { background: #e0ffb8; color: #574f32; text-decoration: none; } div#player { width: 288px; height: 300px; position: fixed; top: 50%; margin-top: -150px ; left: 50%; margin-left:-144px; } div#player img {padding:0; visibility:show; } div#player a, #player div { display: block; width: 50px; height: 50px; background-position: 75px 262px;position: absolute; top: 10px; left: 112px; border:2px solid #666; } div#player a b, #player div b { display: none; } autoradio-autoradio-3.6-4/autoradio/programs/static/programs/css/podcast.css000066400000000000000000000041261454362722700274170ustar00rootroot00000000000000body { margin: 0; padding: 0; border: 0; font-family: arial, helvetica, sans-serif; font-size: 100%; background: #234f32; } div#header-wrap, div#footer-wrap { background: #092e20; } div#content-wrap { background: #234f32; width: 960px; margin: 0 auto; } div#header, div#content, div#footer { width: 960px; margin: 0 auto; color: #fff; } div#header, div#content { text-shadow: #000 0 0 0; } div#return-wrap { background: #92cc47; } div#return { margin: 0 auto; width: 960px; color: #386a42; } div#return p { margin: 0; padding: 8px 16px; font-size: .85em; font-weight: bold; } div#return a { color: #386a42; } div#return a:hover { color: #092e20; background: none; } div#content { background: #fff; color: #222; overflow: auto; width: 100%; } div#footer { padding: 1em 0; } h1, h2, h3, h4, h5, h6, p, dl, dt, dd, img { margin: 0; padding: 16px; border: 0; display: block; } h1 { margin: 0 16px; padding: 1em 0 0; font-size: 2em; width: 375px; height: 95px; text-indent: -9999px; } h2 { font-size: 1.25em; } h2 a { color: #092e20; } h2 a:hover { background: #e0ffb8; color: #574f32; text-decoration: none; } h3 { padding: 0 16px 8px; font-size: 1em; color: #444; font-weight: normal; } h4, h5 { padding: 0 16px 8px; } ul, li { margin: 0; padding: 0; list-style: none; } ul { margin: 0 8px 16px; } li { margin-left: 24px; list-style: square; font-size: .85em; line-height: 24px; } dl, dt, dd { padding: 8px 0; color: #000; } dt, dd { font-size: .8em; padding: 0 16px 8px; } dt { font-weight: bold; float: left; text-align: right; width: 80px; } dd { margin-left: 100px; } #content p { padding: 0 16px 16px; font-size: .8em; line-height: 1.25em; } #content p.back { padding: 16px 16px 0; } #footer p { padding: 0 16px; font-size: .7em; color: #467856; font-family: verdana, tahoma, sans-serif; } #footer a { color: #f7c757; text-decoration: none; } #footer a:hover { color: #f2e761; background: none; } div.image { float: right; margin: 0 16px 16px; border: 1px solid #94da3a; padding: 7px; background: #e0ffb8; } div.image img { padding: 0; } a { color: #b25603; } a:hover { background: #e0ffb8; color: #574f32; text-decoration: none; }autoradio-autoradio-3.6-4/autoradio/programs/static/programs/css/print.css000066400000000000000000000011121454362722700271060ustar00rootroot00000000000000@import url(base.css); @page { size: 7in 9.25in; margin: .75in .5in .75in 1in; } body { font-size:10pt; } /* Hide unneccessary content */ #header, #billboard, #content-extra, #documentation #content-secondary, #documentation #content-related { display:none; } /* Fix widths */ #container { width:7in; } #subwrap, #content-main { width:7in; float:none; } /* Formatting and display fixes */ #content { border-top:none; } .literal-block { overflow:visible; } /* Typographic adjustments */ #content-main p, #content-main h2, #content-main h3, #content-main h4 { margin-bottom:1em; }autoradio-autoradio-3.6-4/autoradio/programs/static/programs/mediacastlogo.png000066400000000000000000000235261454362722700300060ustar00rootroot00000000000000PNG  IHDRw_HtEXtSoftwareAdobe ImageReadyqe<&IDATx] E>}Y$bI,>ED$%,>ŽʢO)O@T YXTYQ21RꙚ۷Iw}{:u)9t..@b`vqb9zrÛ8nܺg f|,g&vXPd+J AeX| /#?u(&^\IAthhprgHaF\[ˎ00p\k.7"Y& j_m,M=>􄪆hߥk+gB@lIFHlG rg.v.݈`Xh]kyB'|ipۋڻ0eMGX1R&]u&uS5khmޡ%LL:4y uNfT=U‹%5HG2.hbf Fg抅Os ${82oţC(CƗyy5;$qS8ZcyP2`1:54< qu~Spi~S2Nd]:6^_&AE5Y1\aNA§8$Tto}- E /oG !C&08=4˸>/ku44RvM鄮zUEYVz;,^?yP]sl꘸&Xŋ(QF/5HdN߾xCgTzݗŕb?otaѡ#;L1ҢB~X!vPŤ/8CB(#Ed ⸋Ts%DC#O6>[f7tj0D7>.G l dO:BP:DolCz4{Q~)~?]9{yNBLA6F?TC#gT5BPm:`&"^dmA PknoM]CCc(1NNۣss E6#T ͂iEڱ(e1R@ye0fř ^ _xvk>R~-̋ 9<|ޣÐԲ@yz~4 \N կ]97#A/v{CiU! {p F؝bOM+zE ud[ʯdXgge=6~E(ߡ26&3%i( P#O^oBIo N[P>#.MP姰 gD|>YF[Pʲ'}6I)k[I/S#{k,<@#|eQ< z':ٖKE氜(!TI>Sm}r5b)/cE¥)+߽'(]v85YGF(Z+d2|bDkio5w,JbMoG9{I"IY@lrJ *̓ -f\Q{IuSNZo\L#MW,_!G?IA=:eM<{k &fRmde Xe'JJ 7Q$&3W(MLxʬki<,oh;M-&b.o*PG XWVF [ZLk Æy6t:Hg\by|1U9uc4rI0cV3g6TvXs%t;[JBM1M=N|CIOSTQˤ e5s C8"8߮)/ê`G̋FyVa l[={fL柦3# ``B,Rz`dA>oo[CF*NT*} Gђȡ^ 0)G-Ǩ@s髽" P,Yޱ5ݏUL4uq]C OG ۉ׹> s \!}ςQf@G{ :Jxlv\̴c>c̉7̋z"w^;N 4Ss|Gɿ !1ܽ)adE|<̎i2Qz03]B:8bq+c;AR+.z/O|G#EQ(Tw-gEo$/b wm5ȱ}% `ׁZ ɣF"9MT&M+CBdn{q=!Bm$35 \xR89AY_7h\"NΑy1He5#6Yϣ(FCZ~GbT:aB:~ L"cYd0B];'AcM wO6;T$e!Y5 B% 6~Ib)B" Y9f.h{Wur*++q(/, ,̋$z Dzxu^n%3(+R(ި!I=s2D6RL\Z^$#׆PZETYjLs&:'3]hEػI f!Ր-A\c Qj$D5z+;`sA02Cf]AHIƎ{*|405UmZyQeX-^fE)}r?M$!Pi"崈jb,F9G&)3.Q/oN1M?Vo?KP@UBժ"BgU5j2zHkMΏx-L2Y [/>>}6TjPVs=V/g{GŤQp|z8^k#퇥灈n4V4b4\;L~qgոմ\;O(#I<Äi6긯bW+}P*G^s$ /ثS( Wnl@=Ψ3W& }fG/ zkx";c7ߡp4a1{ D4Iy}mяBieeJl!7 kcELzlBDv NKWp2C#*ciFy(BnI&*fJ}-P)EJF|W6bn2\B!ّ9C?&U⏡vIsK<M ϖR!mC=;ӽCI穕ߑ Hݰ@?YBfE`pxzaĜBlPo^:itBo ?l0G `ar8 3)ϰ= &51x'AF3|$ 1*uB쟒=dd5Ch|Gj̾s$m`$@>Ԅ.Z SvV}2>ϗvRv6+^ZRU&GnoTC?ӑu3!Yܢlb7r(5uzR[ Gi{R (\ Cw6avoG6qbPoAQ>6K 6R; C= دL!@GG qO tF?C9-PhYzrި#{PNJ0Qh#{T0f1s7Iӊy߇hx. 8% g88ۄI&!6o &Df7+M?&XOm"b6JXq;@FYG.$_ߠwhCwJ7NCaϑ0x~}<@OJrV@] 'kʂ2D̻b ,oG5i {vِ qHs> L$+|"@4 n9kEHm̿V$M0N&]CfJe / t|T-ksF9I3a`bٲ!)k+M%CvjwMBrhtDA]R gR`9_< E&H4L]߽`? =9*IaO`//B&ZJ~G]CUiET<҉^uvmᄄru;jI8.ܛE-mTMr]$2(*צ\ae93CQ1{9 ck6rBw$x|'r^a١S/&xd$ @Q(3:Hj#3?9dek߹_p{g^ Vxnp"BGB;a_LOjhͽ PRw쏅E0؅ rD3js|e.nkطvj;N 6xx1 Mާ$khrO'uQ7ӽ7yl:PϺ5 {K s1Ja,ȍjcC{@kึ_hp_ ݹ54v#]cw$veQԞu] .xۿ=L(8/ `90m- ?AIƙOt񆳡@ʽE=n 5khrZ{0gs jNH&ڧM\(}Ə C :Ʉo"54kh=c\,q{l^E/ kho)6a]>(LsB^3$.qm^yP)􁆆5v `#Erޯg$SC,jƺw[Ө" m8ڻY{kh]c&v% _s<}r3l,y4S͟D"lzݭ5aѫ4殱˂4u5/?x<϶#!R$ EG#s Y _ΓP]cW)ЊOc=1dZd 53 V]<!/g~,0L2ՔyFC.FRk=Ayq6nVrgzqNy>6NxkfczM ^CƮ rwE0 Z==[rcQf9  ,'4QFLCCƨh s7 \wV{q^<`LG~5pͪiq7ihr:gYp@E;¥X4ԘOh} rBCR⬵Օ3
"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("