pax_global_header00006660000000000000000000000064121007420570014510gustar00rootroot0000000000000052 comment=d30a30fe9c58593da8a0cb04ef3778f5799beb32 radium_compressor-0.5.1/000077500000000000000000000000001210074205700152505ustar00rootroot00000000000000radium_compressor-0.5.1/COPYING000066400000000000000000000465101210074205700163110ustar00rootroot00000000000000This software is distributed under GNU Public License (version 2 or later) except jack_capture_gui2 which is distributed under the BSD License. ----------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, 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. 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead of this License. ----------------------------------------------------------- Copyright (c) 2008, Herman Meyer 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 Herman Meyer's organisation 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 REGENTS 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 REGENTS 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. ----------------------------------------------------------- radium_compressor-0.5.1/Changelog000066400000000000000000000003601210074205700170610ustar00rootroot00000000000000 0.5.0 -> 0.5.1: * Dont call init twice, and use correct samplerate 0.0.1 -> 0.5.0 * Don't autoconnect jack ports by default * Option to set jack client name * Faster graphics * Graphics use less CPU * Support for ratios between 0 and 1 radium_compressor-0.5.1/Makefile000066400000000000000000000071041210074205700167120ustar00rootroot00000000000000PREFIX ?= /usr/local bindir ?= $(PREFIX)/bin libdir ?= $(PREFIX)/lib # These two commands are used by me, since most of the source files are stored in the Radium tree. # You would normally just run "make" to compile the program. # # make copy_files && make all && ./radium_compressor # make copy_files && rm -f benchmark && make benchmark && ./benchmark && ./benchmark && ./benchmark CPP = g++ -DDEBUG -O3 -Wall -msse -mfpmath=sse -DUSE_QT_REQTYPE -DUSE_QT4 -g -I. -ffast-math -IQt #FAUST = /home/kjetil/faudiostream/compiler/faust -vec FAUST = faust -vec # only used for copy files RADIUM_PATH = /home/kjetil/radium-qt4 all: audio/system_compressor.cpp cd Qt && ./create_source_from_ui.sh `../find_moc_and_uic_paths.sh uic` `../find_moc_and_uic_paths.sh moc` compressor_widget $(CPP) Qt/Qt_SliderPainter.cpp `pkg-config --cflags Qt3Support` -c $(CPP) main.cpp Qt_SliderPainter.o -Iaudio/faudiostream/architecture/ `pkg-config --libs --cflags Qt3Support` -ljack -o radium_compressor install: install -d $(DESTDIR)$(bindir) cp radium_compressor $(DESTDIR)$(bindir)/ uninstall: rm -f $(DESTDIR)$(bindir)/radium_compressor copy_files: cp $(RADIUM_PATH)/Qt/qt4_compressor_widget.ui Qt/ cp $(RADIUM_PATH)/Qt/Qt_compressor_widget_callbacks.h Qt/ cp $(RADIUM_PATH)/Qt/Qt_MyQCheckBox.h Qt/ cp $(RADIUM_PATH)/Qt/Qt_MyQButton.h Qt/ cp $(RADIUM_PATH)/Qt/Qt_MyQSlider.* Qt/ cp $(RADIUM_PATH)/Qt/Qt_SliderPainter* Qt/ cp $(RADIUM_PATH)/Qt/create_source_from_ui.sh Qt/ cp $(RADIUM_PATH)/Qt/EditorWidget.h Qt/ cp $(RADIUM_PATH)/Qt/OS_Visual.h Qt/ cp $(RADIUM_PATH)/Qt/Qt_ReqType.h Qt/ cp $(RADIUM_PATH)/Qt/Qt_instruments_proc.h Qt/ cp $(RADIUM_PATH)/audio/system_compressor.dsp audio/ cp $(RADIUM_PATH)/audio/typepunning.h audio/ cp $(RADIUM_PATH)/audio/undo_audio_effect_proc.h audio/ cp $(RADIUM_PATH)/audio/SoundPlugin.h audio/ cp $(RADIUM_PATH)/audio/SoundPlugin_proc.h audio/ cp $(RADIUM_PATH)/audio/Smooth_proc.h audio/ cp $(RADIUM_PATH)/common/nsmtracker.h common/ cp $(RADIUM_PATH)/common/debug_proc.h common/ cp $(RADIUM_PATH)/common/memory_proc.h common/ cp $(RADIUM_PATH)/common/nsmtracker_events.h common/ cp $(RADIUM_PATH)/common/keyboard_sub_ids.h common/ cp $(RADIUM_PATH)/common/OS_error_proc.h common/ cp $(RADIUM_PATH)/common/OS_Semaphores.h common/ cp $(RADIUM_PATH)/common/mouse.h common/ cp $(RADIUM_PATH)/common/windows_proc.h common/ cp $(RADIUM_PATH)/common/visual_proc.h common/ cp $(RADIUM_PATH)/common/OS_visual_input.h common/ cp $(RADIUM_PATH)/common/visual_op_queue_proc.h common/ cp $(RADIUM_PATH)/common/undo_patchvoice_proc.h common/ cp $(RADIUM_PATH)/common/instruments_proc.h common/ cp $(RADIUM_PATH)/common/vector_proc.h common/ cp $(RADIUM_PATH)/common/settings_proc.h common/ cp $(RADIUM_PATH)/common/hashmap_proc.h common/ cp $(RADIUM_PATH)/find_moc_and_uic_paths.sh . cp -a $(RADIUM_PATH)/audio/faudiostream audio/ audio/system_compressor.cpp: audio/system_compressor.dsp $(FAUST) audio/system_compressor.dsp >audio/system_compressor.cpp # Note that 0.9.55 runs the benchmark program a bit faster than 0.9.46. # I guess it's because of more min/max functions in 0.9.55, but it could also # be because of some castings. benchmark: $(FAUST) -a bench.cpp audio/system_compressor.dsp >compressor_benchmark.cpp $(CPP) benchmark.cpp -Iaudio -o benchmark -lpthread # original db2linear/linear2db: 60 MB/s # fast pow2/log: 420 MB/s # faster pow2/log: 530 MB/s # lookup table: 420 MB/s # no db<->linear conversion: 610 MB/s # Relative accuracy of faster pow2 / faster log: 0.0152579 / 0.0130367 # Relative accuracy of fast pow2 / fast log: 1.58868e-05 / 2.09348e-05 radium_compressor-0.5.1/Qt/000077500000000000000000000000001210074205700156345ustar00rootroot00000000000000radium_compressor-0.5.1/Qt/EditorWidget.h000077500000000000000000000122231210074205700204020ustar00rootroot00000000000000/* Copyright 2003 Kjetil S. Matheussen 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. */ #ifndef EDITOR_WIDGET_H #define EDITOR_WIDGET_H #ifdef USE_QT3 #include #include #include #include # if USE_GTK_VISUAL # include "qtxembed-1.3-free/src/qtxembed.h" # endif #include #include #include #include #include #endif // USE_QT3 #ifdef USE_QT4 //Added by qt3to4: #include #include #include #include #endif #ifdef USE_QT3 # define Q3PointArray QPointArray # define Q3PopupMenu QPopupMenu #endif #define GFX_DONTSHRINK #include "../common/nsmtracker.h" #include "../common/windows_proc.h" #include "../common/visual_proc.h" #include "../common/visual_op_queue_proc.h" // Don't paint on the frame. //#define XOFFSET 5 //#define YOFFSET 2 class QMainWindow; class QSplitter; #if USE_QIMAGE_BUFFER typedef QImage PaintBuffer; #else typedef QPixmap PaintBuffer; #endif class EditorWidget : public QWidget //QFrame //class EditorWidget : public QtXEmbedContainer //QWidget //QFrame { public: EditorWidget(QWidget *parent=0, const char *name="no name" ); ~EditorWidget(); #if USE_QT_VISUAL && USE_QT4 //const QPaintEngine* paintEngine(); #endif QColor colors[16]; // color array #if USE_QT_VISUAL PaintBuffer *paintbuffer; PaintBuffer *cursorbuffer; #endif //void timerEvent(QTimerEvent *); struct Tracker_Windows *window; // Not sure if this one is used. QMainWindow *main_window; #if USE_QT_VISUAL QPainter *painter; // Set in paintEvent QPainter *paintbuffer_painter; // Set in paintEvent QPainter *cursorbuffer_painter; // Set in paintEvent QFont font; #endif //QFrame *status_frame; QLabel *status_label; QSplitter *xsplitter; QSplitter *ysplitter; int get_editor_width(){ //return this->width()-XOFFSET-2; // Fine tuned. No logical reason behind it. (2 is probably just the frame border width) return this->width(); } int get_editor_height(){ //return this->height()-YOFFSET-2; // Fine tuned. No logical reason behind it. (2 is probably just the frame border width) return this->height(); } Q3PointArray qpa; void updateEditor(); void callCustomEvent(){ customEvent(NULL); } #if USE_QT_VISUAL && USE_QIMAGE_BUFFER void init_buffers(){ const QImage::Format image_format = QImage::Format_RGB32; if(this->paintbuffer==NULL || this->cursorbuffer==NULL || this->paintbuffer->width()width() || this->paintbuffer->height()height()){ delete this->paintbuffer_painter; delete this->cursorbuffer_painter; delete this->paintbuffer; delete this->cursorbuffer; this->paintbuffer = new QImage(this->width(), this->height(), image_format); this->cursorbuffer = new QImage(this->width(), this->height(), image_format); this->paintbuffer_painter = new QPainter(this->paintbuffer); this->cursorbuffer_painter = new QPainter(this->cursorbuffer); this->paintbuffer_painter->setFont(this->font); } #if 1 { this->cursorbuffer_painter->fillRect(0,0,this->width(),this->height(),this->colors[15]); } #if 0 { this->paintbuffer_painter->fillRect(0,0,this->width(),this->height(),this->colors[0]); } #endif #endif } #else void init_buffers(){ #if USE_QT_VISUAL if(this->paintbuffer==NULL || this->cursorbuffer==NULL){ this->paintbuffer=new QPixmap(editor->width(),editor->height()); this->cursorbuffer=new QPixmap(editor->width(),editor->height()); #ifdef USE_QT3 this->paintbuffer->setOptimization(QPixmap::BestOptim); this->cursorbuffer->setOptimization(QPixmap::BestOptim); #endif }else{ this->paintbuffer->resize(this->width(), this->height()); this->cursorbuffer->resize(this->width(), this->height()); } #endif } #endif protected: // bool event(QEvent *); #if 1 //USE_QT_VISUAL void paintEvent( QPaintEvent * ); #endif #if 0 // Using X11filter for keys void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *qkeyevent); #endif #if USE_QT_VISUAL void mousePressEvent( QMouseEvent *); void mouseReleaseEvent( QMouseEvent *); void mouseMoveEvent( QMouseEvent *); #endif void resizeEvent( QResizeEvent *); void closeEvent(QCloseEvent *); void customEvent(QEvent *); }; #endif radium_compressor-0.5.1/Qt/OS_Visual.h000077500000000000000000000016451210074205700176620ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ struct OS_visual{ void *widget; void *main_window; }; #if USE_GTK_REQTYPE # include "../GTK/GTK_ReqType.h" #endif #if USE_QT_REQTYPE # include "Qt_ReqType.h" #endif //# include "../X11/X11_ReqType.h" radium_compressor-0.5.1/Qt/Qt_.h000066400000000000000000000000001210074205700165160ustar00rootroot00000000000000radium_compressor-0.5.1/Qt/Qt_MyQButton.h000066400000000000000000000022431210074205700203540ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef QT_MYQBUTTON_H #define QT_MYQBUTTON_H #include #include "Qt_MyQCheckBox.h" struct MyQButton : public QToolButton{ MyQButton ( QWidget * parent = 0 ) : QToolButton(parent) {} //MyQButton ( const QString & text, QWidget * parent = 0) : QToolButton(text,parent) {} void paintEvent ( QPaintEvent * ev ){ QPainter p(this); CHECKBOX_paint(&p, !isDown(), isEnabled(), width(), height(), text()); } }; #endif // QT_MYQBUTTON_H radium_compressor-0.5.1/Qt/Qt_MyQCheckBox.h000066400000000000000000000102341210074205700205660ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef QT_MYQCHECKBOX_H #define QT_MYQCHECKBOX_H #include #include #include #include "../Qt/EditorWidget.h" #include "../audio/undo_audio_effect_proc.h" #include "../common/undo_patchvoice_proc.h" #ifdef COMPILING_RADIUM extern struct Root *root; #else extern QColor *g_colors; #endif static QColor mix_colors(const QColor &c1, const QColor &c2, float how_much){ float a1 = how_much; float a2 = 1.0f-a1; if(c1.red()==0 && c1.green()==0 && c1.blue()==0){ // some of the black lines doesn't look look very good. int r = 74*a1 + c2.red()*a2; int g = 74*a1 + c2.green()*a2; int b = 74*a1 + c2.blue()*a2; return QColor(r,g,b); }else{ int r = c1.red()*a1 + c2.red()*a2; int g = c1.green()*a1 + c2.green()*a2; int b = c1.blue()*a1 + c2.blue()*a2; return QColor(r,g,b); } } inline static void CHECKBOX_paint(QPainter *painter, bool is_checked, bool is_enabled, int width, int height, QString text){ #ifdef COMPILING_RADIUM QColor *colors = static_cast(root->song->tracker_windows->os_visual.widget)->colors; #else QColor *colors = g_colors; #endif QColor col; // on if(text!=""){ col = colors[13]; col = mix_colors(col.light(70),QColor(98,59,33),0.55);//editor->colors[colnum].light(52); col.setAlpha(76); }else{ col = colors[9].light(52); } if(is_enabled==false) col.setAlpha(col.alpha()/3); //col = QColor(106, 104, 100, 255); //col = QColor(0, 107, 156, 255); if(is_checked==true){ painter->fillRect(1,1,width-2,height-1,col); //painter->setPen(editor->colors[1]); //p.drawRect(0,0,width()-1,height()-1); //p.drawRect(1,1,width()-3,height()-3); }else{ painter->setPen(col); painter->drawRect(1,1,width-3,height-2); painter->drawRect(2,2,width-5,height-4); } if(text!=""){ painter->setPen(colors[15]); painter->drawRect(0,0,width,height); //QRect rect(5,3,width-5,height-3); QRect rect(1,1,width-2,height-1);//5,3,width-5,height-3); QColor black(0,0,0); if(is_checked==true) black.setAlpha(190); else black.setAlpha(120); painter->setPen(black); if(text=="Loop") painter->drawText(rect, Qt::AlignCenter, text + " " + QChar(8634)); else painter->drawText(rect, Qt::AlignCenter, text); } } struct MyQCheckBox : public QCheckBox{ bool _has_mouse; struct Patch *_patch; int _effect_num; bool _undo_patchvoice; void init(){ _has_mouse=false; _patch = NULL; _effect_num = 0; _undo_patchvoice = false; } MyQCheckBox ( QWidget * parent = 0 ) : QCheckBox(parent) {init();} MyQCheckBox ( const QString & text, QWidget * parent = 0) : QCheckBox(text,parent) {init();} void mousePressEvent ( QMouseEvent * event ) { if (event->button() == Qt::LeftButton){ //setSliderDown(true); #ifdef COMPILING_RADIUM if(_undo_patchvoice==true) Undo_PatchVoice_CurrPos(_patch,_effect_num); else if(_patch!=NULL) Undo_AudioEffect_CurrPos(_patch, _effect_num); #endif //handle_mouse_event(event); _has_mouse = true; printf("Got it %p %d\n",_patch,_effect_num); setChecked(!isChecked()); }else QCheckBox::mousePressEvent(event); } void paintEvent ( QPaintEvent * ev ){ QPainter p(this); CHECKBOX_paint(&p, isChecked(), isEnabled(), width(), height(), text()); } }; #endif // QT_MYQCHECKBOX_H radium_compressor-0.5.1/Qt/Qt_MyQSlider.cpp000066400000000000000000000040241210074205700206550ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #include "Qt_MyQSlider.h" #include "Qt_SliderPainter_proc.h" #include "../common/OS_visual_input.h" QVector g_all_myqsliders; static MyQSlider *find_slider(struct Patch *patch, int effect_num){ for(int i=0;i_patch==patch && slider->_effect_num==effect_num) return slider; } fprintf(stderr,"Not found, Qt_MyQSlider.cpp\n"); // could be a checkbox. // abort(); return NULL; } float *OS_SLIDER_obtain_automation_value_pointer(struct Patch *patch,int effect_num){ MyQSlider *slider= find_slider(patch,effect_num); if(slider==NULL) return NULL; else return SLIDERPAINTER_obtain_automation_value_pointer(slider->_painter); } int *OS_SLIDER_obtain_automation_color_pointer(struct Patch *patch,int effect_num){ MyQSlider *slider= find_slider(patch,effect_num); if(slider==NULL) return NULL; else return SLIDERPAINTER_obtain_automation_color_pointer(slider->_painter); } void OS_SLIDER_release_automation_pointers(struct Patch *patch,int effect_num){ //RError("Dont think it is a good idea to call OS_SLIDER_release_automation_pointers"); MyQSlider *slider= find_slider(patch,effect_num); if(slider==NULL) return; else SLIDERPAINTER_release_automation_pointers(slider->_painter); } radium_compressor-0.5.1/Qt/Qt_MyQSlider.h000066400000000000000000000135661210074205700203350ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef QT_MYQSLIDER_H #define QT_MYQSLIDER_H #include #include #include #include #include #include #include #include "EditorWidget.h" #include "../common/instruments_proc.h" #include "../common/vector_proc.h" #include "../common/settings_proc.h" #include "../audio/undo_audio_effect_proc.h" #include "../audio/SoundPlugin.h" #include "../audio/SoundPlugin_proc.h" #include "Qt_instruments_proc.h" #include "Qt_SliderPainter_proc.h" static int scale_int(int x, int x1, int x2, int y1, int y2){ return (int)scale((float)x,(float)x1,(float)x2,(float)y1,(float)y2); } struct MyQSlider; #ifdef COMPILING_RADIUM extern QVector g_all_myqsliders; extern struct Root *root; #else QVector g_all_myqsliders; #endif static int g_minimum_height = 0; struct MyQSlider : public QSlider{ public: struct Patch *_patch; int _effect_num; SliderPainter *_painter; bool _minimum_size_set; void init(){ _has_mouse=false; _patch = NULL; _effect_num = 0; if(g_minimum_height==0){ QFontMetrics fm(QApplication::font()); QRect r =fm.boundingRect("In Out 234234 dB"); g_minimum_height = r.height()+4; printf("Minimum height: %d, family: %s, font pixelsize: %d, font pointsize: %d\n",g_minimum_height,QApplication::font().family().ascii(),QApplication::font().pixelSize(),QApplication::font().pointSize()); } _minimum_size_set = false; // minimumSize must be set later. I think ui generated code overwrites it when set here. _painter = SLIDERPAINTER_create(this); g_all_myqsliders.push_back(this); } MyQSlider ( QWidget * parent = 0 ) : QSlider(parent) {init();} MyQSlider ( Qt::Orientation orientation, QWidget * parent = 0 ) : QSlider(orientation,parent) { init();} ~MyQSlider(){ g_all_myqsliders.remove(g_all_myqsliders.indexOf(this)); SLIDERPAINTER_delete(_painter); } #if 0 void handle_system_delay(bool down){ SoundPlugin *plugin = (SoundPlugin*)_patch->patchdata; const SoundPluginType *type = plugin->type; if(_effect_num==type->num_effects+EFFNUM_DELAY_TIME){ if(down==true) plugin->delay.is_on = false; else plugin->delay.is_on = true; } } #endif bool _has_mouse; void handle_mouse_event ( QMouseEvent * event ){ //printf("Got mouse press event %d / %d\n",(int)event->x(),(int)event->y()); if (orientation() == Qt::Vertical) setValue(scale_int(event->y(),height(),0,minimum(),maximum())); else setValue(scale_int(event->x(),0,width(),minimum(),maximum())); event->accept(); } // mousePressEvent void mousePressEvent ( QMouseEvent * event ) { //printf("Got mouse pres event %d / %d\n",(int)event->x(),(int)event->y()); if (event->button() == Qt::LeftButton){ #ifdef COMPILING_RADIUM if(_patch!=NULL && _patch->instrument==get_audio_instrument()){ Undo_AudioEffect_CurrPos(_patch, _effect_num); //handle_system_delay(true); } #endif handle_mouse_event(event); _has_mouse = true; }else{ #ifdef COMPILING_RADIUM vector_t options = {0}; VECTOR_push_back(&options, "Reset"); //VECTOR_push_back(&options, "Set Value"); int command = GFX_Menu(root->song->tracker_windows, NULL, "", &options); if(command==0 && _patch!=NULL && _patch->instrument==get_audio_instrument()){ SoundPlugin *plugin = (SoundPlugin*)_patch->patchdata; PLUGIN_reset_one_effect(plugin,_effect_num); GFX_update_instrument_widget(_patch); } #endif #if 0 else if(command==1 && _patch!=NULL && _patch->instrument==get_audio_instrument()){ SoundPlugin *plugin = (SoundPlugin*)_patch->patchdata; char *s = GFX_GetString(root->song->tracker_windows,NULL, (char*)"new value"); if(s!=NULL){ float value = OS_get_double_from_string(s); Undo_AudioEffect_CurrPos(_patch, _effect_num); PLUGIN_set_effect_value(plugin,-1,_effect_num,value,PLUGIN_STORED_TYPE,PLUGIN_STORE_VALUE); GFX_update_instrument_widget(_patch); } } #endif event->accept(); } } void mouseMoveEvent ( QMouseEvent * event ) { if (_has_mouse){ handle_mouse_event(event); }else QSlider::mouseMoveEvent(event); } void mouseReleaseEvent ( QMouseEvent * event ) { //printf("Got mouse release event %d / %d\n",(int)event->x(),(int)event->y()); if (_has_mouse){ #if 0 if(_patch!=NULL && _patch->instrument==get_audio_instrument()){ handle_system_delay(false); } #endif handle_mouse_event(event); _has_mouse=false; }else QSlider::mouseReleaseEvent(event); } void paintEvent ( QPaintEvent * ev ){ if(_minimum_size_set==false){ _minimum_size_set=true; setMinimumHeight(g_minimum_height); } #if 0 { QFontMetrics fm(QApplication::font()); //QRect r =fm.boundingRect(SLIDERPAINTER_get_string(_painter)); int width = fm.width(SLIDERPAINTER_get_string(_painter)) + 20; if(minimumWidth() < width) setMinimumWidth(width); } #endif QPainter p(this); SLIDERPAINTER_paint(_painter,&p); } }; #endif // QT_MYQSLIDER_H radium_compressor-0.5.1/Qt/Qt_ReqType.h000066400000000000000000000013561210074205700200470ustar00rootroot00000000000000/* Copyright 2000-2012 Kjetil S. Matheussen 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. */ typedef void* ReqType; radium_compressor-0.5.1/Qt/Qt_SliderPainter.cpp000066400000000000000000000355741210074205700215670ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #include #include #include #include #include #include #include "EditorWidget.h" #include "Qt_SliderPainter_proc.h" const int k_timer_interval = 50; #ifdef COMPILING_RADIUM extern struct Root *root; #else extern QColor *g_colors; #endif static int scale(int x, int x1, int x2, int y1, int y2){ return (int)scale((float)x,(float)x1,(float)x2,(float)y1,(float)y2); } static float gain2db(float val){ if(val<=0.0f) return -100.0f; return 20*log10(val); } static float db2linear(float db){ if(db<-70) return 0.0f; else if(db>40) return 1.0f; else return scale(db,-70.0f,40.0f,0.0f,1.0f); } #if 0 // Function iec_scale picked from meterbridge by Steve Harris. // db is a value between 0 and 1. static float iec_scale(float db) { db = 20.0f * log10f(db); float def = 0.0f; /* Meter deflection %age */ if (db < -70.0f) { def = 0.0f; } else if (db < -60.0f) { def = (db + 70.0f) * 0.25f; } else if (db < -50.0f) { def = (db + 60.0f) * 0.5f + 5.0f; } else if (db < -40.0f) { def = (db + 50.0f) * 0.75f + 7.5; } else if (db < -30.0f) { def = (db + 40.0f) * 1.5f + 15.0f; } else if (db < -20.0f) { def = (db + 30.0f) * 2.0f + 30.0f; } else if (db < 0.0f) { def = (db + 20.0f) * 2.5f + 50.0f; } else { def = 100.0f; } return def * 2.0f / 200.0f; } #endif static QColor mix_colors(const QColor &c1, const QColor &c2, float how_much){ float a1 = how_much; float a2 = 1.0f-a1; if(c1.red()==0 && c1.green()==0 && c1.blue()==0){ // some of the black lines doesn't look look very good. int r = 74*a1 + c2.red()*a2; int g = 74*a1 + c2.green()*a2; int b = 74*a1 + c2.blue()*a2; return QColor(r,g,b); }else{ int r = c1.red()*a1 + c2.red()*a2; int g = c1.green()*a1 + c2.green()*a2; int b = c1.blue()*a1 + c2.blue()*a2; return QColor(r,g,b); } } #define MAX_CHANNELS 8 //namespace{ // stupid c++ with all this useless syntax necessary to make a program appear to work. C++ is only great if you like a challenge and don't want things done. namespace{ struct AutomationOrPeakData{ float *value; int requested_pos; int last_drawn_pos; int *color; int ch; int num_ch; bool is_automation; }; } static int DATA_get_y1(AutomationOrPeakData *data, int height){ return scale(data->ch,0,data->num_ch,1,height-1); } static int DATA_get_y2(AutomationOrPeakData *data, int height){ return scale(data->ch+1,0,data->num_ch,1,height-1); } struct SliderPainter{ struct Timer : public QTimer{ SliderPainter *_painter; void timerEvent(QTimerEvent * e){ //if(_painter->isVisible()) // printf("oh yeah. value: %f. last_drawn: %d, visible? %d\n",*data->value, data->last_drawn_pos,_painter->isVisible()); if(_painter->isVisible()==false) return; for(unsigned int i=0;i<_painter->_data.size();i++){ AutomationOrPeakData *data = _painter->_data.at(i); float gain; if(data->is_automation) gain = *data->value; else{ float db = gain2db(*data->value); if(db>4.0f) _painter->_peak_color = 14; else if(db>0.0f) _painter->_peak_color = 6; else _painter->_peak_color = 13; gain = db2linear(db); } data->requested_pos = scale(gain,0.0f,1.0f, 0.0f,(float)_painter->width()) - 1; if(data->last_drawn_pos != data->requested_pos){ //printf("Painting. Last drawn: %d. requested: %d\n",data->last_drawn_pos,data->requested_pos); int y1 = DATA_get_y1(data,_painter->height()); int y2 = DATA_get_y2(data,_painter->height()); int height = y2-y1; //printf("y1: %d, y2: %d, height: %d. req: %d, last: %d\n",y1,y2,height,data->requested_pos,data->last_drawn_pos); _painter->update(data->requested_pos, y1,4,height+1); _painter->update(data->last_drawn_pos, y1,4,height+1); //printf("%d - %d\n",data->requested_pos,data->last_drawn_pos); } } //e->accept(); } }; // struct Timer std::vector _data; QSlider *_qslider; QGraphicsItem *_graphics_item; // Either widget or _graphics_item must be set. int _x1; int _y1; int _x2; int _y2; float *_peak_values; bool _local_peak_values; float _automation_value; int _automation_color; int _peak_color; bool _alternative_color; int _value; int _num_automations; Timer _timer; QString _display_string; int _num_channels; int value(){ if(_qslider!=NULL) return _qslider->value(); else return _value; } int minimum(){ if(_qslider!=NULL) return _qslider->minimum(); else return 0; } int maximum(){ if(_qslider!=NULL) return _qslider->maximum(); else return 10000; } int orientation(){ if(_qslider!=NULL) return _qslider->orientation(); else return Qt::Horizontal; } bool isEnabled(){ if(_qslider!=NULL) return _qslider->isEnabled(); else return _num_channels>0; } bool isVisible(){ if(_qslider!=NULL) return _qslider->isVisible() && !_qslider->isHidden(); else return _graphics_item->isVisible(); } void update(int x, int y, int width, int height){ //fprintf(stderr,"x: %d. _qslider: %p\n",x,_qslider); if(x<0) x=0; if(y<0) y=0; //fprintf(stderr,"y: %d. _qslider: %p\n",y,_qslider); if(_qslider!=NULL){ return _qslider->update(x,y,width,height); }else return _graphics_item->update(_x1+x, _y1+y, width, height); } int width(){ if(_qslider!=NULL) return _qslider->width(); else return _x2-_x1; } int height(){ if(_qslider!=NULL) return _qslider->height(); else return _y2-_y1; } void init(){ _value = 0; _num_automations = 0; _num_channels = 0; _peak_values = NULL; _local_peak_values=false; _automation_color = 13; _peak_color = 13; _alternative_color = false; } SliderPainter(QSlider *widget) : _qslider(widget) , _graphics_item(NULL) , _automation_value(0.0f) { init(); } SliderPainter(QGraphicsItem *graphics_item) : _qslider(NULL) , _graphics_item(graphics_item) { init(); } ~SliderPainter(){ if(_local_peak_values==true) free(_peak_values); for(unsigned int i=0;i<_data.size();i++) // Don't like iterators. Rather free memory manually than using them. delete _data.at(i); } AutomationOrPeakData *create_automation_data(){ AutomationOrPeakData *data = new AutomationOrPeakData; data->value = &_automation_value; data->requested_pos = 0; data->last_drawn_pos = 0; data->color = &_automation_color; data->ch = 0; data->num_ch = 1; data->is_automation = true; _data.push_back(data); if(_num_automations==0){ _timer._painter = this; _timer.setInterval(k_timer_interval); _timer.start(); } _num_automations++; return data; } float *obtain_automation_value_pointer(){ create_automation_data(); return &_automation_value; } int *obtain_automation_color_pointer(){ return &_automation_color; } float *obtain_peak_value_pointers(int num_channels, float *peak_values){ bool is_replacing = _peak_values!=NULL; if(peak_values==NULL) { _peak_values = (float*)calloc(sizeof(float*),num_channels); _local_peak_values = true; } else { _peak_values = peak_values; } if(is_replacing){ while(_num_automations>0) release_automation_pointers(); // Warning! This works only since _is_replacing==true just for the bottom bar volume slider (which doesn't have automations). _data.clear(); } for(int ch=0;chch = ch; data->num_ch = num_channels; data->is_automation = false; data->value = &_peak_values[ch]; data->color = &_peak_color; } return _peak_values; } void set_peak_value_pointers(int num_channels, float *pointers){ obtain_peak_value_pointers(num_channels, pointers); } void release_automation_pointers(){ _num_automations--; if(_num_automations==0) _timer.stop(); } void paint(QPainter *p){ #ifdef COMPILING_RADIUM QColor *colors = static_cast(root->song->tracker_windows->os_visual.widget)->colors; #else QColor *colors = g_colors; #endif QColor col1; QColor col1b; QColor col2; int col1num = 11; int col2num = 9; //int col1num = qrand() % 15; //int col2num = qrand() % 15; if(false && _qslider!=NULL){ if(isEnabled()){ QColor c1(70,70,33); QColor c2(59,98,33); col1 = mix_colors(c1,colors[col1num].light(90),0.5); col1b = mix_colors(c2,col1,0.3); ///col2 = mix_colors(editor->colors[col2num],editor->colors[col1num],0.8).light(95);//.light(90); col2 = colors[15]; }else{ col1 = colors[col1num].light(105); col1b = col1; col2 = colors[col2num].light(102); } }else{ if(isEnabled()){ QColor c(98,59,33); int colnum = 8; col1 = c.light(90); col1b = colors[13].light(100); //int colnum = 8; //col1 = editor->colors[colnum].light(90); //col1b = editor->colors[13].light(100); col2 = colors[colnum]; }else{ //col1 = editor->colors[col1num].light(105); col1 = mix_colors(colors[col1num], Qt::gray, 0.8f); col1b = mix_colors(colors[col1num].light(110), Qt::gray, 0.8f); col2 = mix_colors(colors[col2num], Qt::gray, 0.8f); //col2 = editor->colors[col2num].light(102); } if(_alternative_color==true){ col1 = QColor(200,200,200); col2 = QColor(100,100,100); } if(_qslider!=NULL){ col1.setAlpha(80); col1b.setAlpha(100); }else{ col1.setAlpha(120); col1b.setAlpha(120); } col2.setAlpha(0); } if(orientation() == Qt::Vertical){ int pos=scale(value(),maximum(),minimum(),0,height()); p->fillRect(0,0,width(),height(),col2); p->fillRect(0,pos,width(),height()-pos,col1); }else{ int pos=scale(value(),minimum(),maximum(),0,width()); { QLinearGradient gradient(0,0,width(),height()*3/4); if(_qslider!=NULL){ //gradient.setColorAt(0,col1.light(90)); //gradient.setColorAt(1,col1.light(110)); gradient.setColorAt(0,col1.light(100)); gradient.setColorAt(1,col1b); }else{ gradient.setColorAt(0,col1.light(150)); gradient.setColorAt(1,col1b); } p->setPen(QPen(QColor(Qt::gray).light(50),1)); p->setBrush(gradient); //p->fillRect(0 ,0, pos ,height(),col1); p->drawRect(0 ,0, pos, height()); p->setBrush(QBrush()); } p->setPen(QPen(Qt::gray,1)); p->fillRect(pos ,0, width()-pos ,height(),col2); } for(unsigned int i=0;i<_data.size();i++){ AutomationOrPeakData *data = _data.at(i); int y1 = DATA_get_y1(data,height()); int y2 = DATA_get_y2(data,height()); int height = y2-y1; p->fillRect(data->requested_pos+1 ,y1+1, 2, height-1, colors[*data->color]); //p->setPen(editor->colors[2].dark(10)); p->setPen(QPen(colors[11].light(120),1)); p->drawRect(data->requested_pos, y1, 3, height); data->last_drawn_pos = data->requested_pos; } if(1){ p->setPen(QPen(colors[11].light(110),1)); p->drawRect(0,0,width(),height()); } QRect rect(5,2,width()-5,height()-2); if(_display_string!=""){ QColor c(colors[1]); if(isEnabled()){ c.setAlpha(160); p->setPen(QPen(c,1));//editor->colors[2].darker(500)); }else{ c.setAlpha(60); p->setPen(QPen(c,1)); } p->drawText(rect, Qt::AlignLeft, _display_string); } } }; //} SliderPainter *SLIDERPAINTER_create(QSlider *qslider){ return new SliderPainter(qslider); } SliderPainter *SLIDERPAINTER_create(QGraphicsItem *graphics_item, int x1, int y1, int x2, int y2){ SliderPainter *painter = new SliderPainter(graphics_item); painter->_x1=x1; painter->_y1=y1; painter->_x2=x2; painter->_y2=y2; return painter; } void SLIDERPAINTER_delete(SliderPainter *painter){ delete painter; } void SLIDERPAINTER_setValue(SliderPainter *painter, int value){ painter->_value = value; } void SLIDERPAINTER_set_num_channels(SliderPainter *painter, int num_channels){ painter->_num_channels = num_channels; } void SLIDERPAINTER_paint(SliderPainter *painter, QPainter *p){ painter->paint(p); } float *SLIDERPAINTER_obtain_peak_value_pointers(SliderPainter *painter, int num_channels){ return painter->obtain_peak_value_pointers(num_channels,NULL); } void SLIDERPAINTER_set_peak_value_pointers(SliderPainter *painter, int num_channels, float *pointers){ painter->set_peak_value_pointers(num_channels, pointers); } float *SLIDERPAINTER_obtain_automation_value_pointer(SliderPainter *painter){ return painter->obtain_automation_value_pointer(); } int *SLIDERPAINTER_obtain_automation_color_pointer(SliderPainter *painter){ return painter->obtain_automation_color_pointer(); } void SLIDERPAINTER_release_automation_pointers(SliderPainter *painter){ painter->release_automation_pointers(); } // Used for chips where the slider controls input volume instead of output volume. void SLIDERPAINTER_set_alternative_color(SliderPainter *painter){ painter->_alternative_color = true; } void SLIDERPAINTER_set_string(SliderPainter *painter,QString string){ painter->_display_string = string; } QString SLIDERPAINTER_get_string(SliderPainter *painter){ return painter->_display_string; } radium_compressor-0.5.1/Qt/Qt_SliderPainter_proc.h000066400000000000000000000034541210074205700222470ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #include struct SliderPainter; SliderPainter *SLIDERPAINTER_create(QSlider *qslider); SliderPainter *SLIDERPAINTER_create(QGraphicsItem *graphics_item, int x1, int y1, int x2, int y2); void SLIDERPAINTER_delete(SliderPainter *painter); void SLIDERPAINTER_paint(SliderPainter *painter, QPainter *p); void SLIDERPAINTER_set_num_channels(SliderPainter *painter, int num_channels); void SLIDERPAINTER_setValue(SliderPainter *painter, int value); // only works with graphics item. float *SLIDERPAINTER_obtain_peak_value_pointers(SliderPainter *painter, int num_channels); void SLIDERPAINTER_set_peak_value_pointers(SliderPainter *painter, int num_channels, float *pointers); float *SLIDERPAINTER_obtain_automation_value_pointer(SliderPainter *painter); int *SLIDERPAINTER_obtain_automation_color_pointer(SliderPainter *painter); void SLIDERPAINTER_release_automation_pointers(SliderPainter *painter); void SLIDERPAINTER_set_alternative_color(SliderPainter *painter); void SLIDERPAINTER_set_string(SliderPainter *painter,QString string); QString SLIDERPAINTER_get_string(SliderPainter *painter); radium_compressor-0.5.1/Qt/Qt_compressor_widget.h000066400000000000000000000117441210074205700222170ustar00rootroot00000000000000/******************************************************************************** ** Form generated from reading UI file 'qt4_compressor_widget.ui' ** ** Created by: Qt User Interface Compiler version 4.8.4 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ #ifndef UI_QT4_COMPRESSOR_WIDGET_H #define UI_QT4_COMPRESSOR_WIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class Ui_Compressor_widget { public: QVBoxLayout *verticalLayout; QHBoxLayout *horizontalLayout; QLabel *radium_url; MyQCheckBox *bypass; MyQButton *load_button; MyQButton *save_button; MyQSlider *attack_slider; MyQSlider *release_slider; void setupUi(QWidget *Compressor_widget) { if (Compressor_widget->objectName().isEmpty()) Compressor_widget->setObjectName(QString::fromUtf8("Compressor_widget")); Compressor_widget->resize(385, 412); verticalLayout = new QVBoxLayout(Compressor_widget); verticalLayout->setSpacing(0); verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); horizontalLayout = new QHBoxLayout(); horizontalLayout->setSpacing(2); horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); horizontalLayout->setSizeConstraint(QLayout::SetFixedSize); horizontalLayout->setContentsMargins(-1, -1, -1, 2); radium_url = new QLabel(Compressor_widget); radium_url->setObjectName(QString::fromUtf8("radium_url")); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(radium_url->sizePolicy().hasHeightForWidth()); radium_url->setSizePolicy(sizePolicy); radium_url->setAlignment(Qt::AlignCenter); radium_url->setOpenExternalLinks(true); horizontalLayout->addWidget(radium_url); bypass = new MyQCheckBox(Compressor_widget); bypass->setObjectName(QString::fromUtf8("bypass")); QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(bypass->sizePolicy().hasHeightForWidth()); bypass->setSizePolicy(sizePolicy1); horizontalLayout->addWidget(bypass); load_button = new MyQButton(Compressor_widget); load_button->setObjectName(QString::fromUtf8("load_button")); sizePolicy.setHeightForWidth(load_button->sizePolicy().hasHeightForWidth()); load_button->setSizePolicy(sizePolicy); horizontalLayout->addWidget(load_button); save_button = new MyQButton(Compressor_widget); save_button->setObjectName(QString::fromUtf8("save_button")); sizePolicy.setHeightForWidth(save_button->sizePolicy().hasHeightForWidth()); save_button->setSizePolicy(sizePolicy); horizontalLayout->addWidget(save_button); verticalLayout->addLayout(horizontalLayout); attack_slider = new MyQSlider(Compressor_widget); attack_slider->setObjectName(QString::fromUtf8("attack_slider")); attack_slider->setMaximum(1000); attack_slider->setOrientation(Qt::Horizontal); verticalLayout->addWidget(attack_slider); release_slider = new MyQSlider(Compressor_widget); release_slider->setObjectName(QString::fromUtf8("release_slider")); release_slider->setMaximum(1000); release_slider->setOrientation(Qt::Horizontal); verticalLayout->addWidget(release_slider); retranslateUi(Compressor_widget); QMetaObject::connectSlotsByName(Compressor_widget); } // setupUi void retranslateUi(QWidget *Compressor_widget) { Compressor_widget->setWindowTitle(QApplication::translate("Compressor_widget", "Radium Compressor", 0, QApplication::UnicodeUTF8)); radium_url->setText(QApplication::translate("Compressor_widget", "Radium", 0, QApplication::UnicodeUTF8)); bypass->setText(QApplication::translate("Compressor_widget", "Bypass", 0, QApplication::UnicodeUTF8)); load_button->setText(QApplication::translate("Compressor_widget", "Load", 0, QApplication::UnicodeUTF8)); save_button->setText(QApplication::translate("Compressor_widget", "Save", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; namespace Ui { class Compressor_widget: public Ui_Compressor_widget {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_QT4_COMPRESSOR_WIDGET_H radium_compressor-0.5.1/Qt/Qt_compressor_widget_callbacks.h000066400000000000000000000716321210074205700242200ustar00rootroot00000000000000/* Copyright 2013 Kjetil S. Matheussen 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. */ #include #include #include #include #include #include #include "Qt_compressor_widget.h" #define GLIDING_PEAK_AREA 0 const int min_db = -40; const int max_db = 40; const int k_timer_interval = 35; const int max_attack_release = 500; const float def_threshold = 0.7f; const float def_ratio = 0.3; const float def_makeupgain = 0.3f; namespace{ enum{ RATIO=0, THRESHOLD, ATTACK, RELEASE, //INPUT_VOLUME, OUTPUT_VOLUME, BYPASS }; struct Comp : public QWidget, public QTimer{ // All values have the value 0 at top, and 1 at bottom, and: // 0 <= val1 <= val2 <= 1 // (sometimes < instead of <=) // slider 1 double in_val1; // 0 double in_val2; // threshold // slider 2 double out_val1; // used to calculate ratio ( ratio = in_val2/(out_val1-in_val2) ) double out_val2; // threshold // slider 3 double vol_val1; // used to calculate volume ( volume = out_val1/vol_val1 ) double vol_val2; // threshold * volume int curr_slider; struct Box{ int x1,y1,x2,y2; int p1,p2; Box(int _x1, int _y1, int _x2, int _y2, float val1,float val2) : x1(_x1) , y1(_y1) , x2(_x2) , y2(_y2) { p1 = scale(val1,0,1,y1,y2); p2 = scale(val2,0,1,y1,y2); } bool inside(int x,int y){ return x>=x1 && xy1 && y=p; } }; struct Peaks{ const static int num_peaks = 30;//24; float peaks[num_peaks]; // in dB int peak_pos; float last_peak; #if GLIDING_PEAK_AREA float min_peak_db, max_peak_db; // in dB #endif int min_peak, max_peak; // in pixels Peaks() : peak_pos(0) , last_peak(0) #if GLIDING_PEAK_AREA , min_peak_db(0), max_peak_db(0) #endif , min_peak(0) , max_peak(0) { for(int i=0;iret) ret=peaks[i]; return ret; } #if GLIDING_PEAK_AREA // Trying gliding area instead of array. IMO it is less clear, and it also uses more CPU because of more gfx updates. void update_peaks(const Box &box, float peak){ const float inc = 0.25; if(peak>max_peak_db) max_peak_db = peak; else max_peak_db = max_peak_db - inc; if(peak max_db) max_peak_db = max_db; if(min_peak_db>max_peak_db) min_peak_db=max_peak_db; //if(box.x1<50) // printf("min_peak_db: %f\n",min_peak_db); min_peak = scale(min_peak_db,min_db,max_db, box.y2, box.y1); max_peak = scale(max_peak_db,min_db,max_db, box.y2, box.y1); } #else void set_min_max(const Box &box){ min_peak = scale(get_min_peak(),min_db,max_db, box.y2, box.y1); max_peak = scale(get_max_peak(),min_db,max_db, box.y2, box.y1); } #endif const int get_y_pixel(const Box &box){ return scale(last_peak,min_db,max_db, box.y2, box.y1); } const QLine get_line_line(const Box &box){ const int peak = get_y_pixel(box); return QLine(box.x1,peak,box.x2,peak); } const QLine get_line_to_next_box(const Box &box1, Peaks *peaks2, const Box &box2){ Peaks *peaks1 = this; int x1=box1.x2; int y1=peaks1->get_y_pixel(box1); int x2=box2.x1; int y2=peaks2->get_y_pixel(box2); if(y1 < box1.y1){ x1=scale(box1.y1, y1,y2, x1,x2); y1=box1.y1 - 10; // FIX. why is - 10 needed? } if(y2 < box2.y1){ x2=scale(box2.y1, y1,y2, x1,x2); y2=box2.y1 - 10; } if(y1 > box1.y2){ x1=scale(box1.y2, y1,y2, x1,x2); y1=box1.y2 + 10; } if(y2 > box2.y2){ x2=scale(box2.y2, y1,y2, x1,x2); y2=box2.y2 + 10; } if(x1box2.x1) x1=10000; if(x2box2.x1) x1=10000; return QLine(x1,y1,x2,y2); } // For lines in boxes (those lines are always horizontal) const QRect get_line_rect(const Box &box){ const int peak = get_y_pixel(box); return QRect(box.x1,peak-2,box.x2-box.x1,5); } // For the lines between boxes. const QPolygon get_line_region(const Box &box1, Peaks *peaks2, const Box &box2){ const QLine line = get_line_to_next_box(box1,peaks2,box2); int x1=line.x1(); int y1=line.y1(); int x2=line.x2(); int y2=line.y2(); if(x1==10000) return QPolygon(); // Line is not painted. #if 0 double degree = 3.14159265359/2.0 - atan( (double)(line2.y1() - line1.y2()) / (double)(line2.x1() - line1.x2())); int h = ceil( (4.0/sin(degree)) / 2.0); //printf("degree: %f, h: %d\n",degree*57.2957795,h); #else // optimized: int h_square = y2 - y1; h_square *= h_square; int w_square = x2 - x1; w_square *= w_square; int h = ceil(4.0/2.0 * sqrt((double)h_square/(double)w_square + 1.0)); // "4.0" is the pen width. #endif QPolygon poly(4); poly.setPoint(0, x1, y1-h); poly.setPoint(1, x1, y1+h); poly.setPoint(2, x2, y2+h); poly.setPoint(3, x2, y2-h); return poly; } const QRect get_area_rect(const Box &box){ return QRect(box.x1,max_peak, box.x2-box.x1, min_peak-max_peak); } void paint_peak_area(QPainter *p, const Box &box){ QColor col(40,90,140); col.setAlpha(80); p->fillRect(get_area_rect(box),col); } void paint_peak_line(QPainter *p, const Box &box){ p->drawLine(get_line_line(box)); } void paint_peak_line_between_boxes(QPainter *p, const Box &box1, Peaks *peaks2, const Box &box2){ const QLine line = get_line_to_next_box(box1, peaks2, box2); if(line.x1()==10000) return; p->drawLine(line); } QRegion add_peaks(const Box &box, float peak){ QRegion reg_before = get_area_rect(box); if(peak<-1000) peak=-1000; if(peak>1000) peak=1000; last_peak = peak; //printf("adding peak %.2f. ",peak); peaks[peak_pos] = peak; peak_pos++; if(peak_pos==num_peaks) peak_pos=0; #if USE_GLIDING_PEAK_AREA update_peaks(box,peak); #else set_min_max(box); #endif QRegion reg_after = get_area_rect(box); return reg_before.xored(reg_after); } }; Peaks peaks_in; Peaks peaks_out; Peaks peaks_vol; float in_peak_value; float out_peak_value; float vol_peak_value; void timerEvent(QTimerEvent * e){ // virtual method from QTimer update_peaks(); } Comp(QWidget *parent) : QWidget(parent) , in_val1(0.0) , in_val2(def_threshold) , out_val1(def_ratio) , out_val2(def_threshold) , vol_val1(def_makeupgain) , vol_val2(def_threshold) , curr_slider(0) { setInterval(k_timer_interval); // QTimer start(); // QTimer set_threshold(def_threshold); set_compressor_parameters(); update_peaks(); } int get_box_width(){ return (width()-1) / 4; } int get_width_between_boxes(){ return get_box_width() / 2; } Box get_slider1_parms(){ return Box( 0,0, get_box_width(), height()-1, in_val1,in_val2); } Box get_slider2_parms(){ return Box( get_box_width() + get_width_between_boxes(), 0, get_box_width() + get_width_between_boxes() + get_box_width(), height()-1, out_val1,out_val2); } Box get_slider3_parms(){ return Box( get_box_width() + get_width_between_boxes() + get_box_width() + get_width_between_boxes(), 0, get_box_width() + get_width_between_boxes() + get_box_width() + get_width_between_boxes() + get_box_width(), height()-1, vol_val1, vol_val2); } double get_threshold(){ return scale(in_val2, in_val1,1, max_db,min_db); } void set_threshold_gui(){ set_threshold(scale(get_compressor_parameter(THRESHOLD),max_db,min_db,in_val1,1)); } double get_ratio(){ double len_in = in_val2-in_val1; double len_out = out_val2-out_val1; if(len_in==0.0 && len_out==0.0) return 1.0; if(len_out==0.0) return 60; double ratio = fabs(len_in-len_out)<0.00001 ? 1.0 : len_in / len_out; if(ratio>60) ratio=60; return ratio; } void set_ratio_gui(){ double ratio = get_compressor_parameter(RATIO); if(ratio<1.0){ set_ratio(scale(ratio,1,0,0,-1)); }else set_ratio(out_val2 - out_val2/ratio); } double get_makeup_gain(){ return scale(vol_val1,0,1,max_db,min_db) - scale(out_val1,0,1,max_db,min_db); } // set_ratio must be called first. void set_makeup_gain_gui(){ float vol = get_compressor_parameter(OUTPUT_VOLUME); float addvol = scale(out_val1,0,1,max_db,min_db) + vol; set_makeupgain(scale(addvol,max_db,min_db,0,1)); } // After loading. void set_gui_parameters(){ set_threshold_gui(); set_ratio_gui(); set_makeup_gain_gui(); } void set_compressor_parameters(){ //double input_volume = 1.0; double threshold = get_threshold(); double ratio = get_ratio(); double output_volume = get_makeup_gain(); set_compressor_parameter(RATIO,ratio); set_compressor_parameter(THRESHOLD, threshold); //set_compressor_parameter(2,attack); //set_compressor_parameter(3,release); //set_compressor_parameter(4,input_volume); set_compressor_parameter(OUTPUT_VOLUME,output_volume); #if 0 printf("%f / %f\n%f / %f\n%f / %f\ninput_volume:\t\t %.2f\n" "threshold:\t\t %f.2f\n" "ratio:\t\t\t %f.2f\n" "output_volume:\t\t %.2f\n\n",in_val2,out_val2,scale(vol_val1,0,1,max_db,min_db),scale(out_val1,0,1,max_db,min_db),vol_val1,out_val1, input_volume, threshold, ratio, output_volume); #endif } enum{ THRESHOLD_SLIDER = 1, RATIO_SLIDER, MAKEUPGAIN_SLIDER }; double p_startpos; int y_startpos; void set_makeupgain(float val){ //double old = vol_val2; vol_val1=val; #if 0 // allow this. if(vol_val1<0.0) vol_val1=0.0; #endif if(vol_val1>0.9999) vol_val1=0.9999; vol_val2 = vol_val1 + (out_val2-out_val1);// scale(out_val2, out_val1, 1.0, vol_val1, 1.0); //printf("setting makeupgain to %f. old/new vol_val2: %f / %f\n",val,vol_val2,old); } void set_ratio(float val){ double vol_diff = vol_val1 - out_val1; out_val1=val; // if(out_val1<0.0) // out_val1=0.0; if(out_val1<0){ double threshold=get_compressor_parameter(THRESHOLD); //get_threshold(); double threshold_scaled=scale(threshold,max_db,min_db,0,1); double ratio = scale(val,0,-1,1,0); //1.0 + val; // val is the out slider value, which goes from 0 to -1 when we are in expanding mode. if(ratio<0.001) ratio=0.001; in_val1 = ((ratio-1)*threshold_scaled) / (ratio*threshold_scaled - ratio - threshold_scaled); // From: i1 = i2*(1-ratio), i2=scale(threshold_scaled,0,1,i1,1), i1=in_va1, i2=in_val2 out_val1=0.0; if(in_val1>0.999) in_val1=0.999; in_val2=scale(threshold,max_db,min_db,in_val1,1); out_val2=in_val2; }else{ in_val1=0.0; } if(out_val1>in_val2-0.0001) out_val1=in_val2-0.0001; set_makeupgain(vol_diff + out_val1); } void set_threshold(float val){ //double bef=in_val2; double old_inval1_scaled = scale(in_val1,0,in_val2,0,1); double old_ratio_factor = out_val1 / (in_val2-in_val1); in_val2 = val; if(in_val2<=0.0) in_val2=0.00001; if(in_val2>0.9999) in_val2=0.9999; out_val2 = in_val2; if(in_val1<=0.0){ set_ratio(old_ratio_factor*in_val2); }else{ in_val1 = scale(old_inval1_scaled,0,1,0,in_val2); set_makeupgain(vol_val1); //printf("b %.2f - %.2f. Bef: %.2f, now: %.2f\n",in_val1,old_inval1_scaled,bef,in_val2); } } void handle_mouse_event ( QMouseEvent * event ){ //printf("Got mouse press event %d / %d\n",(int)event->x(),(int)event->y()); double new_val = p_startpos + scale(event->y()-y_startpos,0,height(),0,1); //printf("p_startpos: %f\n",p_startpos); switch(curr_slider){ case THRESHOLD_SLIDER: set_threshold(new_val); break; case RATIO_SLIDER: set_ratio(new_val); break; case MAKEUPGAIN_SLIDER: set_makeupgain(new_val); break; } set_compressor_parameters(); update(); event->accept(); } void mousePressEvent ( QMouseEvent * event ) { Box in_box = get_slider1_parms(); Box out_box = get_slider2_parms(); Box vol_box = get_slider3_parms(); int x = event->x(); int y = event->y(); if(in_box.inside(x,y)){ curr_slider = THRESHOLD_SLIDER; p_startpos = in_box.p2; }else if(out_box.inside(x,y)){ curr_slider = RATIO_SLIDER; if(in_box.p1>0){ p_startpos = scale(in_box.p1,0,in_box.p2,0,-height()); }else{ p_startpos = out_box.p1; } }else if(vol_box.inside(x,y)){ curr_slider = MAKEUPGAIN_SLIDER; p_startpos = vol_box.p1; } p_startpos = scale(p_startpos,0,height(),0,1); y_startpos = y; } void mouseMoveEvent ( QMouseEvent * event ) { handle_mouse_event(event); } void mouseReleaseEvent ( QMouseEvent * event ) { handle_mouse_event(event); curr_slider = 0; } void paint_slider(QPainter *p, const Box &b){ p->drawRect(b.x1, b.y1, b.x2-b.x1, b.y2-b.y1); p->drawLine(b.x1,b.p1, b.x2,b.p1); p->drawLine(b.x1,b.p2, b.x2,b.p2); } void paint_gradient(QPainter *p, const Box &in, const Box &out, const Box &vol){ QColor col1(30,170,33); QColor col2(159,58,33); col2=col2.light(80); // in slider { QLinearGradient gradient(0,in.p1,0,in.y2); gradient.setColorAt(0,col1); gradient.setColorAt(1,col2); p->fillRect(in.x1 ,in.p1, in.x2-in.x1 ,in.y2-in.p1,QBrush(gradient)); } float in_val = scale(in_val2,in_val1,1.0f,0.0f,1.0f); QColor col = mix_colors(col1,col2,1.0f-in_val); // out slider top { QLinearGradient gradient(0,out.p1,0,out.p2); gradient.setColorAt(0,col1); gradient.setColorAt(1,col); p->fillRect(out.x1, out.p1, out.x2-out.x1, out.p2-out.p1, QBrush(gradient)); } // out slider bot. { QLinearGradient gradient(0,out.p2,0,out.y2); gradient.setColorAt(0,col); gradient.setColorAt(1,col2); p->fillRect(out.x1, out.p2, out.x2-out.x1, out.y2-out.p2, QBrush(gradient)); } // area between in slider and out slider, below threshold { QLinearGradient gradient(0,out.p2, 0,out.y2); gradient.setColorAt(0,col); gradient.setColorAt(1,col2); p->fillRect(in.x2, out.p2, out.x1-in.x2, out.y2-out.p2, QBrush(gradient)); } // area between in slider and out slider, above threshold for(int x=in.x2;xsetPen(QPen(QBrush(gradient),1)); p->drawLine(x,y1,x,y2); } // volume slider { int p1 = vol.p1; int p2 = vol.p2;//scale(out.p2, out.p1, out.y2, vol.p1, vol.y2); int p3 = p2 + (out.y2-out.p2); // top { QLinearGradient gradient(0,p1,0,p2); gradient.setColorAt(0,col1); gradient.setColorAt(1,col); p->fillRect(vol.x1, p1, vol.x2-vol.x1, p2-p1, QBrush(gradient)); } // bot. { QLinearGradient gradient(0,p2,0,p3); gradient.setColorAt(0,col); gradient.setColorAt(1,col2); p->fillRect(vol.x1, p2, vol.x2-vol.x1, p3-p2, QBrush(gradient)); } QColor col3=col2.light(scale(p3,vol.y2,vol.y1,100,40)); // below bot. { QLinearGradient gradient(0,p3,0,vol.y2); gradient.setColorAt(0,col2); gradient.setColorAt(1,col3); p->fillRect(vol.x1,p3, vol.x2-vol.x1,vol.y2-p3, QBrush(gradient)); } // area between out slider and vol slider, above threshold for(int x=out.x2;xsetPen(QPen(QBrush(gradient),1)); p->drawLine(x,y1,x,y2); } // area between out slider and vol slider, below threshold for(int x=out.x2;xsetPen(QPen(QBrush(gradient),1)); p->drawLine(x,y1,x,y2); } } //p->setBrush(QBrush()); p->setPen(QPen()); } // Called regularly void update_peaks(){ Box in_box = get_slider1_parms(); Box out_box = get_slider2_parms(); Box vol_box = get_slider3_parms(); in_peak_value = get_graph_value(0); out_peak_value = in_peak_value + get_graph_value(1); vol_peak_value = out_peak_value + get_makeup_gain(); QRegion reg; // update old line boxes reg = peaks_in.get_line_rect(in_box); reg = reg.united(peaks_out.get_line_rect(out_box)); reg = reg.united(peaks_vol.get_line_rect(vol_box)); // update old lines between boxes reg = reg.united(peaks_in.get_line_region(in_box,&peaks_out,out_box)); reg = reg.united(peaks_out.get_line_region(out_box,&peaks_vol,vol_box)); // Add new peaks, and update areas in boxes (both old and new) reg = reg.united(peaks_in.add_peaks(in_box, scale(scale(in_peak_value,max_db,min_db,in_val1,1),0,1,max_db,min_db))); reg = reg.united(peaks_out.add_peaks(out_box,scale(scale(out_peak_value,max_db,min_db,in_val1,1),0,1,max_db,min_db))); reg = reg.united(peaks_vol.add_peaks(vol_box,scale(scale(vol_peak_value,max_db,min_db,in_val1,1),0,1,max_db,min_db))); // update new lines between boxes reg = reg.united(peaks_in.get_line_region(in_box,&peaks_out,out_box)); reg = reg.united(peaks_out.get_line_region(out_box,&peaks_vol,vol_box)); // update new line boxes reg = reg.united(peaks_in.get_line_rect(in_box)); reg = reg.united(peaks_out.get_line_rect(out_box)); reg = reg.united(peaks_vol.get_line_rect(vol_box)); update(reg); } void paintPeaks(QPainter *p, const Box &in_box, const Box &out_box, const Box &vol_box){ { QColor col(0,90,180); col.setAlpha(80); QPen pen(col); pen.setWidth(4); p->setPen(pen); } // paint lines { // in peaks_in.paint_peak_line(p, in_box); // between in and out peaks_in.paint_peak_line_between_boxes(p, in_box, &peaks_out, out_box); // out peaks_out.paint_peak_line(p, out_box); // between out and vol peaks_out.paint_peak_line_between_boxes(p, out_box, &peaks_vol, vol_box); // vol peaks_vol.paint_peak_line(p, vol_box); } // paint areas { peaks_in.paint_peak_area(p,in_box); peaks_out.paint_peak_area(p,out_box); peaks_vol.paint_peak_area(p,vol_box); } #if 0 // for checking that get_line_region returns correct value. p->setPen(QPen()); p->drawPolygon(peaks_in.get_line_region(in_box,&peaks_out,out_box)); p->drawPolygon(peaks_out.get_line_region(out_box,&peaks_vol,vol_box)); #endif } int get_text_width(QString text){ const QFontMetrics fn = QFontMetrics(QFont()); return fn.width(text); } void paintSliderText(QPainter *p, const Box &box, QString text, double value, QString unit){ QString value_text = QString::number(value,'g',3) + unit; QString one_line = text + " " + value_text; QRect rect(QPoint(box.x1+2,box.y1+2),QPoint(box.x2-4,box.y2-4)); if(get_text_width(text) < rect.width() && get_text_width(value_text) < rect.width()){ // horizontal p->drawText(rect,Qt::AlignTop|Qt::AlignLeft, get_text_width(one_line)save(); QPoint point(box.x1,box.y1); p->translate(box.x1,0);//point);//x, y); p->rotate(90); // or 270 //p->scale((box.x2-box.x1)/12,1.0); //point = p->xFormDev(point); p->drawText(5,-5, one_line); p->restore(); } //p->drawText(box.x1,box.y2-20,QString::number(value)); } void paint_box_fill(QPainter *p, const Box &box){ QColor col(150,190,10); col.setAlpha(10); p->fillRect(box.x1, box.y1, box.x2-box.x1, box.y2-box.y1, col); } void paintEvent ( QPaintEvent * ev ){ QPainter p(this); //printf("Paint\n"); Box in_box = get_slider1_parms(); Box out_box = get_slider2_parms(); Box vol_box = get_slider3_parms(); paint_gradient(&p,in_box,out_box,vol_box); QColor black(0,0,0); black.setAlpha(80); QPen pen(black); //pen.setWidth(2); p.setPen(pen); paint_slider(&p, in_box); paint_slider(&p, out_box); paint_slider(&p, vol_box); // bottom line between sliders { p.drawLine(in_box.x2,in_box.y2,out_box.x1,out_box.y2); p.drawLine(out_box.x2,out_box.y2,vol_box.x1,vol_box.y2); } // threshold line between sliders { // between in and out p.drawLine(in_box.x2,in_box.p2, out_box.x1,out_box.p2); if(out_box.p2!=vol_box.p2) p.setRenderHints(QPainter::Antialiasing,true); // between out and vol p.drawLine(out_box.x2,out_box.p2, vol_box.x1,vol_box.p2); if(out_box.p2!=vol_box.p2) p.setRenderHints(QPainter::Antialiasing,false); } paint_box_fill(&p,in_box); paint_box_fill(&p,out_box); paint_box_fill(&p,vol_box); paintPeaks(&p, in_box, out_box, vol_box); // border line between sliders { black.setAlpha(60); QPen pen(black); p.setPen(pen); // between in and out { if(in_box.p1!=out_box.p1){ p.setRenderHints(QPainter::Antialiasing,true); pen.setWidth(2); } p.drawLine(in_box.x2,in_box.p1, out_box.x1,out_box.p1); if(in_box.p1!=out_box.p1){ p.setRenderHints(QPainter::Antialiasing,false); pen.setWidth(1); } } // between out and vol { if(out_box.p1!=vol_box.p1){ p.setRenderHints(QPainter::Antialiasing,true); pen.setWidth(2); } p.drawLine(out_box.x2,out_box.p1, vol_box.x1,vol_box.p1); if(out_box.p1!=vol_box.p1){ p.setRenderHints(QPainter::Antialiasing,false); pen.setWidth(1); } } } p.setPen(QPen()); paintSliderText(&p,in_box,"Threshold: ",get_threshold(), "dB"); paintSliderText(&p,out_box,"Ratio: ",get_ratio(),":1"); paintSliderText(&p,vol_box,"Makeup Gain: ",get_makeup_gain(),"dB"); } }; static double OS_get_double_from_string(const char *s){ QLocale::setDefault(QLocale::C); QString string(s); return string.toDouble(); } static float read_float(FILE *file){ char temp[512] = {0}; fgets(temp,500,file); return OS_get_double_from_string(temp); } class Compressor_widget : public QWidget, public Ui::Compressor_widget{ Q_OBJECT public: bool initing; Comp *comp; Compressor_widget(QWidget *parent=NULL) : QWidget(parent) { initing = true; setupUi(this); comp = new Comp(this); verticalLayout->insertWidget(1,comp); update_gui(); initing = false; } float get_exp_value(double val, double max_val, double y1, double y2){ return scale_double(exp(val/max_val), exp(0.0),expf(1.0), y1,y2 ); } float get_exp_inverted_value(double y, double max_val, double y1, double y2){ return max_val * log(scale_double(y,y1,y2,exp(0.0),exp(1.0))); } void update_gui(){ comp->set_gui_parameters(); attack_slider->setValue(get_exp_inverted_value(get_compressor_parameter(ATTACK),1000,0,max_attack_release)); release_slider->setValue(get_exp_inverted_value(get_compressor_parameter(RELEASE),1000,0,max_attack_release)); } void load(QString filename){ FILE *file = fopen(filename,"r"); if(file==NULL){ QMessageBox msgBox; msgBox.setText("Could not open file \""+filename+"\"."); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); return; } set_compressor_parameter(RATIO,read_float(file)); // ratio set_compressor_parameter(THRESHOLD,read_float(file)); // threshold set_compressor_parameter(ATTACK,read_float(file)); // attack set_compressor_parameter(RELEASE,read_float(file)); // release //set_compressor_parameter(INPUT_VOLUME,read_float(file)); // input volume (currently not used) read_float(file); // input volume (currently not used) set_compressor_parameter(OUTPUT_VOLUME,read_float(file)); // output volume fclose(file); update_gui(); } public slots: void on_attack_slider_valueChanged(int val){ float attack = get_exp_value(val,1000,0,max_attack_release); set_compressor_parameter(ATTACK,attack); char temp[512]; sprintf(temp,"Attack: %.2fms",attack); SLIDERPAINTER_set_string(attack_slider->_painter, temp); } void on_release_slider_valueChanged(int val){ float release = get_exp_value(val,1000,0,max_attack_release); set_compressor_parameter(RELEASE,release); char temp[512]; sprintf(temp,"Release: %.2fms",release); SLIDERPAINTER_set_string(release_slider->_painter, temp); } void on_bypass_toggled(bool val){ printf("bypass: %d\n",(int)val); set_compressor_parameter(BYPASS,val==true?1.0f:0.0f); } void on_load_button_pressed(void){ printf("load pressed\n"); QString filename = QFileDialog::getOpenFileName(this, "Load Effect configuration", "", "Radium Compressor Configuration (*.rcc)"); if(filename=="") return; load(filename); } void on_save_button_pressed(void){ printf("save pressed\n"); QString filename = QFileDialog::getSaveFileName(this, "Save Effect configuration", "", "Radium Compressor Configuration (*.rcc)"); if(filename=="") return; FILE *file = fopen(filename,"w"); if(file==NULL){ QMessageBox msgBox; msgBox.setText("Could not save file."); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); return; } fprintf(file,"%f\n%f\n%f\n%f\n%f\n%f\n", get_compressor_parameter(RATIO), get_compressor_parameter(THRESHOLD), get_compressor_parameter(ATTACK), get_compressor_parameter(RELEASE), //get_compressor_parameter(INPUT_VOLUME), 0.0f, // input volume (in dB) get_compressor_parameter(OUTPUT_VOLUME) ); fclose(file); } }; } // anon. namespace radium_compressor-0.5.1/Qt/Qt_instruments_proc.h000066400000000000000000000026031210074205700220700ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef QT_INSTRUMENTS_PROC_H #define QT_INSTRUMENTS_PROC_H extern LANGSPEC hash_t *create_instrument_widget_order_state(void); extern LANGSPEC void recreate_instrument_widget_order_from_state(hash_t *state); extern LANGSPEC void GFX_update_instrument_widget(struct Patch *patch); struct SoundPlugin; struct SoundPluginType; extern LANGSPEC SoundPlugin *add_new_audio_instrument_widget(SoundPluginType *plugin_type, int x, int y, bool autoconnect, const char *name); extern LANGSPEC void close_all_instrument_widgets(void); extern LANGSPEC struct Patch *get_current_instruments_gui_patch(void); #ifdef __cplusplus QWidget *createInstrumentsWidget(void); #endif // __cplusplus #endif radium_compressor-0.5.1/Qt/create_source_from_ui.sh000077500000000000000000000025761210074205700225500ustar00rootroot00000000000000#!/bin/bash UIC=$1 MOC=$2 V=$3 # * Creates the .h and .cpp files for the qt designer ui files. # * Replace "protected" with "public" in the header files. (to avoid having to make subclasses) # * Replace QLineEdit with MyQLineEdit so that we can override focusIn UIFILE=qt4_$3.ui #UIFILE=$3.ui $UIC $UIFILE | sed s/protected/public/ | sed s/QLineEdit/FocusSnifferQLineEdit/ | sed s/QListWidget/FocusSnifferQListWidget/ | sed s/QSpinBox/MyQSpinBox/| sed s/QDoubleSpinBox/FocusSnifferQDoubleSpinBox/ | sed s/QTableWidget/FocusSnifferQTableWidget/ | sed s/\ QSlider/\ MyQSlider/ | sed s/\ QCheckBox/\ MyQCheckBox/ | sed s/\ QToolButton/\ MyQButton/ | sed s:\#include\ \://\ \ qlineedit.h: | sed s:\#include\ \://\ \ qlineedit.h: | sed s:\#include\ \://\ \ qspingox.h:| sed s:\#include\ \://\ \ qspingox.h: | sed s:\#include\ \://\ \ qspingox.h: >Qt_$3.h #$UIC $UIFILE | sed s/protected/public/ | sed s/QSpinBox/MyQSpinBox/ | sed s:\#include\ \://\ \ qlineedit.h: | sed s:\#include\ \://\ \ qspingox.h: >Qt_$3.h $MOC Qt_$3_callbacks.h >mQt_$3_callbacks.h #echo "class #$UIC -impl Qt_$3.h $UIFILE | sed s/QLineEdit/FocusSnifferQLineEdit/ | sed s/QSpinBox/MyQSpinBox/ >Qt_$3.cpp #$MOC Qt_$3.h >>Qt_$3.cpp radium_compressor-0.5.1/Qt/mQt__callbacks.h000066400000000000000000000000001210074205700206720ustar00rootroot00000000000000radium_compressor-0.5.1/Qt/mQt_compressor_widget_callbacks.h000066400000000000000000000071641210074205700243740ustar00rootroot00000000000000/**************************************************************************** ** Meta object code from reading C++ file 'Qt_compressor_widget_callbacks.h' ** ** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.4) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include "Qt_compressor_widget_callbacks.h" #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'Qt_compressor_widget_callbacks.h' doesn't include ." #elif Q_MOC_OUTPUT_REVISION != 63 #error "This file was generated using the moc from 4.8.4. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE static const uint qt_meta_data_Compressor_widget[] = { // content: 6, // revision 0, // classname 0, 0, // classinfo 5, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 23, 19, 18, 18, 0x0a, 58, 19, 18, 18, 0x0a, 94, 19, 18, 18, 0x0a, 118, 18, 18, 18, 0x0a, 143, 18, 18, 18, 0x0a, 0 // eod }; static const char qt_meta_stringdata_Compressor_widget[] = { "Compressor_widget\0\0val\0" "on_attack_slider_valueChanged(int)\0" "on_release_slider_valueChanged(int)\0" "on_bypass_toggled(bool)\0" "on_load_button_pressed()\0" "on_save_button_pressed()\0" }; void Compressor_widget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { Q_ASSERT(staticMetaObject.cast(_o)); Compressor_widget *_t = static_cast(_o); switch (_id) { case 0: _t->on_attack_slider_valueChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 1: _t->on_release_slider_valueChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 2: _t->on_bypass_toggled((*reinterpret_cast< bool(*)>(_a[1]))); break; case 3: _t->on_load_button_pressed(); break; case 4: _t->on_save_button_pressed(); break; default: ; } } } const QMetaObjectExtraData Compressor_widget::staticMetaObjectExtraData = { 0, qt_static_metacall }; const QMetaObject Compressor_widget::staticMetaObject = { { &QWidget::staticMetaObject, qt_meta_stringdata_Compressor_widget, qt_meta_data_Compressor_widget, &staticMetaObjectExtraData } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &Compressor_widget::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *Compressor_widget::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *Compressor_widget::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_Compressor_widget)) return static_cast(const_cast< Compressor_widget*>(this)); if (!strcmp(_clname, "Ui::Compressor_widget")) return static_cast< Ui::Compressor_widget*>(const_cast< Compressor_widget*>(this)); return QWidget::qt_metacast(_clname); } int Compressor_widget::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QWidget::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { if (_id < 5) qt_static_metacall(this, _c, _id, _a); _id -= 5; } return _id; } QT_END_MOC_NAMESPACE radium_compressor-0.5.1/Qt/qt4_compressor_widget.ui000066400000000000000000000062151210074205700225260ustar00rootroot00000000000000 Compressor_widget 0 0 385 412 Radium Compressor 0 0 2 QLayout::SetFixedSize 2 0 0 <A href="http://users.notam02.no/~kjetism/radium/">Radium</A> Qt::AlignCenter true 0 0 Bypass 0 0 Load 0 0 Save 1000 Qt::Horizontal 1000 Qt::Horizontal radium_compressor-0.5.1/README000066400000000000000000000026451210074205700161370ustar00rootroot00000000000000 Radium compressor V0.5.1 Released 2013-01-26 HOW TO MAKE IT RUN Either: 1. If you downloaded a tar-ball: " make ./radium_compressor " Or: 2. If you checked out from a git repository: " touch audio/system_compressor.cpp make ./radium_compressor " INTRODUCTION Radium Compressor is the system compressor in Radium, but distributed as a standalone jack application. Radium Compressor uses the stereo compressor found in effect.lib in the Faust distribution. This compressor is written by Julius O. Smith III. The Radium version is an optimized version of this compressor by using fast approximate logarithmic and exponential functions written by Paul Mineiro: http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.htm The GUI shows accurately the sound used for compression, and how much the sound is being compressed. I haven't seen this in any audio compressor GUI before, but it's probably been done before. BUILD DEPENDENCIES FEDORA: qt4-devel jack-audio-connection-kit-devel BUILD DEPENDENCIES UBUNTU: libqt4-dev qt4-dev-tools libjack-jackd2-dev or libjack-jackd1-dev CONTACT k.s.matheussen@notam02.no http://www.notam02.no/radium/ radium_compressor-0.5.1/audio/000077500000000000000000000000001210074205700163515ustar00rootroot00000000000000radium_compressor-0.5.1/audio/Smooth_proc.h000066400000000000000000000071751210074205700210300ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef AUDIO_SMOOTH_PROC_H #define AUDIO_SMOOTH_PROC_H typedef struct{ float* values; volatile float target_value; float start_value; float end_value; int num_values; bool smoothing_is_necessary; } Smooth; typedef struct{ float vals [2][2]; } Panvals; // Copied from https://github.com/kmatheussen/soundengine/blob/master/SoundObject.java (written by me) // static inline Panvals get_pan_vals_vector(float pan, int num_source_channels){ Panvals p; const float sqrt2 = 1.414213562373095; const float pan_scaleval = 2.0f-(2*sqrt2); if(num_source_channels==1){ float x=scale(pan,-1,1,0,1); p.vals[0][0] = ((1.0f-x)*((pan_scaleval*(1.0f-x))+(1.0f-pan_scaleval))); p.vals[0][1] = x * ( (pan_scaleval*x) + (1.0f-pan_scaleval)); }else{ if(pan<=0){ //fprintf(stderr,"p1\n"); p.vals[0][0] = 1.0f; p.vals[0][1] = 0.0f; pan=scale(pan,-1,0,-1,1); float x=scale(pan,-1,1,0,1); //fprintf(stderr,"p2\n"); p.vals[1][0] = ((1.0f-x)*((pan_scaleval*(1.0f-x))+(1.0f-pan_scaleval))); //fprintf(stderr,"p3\n"); p.vals[1][1] = x * ( (pan_scaleval*x) + (1.0f-pan_scaleval)); //fprintf(stderr,"p4\n"); //System.out.println("l/r/pan "+p.vals[1][0]+" "+p.vals[1][1]+" "+pan); }else{ //fprintf(stderr,"p5\n"); pan=scale(pan,0,1,-1,1); float x=scale(pan,-1,1,0,1); //fprintf(stderr,"p6\n"); p.vals[0][0] = ((1.0f-x)*((pan_scaleval*(1.0f-x))+(1.0f-pan_scaleval))); //fprintf(stderr,"p7\n"); p.vals[0][1] = x * ( (pan_scaleval*x) + (1.0f-pan_scaleval)); //fprintf(stderr,"p8\n"); p.vals[1][0] = 0.0f; p.vals[1][1] = 1.0f; //System.out.println("l/r/pan "+p.vals[0][0]+" "+p.vals[0][1]+" "+pan); } } return p; } extern LANGSPEC void SMOOTH_init(Smooth *smooth, float value, int blocksize); extern LANGSPEC void SMOOTH_new_blocksize(Smooth *smooth, int blockframes); extern LANGSPEC void SMOOTH_release(Smooth *smooth); extern LANGSPEC void SMOOTH_set_target_value(Smooth *smooth, float value); extern LANGSPEC float SMOOTH_get_target_value(Smooth *smooth); extern LANGSPEC void SMOOTH_called_per_block(Smooth *smooth); extern LANGSPEC void SMOOTH_apply_volume(Smooth *smooth, float *sound, int num_frames); extern LANGSPEC void SMOOTH_apply_inverted_volume(Smooth *smooth, float *sound, int num_frames); extern LANGSPEC void SMOOTH_copy_sound(Smooth *smooth, float *dst, float *src, int num_frames); extern LANGSPEC void SMOOTH_mix_sounds_raw(float *target, float *source, int num_frames, float start_volume, float end_volume); extern LANGSPEC void SMOOTH_mix_sounds(Smooth *smooth, float *target, float *source, int num_frames); extern LANGSPEC void SMOOTH_mix_sounds_using_inverted_values(Smooth *smooth, float *target, float *source, int num_frames); extern LANGSPEC void SMOOTH_apply_pan(Smooth *smooth, float **sound, int num_channels, int num_frames); #endif // AUDIO_SMOOTH_PROC_H radium_compressor-0.5.1/audio/SoundPlugin.h000066400000000000000000000246721210074205700210040ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef AUDIO_SOUNDPLUGIN_H #define AUDIO_SOUNDPLUGIN_H #include "../common/hashmap_proc.h" #include "Smooth_proc.h" /* get_effect_value / set_effect value is screwed up. All the horrible code and hacks stems from the bad decision of scaling values between 0 and 1. This must be fixed. */ #ifdef __cplusplus extern "C"{ #endif enum{ EFFNUM_INPUT_VOLUME = 0, // This one must be first. EFFNUM_INPUT_VOLUME_ONOFF, EFFNUM_VOLUME, EFFNUM_VOLUME_ONOFF, EFFNUM_OUTPUT_VOLUME, EFFNUM_OUTPUT_VOLUME_ONOFF, EFFNUM_BUS1, EFFNUM_BUS1_ONOFF, EFFNUM_BUS2, EFFNUM_BUS2_ONOFF, EFFNUM_PAN, EFFNUM_PAN_ONOFF, EFFNUM_DRYWET, EFFNUM_EFFECTS_ONOFF, EFFNUM_LOWPASS_FREQ, EFFNUM_LOWPASS_ONOFF, EFFNUM_EQ1_FREQ, EFFNUM_EQ1_GAIN, EFFNUM_EQ1_ONOFF, EFFNUM_EQ2_FREQ, EFFNUM_EQ2_GAIN, EFFNUM_EQ2_ONOFF, EFFNUM_LOWSHELF_FREQ, EFFNUM_LOWSHELF_GAIN, EFFNUM_LOWSHELF_ONOFF, EFFNUM_HIGHSHELF_FREQ, EFFNUM_HIGHSHELF_GAIN, EFFNUM_HIGHSHELF_ONOFF, EFFNUM_DELAY_TIME, EFFNUM_DELAY_ONOFF, NUM_SYSTEM_EFFECTS }; enum{ EFFECT_FORMAT_FLOAT, EFFECT_FORMAT_INT, EFFECT_FORMAT_BOOL, EFFECT_FORMAT_RADIO }; enum ValueFormat{ PLUGIN_FORMAT_NATIVE, PLUGIN_FORMAT_SCALED // scaled between 0 and 1 }; struct SoundPlugin; #if 0 // maybe struct SoundPluginEffect{ float (*get_effect_display_min_value)(const struct SoundPluginType *plugin_type); float (*get_effect_display_max_value)(const struct SoundPluginType *plugin_type); int (*get_effect_format)(const struct SoundPluginType *plugin_type); // Must return one of the EFFECT_* values above. const char *(*get_effect_name)(const struct SoundPluginType *plugin_type); const char *(*get_effect_description)(const struct SoundPluginType *plugin_type); void (*get_display_value_string)(struct SoundPlugin *plugin, char *buffer, int buffersize); // Returns true if you want to call SP_RT_get_effect_value_array to get effect values for this effect. // If not, set_effect_value will be called instead. bool (*effect_is_RT)(const struct SoundPluginType *plugin_type); // This functions is called if SoundPluginType->effect_is_RT(effect_num) returns false void (*set_effect_value)(struct SoundPlugin *plugin, int64_t time, float value); float (*get_effect_value)(struct SoundPlugin *plugin_type); }; #endif // Note that only the fields 'name' and 'is_instrument' will be accessed before the call to 'create_plugin_data'. // The 'is_instrument' field will also be re-read after a call to 'create_plugin_data', in case it had the wrong value before. typedef struct SoundPluginType{ const char *type_name; // I.e. Ladspa / Vst / FluidSynth / etc. Must be unique. const char *name; // i.e. zita-reverb / low-pass filter / etc. Must be unique within plugins with the same type_name. const char *info; // Contains text inside the info box which appear when pressing the button with the name of the plugin. Can be NULL. int num_inputs; int num_outputs; bool is_instrument; // Should be set to true if it is not known until instantiation whether it is an instrument. bool note_handling_is_RT; int num_effects; bool plugin_takes_care_of_savable_values; // For instance, if a VST plugin has it's own editor, we ask the plugin for values instead of using savable_effect_values (which contains the last set value). Then this value is true. int (*get_effect_format)(const struct SoundPluginType *plugin_type, int effect_num); // Must return one of the EFFECT_* values above. int (*get_effect_num)(const struct SoundPluginType *plugin_type, const char *effect_name); // Necessary to implement this if the order of effects may change in the future. const char *(*get_effect_name)(const struct SoundPluginType *plugin_type, int effect_num); // The effect name is used as effect id. Two effects can not have the same name. const char *(*get_effect_description)(const struct SoundPluginType *plugin_type, int effect_num); void (*get_display_value_string)(struct SoundPlugin *plugin, int effect_num, char *buffer, int buffersize); // Returns true if you want to call SP_RT_get_effect_value_array to get effect values for this effect. // If not, set_effect_value will be called instead. bool (*effect_is_RT)(const struct SoundPluginType *plugin_type, int effect_num); void *(*create_plugin_data)(const struct SoundPluginType *plugin_type, struct SoundPlugin *plugin, float sample_rate, int block_size); // Called by Radium during the instantiation of a plugin. The function returns plugin->data. void (*cleanup_plugin_data)(struct SoundPlugin *plugin); // If set, this callback will be called when the 'num_frames' argument to RT_process changes. The audio thread is suspended while this function is called. void (*buffer_size_is_changed)(struct SoundPlugin *plugin, int new_buffer_size); // The sound processing function. Note that the inputs and outputs arrays are likely to point to the same sound buffers. // For instance, if the plugin has one input and one output, inputs[0] and outputs[0] are very likely to be equal. void (*RT_process)(struct SoundPlugin *plugin, int64_t time, int num_frames, float **inputs, float **outputs); // These two functions are not used if SoundPluginType->note_handling_is_RT is false (currently, these two functions are note used at all) void (*RT_play_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume, float pan); void (*RT_stop_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume); // These three functions are not used if SoundPluginType->note_handling_is_RT is true void (*play_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume, float pan); void (*set_note_volume)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume); void (*stop_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume); // Returns the number of channels it can provide peaks for. (calling this function with ch=-1 is considered a dummy operation, except that the return value is correct) int (*get_peaks)(struct SoundPlugin *plugin, int note_num, int ch, float pan, int64_t start_time, int64_t end_time, float *min_value, float *max_value); // This functions is called if SoundPluginType->effect_is_RT(effect_num) returns false void (*set_effect_value)(struct SoundPlugin *plugin, int64_t time, int effect_num, float value, enum ValueFormat value_format); float (*get_effect_value)(struct SoundPlugin *plugin, int effect_num, enum ValueFormat value_format); void (*show_gui)(struct SoundPlugin *plugin); void (*hide_gui)(struct SoundPlugin *plugin); void (*recreate_from_state)(struct SoundPlugin *plugin, hash_t *state); void (*create_state)(struct SoundPlugin *plugin, hash_t *state); // Free use by the plugin void *data; // Used by Radium int instance_num; // Only used to autocreate a name } SoundPluginType; typedef struct SystemFilter{ struct SoundPlugin **plugins; bool is_on; bool was_on; bool was_off; } SystemFilter; enum BusDescendantType{ IS_BUS_DESCENDANT, IS_NOT_A_BUS_DESCENDANT, MAYBE_A_BUS_DESCENDANT, }; typedef struct SoundPlugin{ const SoundPluginType *type; // Data used by the plugin (the value returned by 'create_plugin_data') void *data; // Data below handled by Radium. struct Patch *patch; // The patch points to the plugin and the plugin points to the patch. However, the patch outlives the plugin. Plugin comes and goes, while the patch stays. // Beware that this value might be NULL. float *savable_effect_values; // When dragging a slider, we want to save that value. But we don't want to save the last sent out automation value. (saving to disk, that is) float *initial_effect_values; // Used when resetting. bool editor_is_on; // Data used by SoundProducer Smooth input_volume; bool input_volume_is_on; float volume; bool volume_is_on; Smooth output_volume; bool output_volume_is_on; Smooth bus_volume[2]; bool bus_volume_is_on[2]; Smooth pan; // between 0 and 1 bool pan_is_on; Smooth drywet; bool effects_are_on; SystemFilter lowpass; float lowpass_freq; SystemFilter eq1; float eq1_freq; float eq1_db; SystemFilter eq2; float eq2_freq; float eq2_db; SystemFilter lowshelf; float lowshelf_freq; float lowshelf_db; SystemFilter highshelf; float highshelf_freq; float highshelf_db; SystemFilter delay; float delay_time; float *volume_peak_values; float *volume_peak_values_for_chip; float *output_volume_peak_values; float *input_volume_peak_values; float *input_volume_peak_values_for_chip; float *system_volume_peak_values; // The one in the status bar. (Only if this is the system out plugin.) Set in Jack_plugin.c float *bus_volume_peak_values[2]; enum BusDescendantType bus_descendant_type; // Is 'IS_BUS_DESCENDANT' for all descendants of bus plugins. To prevent accidental feedback loops. } SoundPlugin; // Call this function to get effects from the realtime process. // For instance, if there is a volume starting from 0.5, and ending at 1.0, in the current block of 1024 frames, // then the function will return {0.5, 0.50048828125, 0.5009765625, ..., 1.0} // // This functions can only be called if SoundPluginType->effect_is_RT(effect_num) returns true float *RT_get_effect_value_array(SoundPlugin *plugin, int effect_num); // RT_get_note_volume_array works the same way, but for note volumes. If several similar note_nums (i.e. same note_num value) // are playing at the same time, the returned array will contain the values for one of those notes. It is undefined // which of them. // // The functions can only be called if SoundPluginType->note_handling_is_RT is true float *RT_get_note_volume_array(SoundPlugin *plugin, int note_num); #ifdef __cplusplus } #endif #endif // AUDIO_SOUNDPLUGIN_H radium_compressor-0.5.1/audio/SoundPlugin_proc.h000066400000000000000000000047751210074205700220310ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef AUDIO_SOUNDPLUGIN_PROC_H #define AUDIO_SOUNDPLUGIN_PROC_H enum ValueType{ PLUGIN_STORED_TYPE, PLUGIN_NONSTORED_TYPE }; enum SetValueType{ PLUGIN_STORE_VALUE, PLUGIN_DONT_STORE_VALUE }; enum WhereToGetValue{ VALUE_FROM_PLUGIN, VALUE_FROM_STORAGE }; extern LANGSPEC SoundPlugin *PLUGIN_create_plugin(const SoundPluginType *plugin_type); extern LANGSPEC void PLUGIN_delete_plugin(SoundPlugin *plugin); extern LANGSPEC void PLUGIN_update_smooth_values(SoundPlugin *plugin); extern LANGSPEC int PLUGIN_get_effect_format(const struct SoundPluginType *plugin_type, int effect_num); extern LANGSPEC int PLUGIN_get_effect_num(const struct SoundPluginType *plugin_type, const char *effect_name); extern LANGSPEC const char *PLUGIN_get_effect_name(const struct SoundPluginType *plugin_type, int effect_num); extern LANGSPEC const char *PLUGIN_get_effect_description(const struct SoundPluginType *plugin_type, int effect_num); extern LANGSPEC void PLUGIN_get_display_value_string(struct SoundPlugin *plugin, int effect_num, char *buffer, int buffersize); extern LANGSPEC void PLUGIN_set_effect_value(struct SoundPlugin *plugin, int64_t time, int effect_num, float value, enum ValueType value_type, enum SetValueType set_type); extern LANGSPEC float PLUGIN_get_effect_value(struct SoundPlugin *plugin, int effect_num, enum WhereToGetValue where); extern LANGSPEC hash_t *PLUGIN_get_effects_state(SoundPlugin *plugin); extern LANGSPEC hash_t *PLUGIN_get_state(SoundPlugin *plugin); extern LANGSPEC void PLUGIN_create_effects_from_state(SoundPlugin *plugin, hash_t *effects); extern LANGSPEC SoundPlugin *PLUGIN_create_from_state(hash_t *state); extern LANGSPEC void PLUGIN_reset(SoundPlugin *plugin); extern LANGSPEC void PLUGIN_reset_one_effect(SoundPlugin *plugin, int effect_num); #endif // AUDIO_SOUNDPLUGIN_PROC_H radium_compressor-0.5.1/audio/faudiostream/000077500000000000000000000000001210074205700210345ustar00rootroot00000000000000radium_compressor-0.5.1/audio/faudiostream/architecture/000077500000000000000000000000001210074205700235165ustar00rootroot00000000000000radium_compressor-0.5.1/audio/faudiostream/architecture/faust/000077500000000000000000000000001210074205700246405ustar00rootroot00000000000000radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/000077500000000000000000000000001210074205700257415ustar00rootroot00000000000000radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/alsa-dsp.h000066400000000000000000000527121210074205700276250ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __alsa_dsp__ #define __alsa_dsp__ #include #include #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" /** DEFAULT ALSA PARAMETERS CONTROLLED BY ENVIRONMENT VARIABLES Some default parameters of Faust's ALSA applications are controlled by the following environment variables : FAUST2ALSA_DEVICE = "hw:0" FAUST2ALSA_FREQUENCY= 44100 FAUST2ALSA_BUFFER = 1024 FAUST2ALSA_PERIODS = 2 */ using namespace std; // handle 32/64 bits int size issues #ifdef __x86_64__ #define uint32 unsigned int #define uint64 unsigned long int #define int32 int #define int64 long int #else #define uint32 unsigned int #define uint64 unsigned long long int #define int32 int #define int64 long long int #endif // check 32/64 bits issues are correctly handled #define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); } #define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); } #define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); } /** * Used to set the priority and scheduling of the audi#include #include o thread */ static bool setRealtimePriority () { struct passwd * pw; int err; uid_t uid; struct sched_param param; uid = getuid (); pw = getpwnam ("root"); setuid (pw->pw_uid); param.sched_priority = 50; /* 0 to 99 */ err = sched_setscheduler(0, SCHED_RR, ¶m); setuid (uid); return (err != -1); } /****************************************************************************** ******************************************************************************* AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; /** * A convenient class to pass parameters to AudioInterface */ class AudioParam { public: const char* fCardName; unsigned int fFrequency; unsigned int fBuffering; unsigned int fPeriods; unsigned int fSoftInputs; unsigned int fSoftOutputs; public : AudioParam() : fCardName("hw:0"), fFrequency(44100), fBuffering(512), fPeriods(2), fSoftInputs(2), fSoftOutputs(2) {} AudioParam& cardName(const char* n) { fCardName = n; return *this; } AudioParam& frequency(int f) { fFrequency = f; return *this; } AudioParam& buffering(int fpb) { fBuffering = fpb; return *this; } AudioParam& periods(int p) { fPeriods = p; return *this; } AudioParam& inputs(int n) { fSoftInputs = n; return *this; } AudioParam& outputs(int n) { fSoftOutputs = n; return *this; } }; /** * An ALSA audio interface */ class AudioInterface : public AudioParam { public : snd_pcm_t* fOutputDevice ; snd_pcm_t* fInputDevice ; snd_pcm_hw_params_t* fInputParams; snd_pcm_hw_params_t* fOutputParams; snd_pcm_format_t fSampleFormat; snd_pcm_access_t fSampleAccess; unsigned int fCardInputs; unsigned int fCardOutputs; unsigned int fChanInputs; unsigned int fChanOutputs; // interleaved mode audiocard buffers void* fInputCardBuffer; void* fOutputCardBuffer; // non interleaved mode audiocard buffers void* fInputCardChannels[256]; void* fOutputCardChannels[256]; // non interleaved mod, floating point software buffers float* fInputSoftChannels[256]; float* fOutputSoftChannels[256]; public : const char* cardName() { return fCardName; } int frequency() { return fFrequency; } int buffering() { return fBuffering; } int periods() { return fPeriods; } float** inputSoftChannels() { return fInputSoftChannels; } float** outputSoftChannels() { return fOutputSoftChannels; } AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap) { fInputDevice = 0; fOutputDevice = 0; fInputParams = 0; fOutputParams = 0; } /** * Open the audio interface */ void open() { int err; // allocation d'un stream d'entree et d'un stream de sortie err = snd_pcm_open( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ); check_error(err) err = snd_pcm_open( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ); check_error(err) // recherche des parametres d'entree err = snd_pcm_hw_params_malloc ( &fInputParams ); check_error(err); setAudioParams(fInputDevice, fInputParams); // recherche des parametres de sortie err = snd_pcm_hw_params_malloc ( &fOutputParams ); check_error(err) setAudioParams(fOutputDevice, fOutputParams); // set the number of physical input and output channels close to what we need fCardInputs = fSoftInputs; fCardOutputs = fSoftOutputs; snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs); // enregistrement des parametres d'entree-sortie err = snd_pcm_hw_params (fInputDevice, fInputParams ); check_error (err); err = snd_pcm_hw_params (fOutputDevice, fOutputParams ); check_error (err); //assert(snd_pcm_hw_params_get_period_size(fInputParams,NULL) == snd_pcm_hw_params_get_period_size(fOutputParams,NULL)); // allocation of alsa buffers if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { fInputCardBuffer = calloc(interleavedBufferSize(fInputParams), 1); fOutputCardBuffer = calloc(interleavedBufferSize(fOutputParams), 1); } else { for (unsigned int i = 0; i < fCardInputs; i++) { fInputCardChannels[i] = calloc(noninterleavedBufferSize(fInputParams), 1); } for (unsigned int i = 0; i < fCardOutputs; i++) { fOutputCardChannels[i] = calloc(noninterleavedBufferSize(fOutputParams), 1); } } // allocation of floating point buffers needed by the dsp code fChanInputs = max(fSoftInputs, fCardInputs); assert (fChanInputs < 256); fChanOutputs = max(fSoftOutputs, fCardOutputs); assert (fChanOutputs < 256); for (unsigned int i = 0; i < fChanInputs; i++) { fInputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); for (unsigned int j = 0; j < fBuffering; j++) { fInputSoftChannels[i][j] = 0.0; } } for (unsigned int i = 0; i < fChanOutputs; i++) { fOutputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); for (unsigned int j = 0; j < fBuffering; j++) { fOutputSoftChannels[i][j] = 0.0; } } } void setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params) { int err; // set params record with initial values err = snd_pcm_hw_params_any ( stream, params ); check_error_msg(err, "unable to init parameters") // set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ); if (err) { err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ); check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved"); } snd_pcm_hw_params_get_access(params, &fSampleAccess); // search for 32-bits or 16-bits format err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32); if (err) { err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16); check_error_msg(err, "unable to set format to either 32-bits or 16-bits"); } snd_pcm_hw_params_get_format(params, &fSampleFormat); // set sample frequency snd_pcm_hw_params_set_rate_near (stream, params, &fFrequency, 0); // set period and period size (buffering) err = snd_pcm_hw_params_set_period_size (stream, params, fBuffering, 0); check_error_msg(err, "period size not available"); err = snd_pcm_hw_params_set_periods (stream, params, fPeriods, 0); check_error_msg(err, "number of periods not available"); } ssize_t interleavedBufferSize (snd_pcm_hw_params_t* params) { _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); unsigned int channels; snd_pcm_hw_params_get_channels(params, &channels); ssize_t bsize = snd_pcm_format_size (format, psize * channels); return bsize; } ssize_t noninterleavedBufferSize (snd_pcm_hw_params_t* params) { _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); ssize_t bsize = snd_pcm_format_size (format, psize); return bsize; } void close() {} /** * Read audio samples from the audio card. Convert samples to floats and take * care of interleaved buffers */ void read() { if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering); if (count<0) { display_error_msg(count, "reading samples"); int err = snd_pcm_prepare(fInputDevice); check_error_msg(err, "preparing input stream"); } if (fSampleFormat == SND_PCM_FORMAT_S16) { short* buffer16b = (short*) fInputCardBuffer; for (unsigned int s = 0; s < fBuffering; s++) { for (unsigned int c = 0; c < fCardInputs; c++) { fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX)); } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { int32* buffer32b = (int32*) fInputCardBuffer; for (unsigned int s = 0; s < fBuffering; s++) { for (unsigned int c = 0; c < fCardInputs; c++) { fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(INT_MAX)); } } } else { printf("unrecognized input sample format : %u\n", fSampleFormat); exit(1); } } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering); if (count<0) { display_error_msg(count, "reading samples"); int err = snd_pcm_prepare(fInputDevice); check_error_msg(err, "preparing input stream"); } if (fSampleFormat == SND_PCM_FORMAT_S16) { for (unsigned int c = 0; c < fCardInputs; c++) { short* chan16b = (short*) fInputCardChannels[c]; for (unsigned int s = 0; s < fBuffering; s++) { fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX)); } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { for (unsigned int c = 0; c < fCardInputs; c++) { int32* chan32b = (int32*) fInputCardChannels[c]; for (unsigned int s = 0; s < fBuffering; s++) { fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(INT_MAX)); } } } else { printf("unrecognized input sample format : %u\n", fSampleFormat); exit(1); } } else { check_error_msg(-10000, "unknow access mode"); } } /** * write the output soft channels to the audio card. Convert sample * format and interleaves buffers when needed */ void write() { recovery : if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { if (fSampleFormat == SND_PCM_FORMAT_S16) { short* buffer16b = (short*) fOutputCardBuffer; for (unsigned int f = 0; f < fBuffering; f++) { for (unsigned int c = 0; c < fCardOutputs; c++) { float x = fOutputSoftChannels[c][f]; buffer16b[c + f*fCardOutputs] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ; } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { int32* buffer32b = (int32*) fOutputCardBuffer; for (unsigned int f = 0; f < fBuffering; f++) { for (unsigned int c = 0; c < fCardOutputs; c++) { float x = fOutputSoftChannels[c][f]; buffer32b[c + f*fCardOutputs] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ; } } } else { printf("unrecognized output sample format : %u\n", fSampleFormat); exit(1); } int count = snd_pcm_writei(fOutputDevice, fOutputCardBuffer, fBuffering); if (count<0) { display_error_msg(count, "w3"); int err = snd_pcm_prepare(fOutputDevice); check_error_msg(err, "preparing output stream"); goto recovery; } } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { if (fSampleFormat == SND_PCM_FORMAT_S16) { for (unsigned int c = 0; c < fCardOutputs; c++) { short* chan16b = (short*) fOutputCardChannels[c]; for (unsigned int f = 0; f < fBuffering; f++) { float x = fOutputSoftChannels[c][f]; chan16b[f] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ; } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { for (unsigned int c = 0; c < fCardOutputs; c++) { int32* chan32b = (int32*) fOutputCardChannels[c]; for (unsigned int f = 0; f < fBuffering; f++) { float x = fOutputSoftChannels[c][f]; chan32b[f] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ; } } } else { printf("unrecognized output sample format : %u\n", fSampleFormat); exit(1); } int count = snd_pcm_writen(fOutputDevice, fOutputCardChannels, fBuffering); if (count<0) { display_error_msg(count, "w3"); int err = snd_pcm_prepare(fOutputDevice); check_error_msg(err, "preparing output stream"); goto recovery; } } else { check_error_msg(-10000, "unknow access mode"); } } /** * print short information on the audio device */ void shortinfo() { int err; snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); snd_ctl_card_info_alloca (&card_info); err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); printf("%s|%d|%d|%d|%d|%s\n", snd_ctl_card_info_get_driver(card_info), fCardInputs, fCardOutputs, fFrequency, fBuffering, snd_pcm_format_name((_snd_pcm_format)fSampleFormat)); } /** * print more detailled information on the audio device */ void longinfo() { int err; snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; printf("Audio Interface Description :\n"); printf("Sampling Frequency : %d, Sample Format : %s, buffering : %d\n", fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering); printf("Software inputs : %2d, Software outputs : %2d\n", fSoftInputs, fSoftOutputs); printf("Hardware inputs : %2d, Hardware outputs : %2d\n", fCardInputs, fCardOutputs); printf("Channel inputs : %2d, Channel outputs : %2d\n", fChanInputs, fChanOutputs); // affichage des infos de la carte err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); snd_ctl_card_info_alloca (&card_info); err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); printCardInfo(card_info); // affichage des infos liees aux streams d'entree-sortie if (fSoftInputs > 0) printHWParams(fInputParams); if (fSoftOutputs > 0) printHWParams(fOutputParams); } void printCardInfo(snd_ctl_card_info_t* ci) { printf("Card info (address : %p)\n", ci); printf("\tID = %s\n", snd_ctl_card_info_get_id(ci)); printf("\tDriver = %s\n", snd_ctl_card_info_get_driver(ci)); printf("\tName = %s\n", snd_ctl_card_info_get_name(ci)); printf("\tLongName = %s\n", snd_ctl_card_info_get_longname(ci)); printf("\tMixerName = %s\n", snd_ctl_card_info_get_mixername(ci)); printf("\tComponents = %s\n", snd_ctl_card_info_get_components(ci)); printf("--------------\n"); } void printHWParams( snd_pcm_hw_params_t* params ) { printf("HW Params info (address : %p)\n", params); #if 0 printf("\tChannels = %d\n", snd_pcm_hw_params_get_channels(params)); printf("\tFormat = %s\n", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params))); printf("\tAccess = %s\n", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params))); printf("\tRate = %d\n", snd_pcm_hw_params_get_rate(params, NULL)); printf("\tPeriods = %d\n", snd_pcm_hw_params_get_periods(params, NULL)); printf("\tPeriod size = %d\n", (int)snd_pcm_hw_params_get_period_size(params, NULL)); printf("\tPeriod time = %d\n", snd_pcm_hw_params_get_period_time(params, NULL)); printf("\tBuffer size = %d\n", (int)snd_pcm_hw_params_get_buffer_size(params)); printf("\tBuffer time = %d\n", snd_pcm_hw_params_get_buffer_time(params, NULL)); #endif printf("--------------\n"); } }; // lopt : Scan Command Line long int Arguments long lopt(int argc, char *argv[], const char* longname, const char* shortname, long def) { for (int i=2; igetNumInputs()) .outputs(DSP->getNumOutputs())); } virtual ~alsaaudio() { stop(); delete fAudio; } virtual bool init(const char */*name*/, dsp* DSP) { AVOIDDENORMALS; fAudio->open(); DSP->init(fAudio->frequency()); return true; } virtual bool start() { fRunning = true; if (pthread_create( &fAudioThread, 0, __run, this)) fRunning = false; return fRunning; } virtual void stop() { if (fRunning) { fRunning = false; pthread_join (fAudioThread, 0); } } virtual void run() { bool rt = setRealtimePriority(); printf(rt ? "RT : ":"NRT: "); fAudio->shortinfo(); fAudio->write(); fAudio->write(); while(fRunning) { fAudio->read(); fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels()); fAudio->write(); } } }; void* __run (void* ptr) { alsaaudio * alsa = (alsaaudio*)ptr; alsa->run(); return 0; } #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/audio.h000066400000000000000000000011411210074205700272100ustar00rootroot00000000000000 /****************************************************************************** ******************************************************************************* An abstraction layer over audio layer ******************************************************************************* *******************************************************************************/ #ifndef __audio__ #define __audio__ class dsp; class audio { public: audio() {} virtual ~audio() {} virtual bool init(const char* name, dsp*) = 0; virtual bool start() = 0; virtual void stop() = 0; }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/coreaudio-dsp.h000066400000000000000000001335631210074205700306630ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __coreaudio_dsp__ #define __coreaudio_dsp__ #include #include #include #include #include #include #include #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" using namespace std; /****************************************************************************** ******************************************************************************* COREAUDIO INTERFACE ******************************************************************************* *******************************************************************************/ #define OPEN_ERR -1 #define CLOSE_ERR -1 #define NO_ERR 0 #define WAIT_COUNTER 60 typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) class TCoreAudioRenderer { private: int fDevNumInChans; int fDevNumOutChans; float** fInChannel; float** fOutChannel; dsp* fDSP; AudioBufferList* fInputData; AudioDeviceID fDeviceID; AudioUnit fAUHAL; AudioObjectID fPluginID; // Used for aggregate device bool fState; OSStatus GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id); OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); int SetupSampleRateAux(AudioDeviceID inDevice, int samplerate); static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); void compute(int inNumberFrames) { fDSP->compute(inNumberFrames, fInChannel, fOutChannel); } public: TCoreAudioRenderer() :fInputData(0),fDeviceID(0),fAUHAL(0),fPluginID(0),fState(false),fDevNumInChans(0),fDevNumOutChans(0),fDSP(0) {} virtual ~TCoreAudioRenderer() {} long OpenDefault(dsp* dsp, long inChan, long outChan, long bufferSize, long sampleRate); long Close(); long Start(); long Stop(); }; typedef TCoreAudioRenderer * TCoreAudioRendererPtr; static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { cout << "- - - - - - - - - - - - - - - - - - - -" << endl; cout << " Sample Rate: " << inDesc->mSampleRate << endl; cout << " Format ID:%.*s\n" << sizeof(inDesc->mFormatID) << (char*)&inDesc->mFormatID << endl; cout << " Format Flags " << inDesc->mFormatFlags << endl; cout << " Bytes per Packet: " << inDesc->mBytesPerPacket << endl; cout << " Frames per Packet: " << inDesc->mFramesPerPacket << endl; cout << " Bytes per Frame: " << inDesc->mBytesPerFrame << endl; cout << " Channels per Frame: "<< inDesc->mChannelsPerFrame << endl; cout << " Bits per Channel: " << inDesc->mBitsPerChannel << endl; cout << "- - - - - - - - - - - - - - - - - - - -" << endl; } static void printError(OSStatus err) { switch (err) { case kAudioHardwareNoError: printf("error code : kAudioHardwareNoError\n"); break; case kAudioConverterErr_FormatNotSupported: printf("error code : kAudioConverterErr_FormatNotSupported\n"); break; case kAudioConverterErr_OperationNotSupported: printf("error code : kAudioConverterErr_OperationNotSupported\n"); break; case kAudioConverterErr_PropertyNotSupported: printf("error code : kAudioConverterErr_PropertyNotSupported\n"); break; case kAudioConverterErr_InvalidInputSize: printf("error code : kAudioConverterErr_InvalidInputSize\n"); break; case kAudioConverterErr_InvalidOutputSize: printf("error code : kAudioConverterErr_InvalidOutputSize\n"); break; case kAudioConverterErr_UnspecifiedError: printf("error code : kAudioConverterErr_UnspecifiedError\n"); break; case kAudioConverterErr_BadPropertySizeError: printf("error code : kAudioConverterErr_BadPropertySizeError\n"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); break; case kAudioConverterErr_InputSampleRateOutOfRange: printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); break; case kAudioHardwareNotRunningError: printf("error code : kAudioHardwareNotRunningError\n"); break; case kAudioHardwareUnknownPropertyError: printf("error code : kAudioHardwareUnknownPropertyError\n"); break; case kAudioHardwareIllegalOperationError: printf("error code : kAudioHardwareIllegalOperationError\n"); break; case kAudioHardwareBadDeviceError: printf("error code : kAudioHardwareBadDeviceError\n"); break; case kAudioHardwareBadStreamError: printf("error code : kAudioHardwareBadStreamError\n"); break; case kAudioDeviceUnsupportedFormatError: printf("error code : kAudioDeviceUnsupportedFormatError\n"); break; case kAudioDevicePermissionsError: printf("error code : kAudioDevicePermissionsError\n"); break; default: printf("error code : unknown\n"); break; } } OSStatus TCoreAudioRenderer::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32, UInt32 inNumberFrames, AudioBufferList *ioData) { TCoreAudioRendererPtr renderer = (TCoreAudioRendererPtr)inRefCon; AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fInputData); for (int i = 0; i < renderer->fDevNumInChans; i++) { renderer->fInChannel[i] = (float*)renderer->fInputData->mBuffers[i].mData; } for (int i = 0; i < renderer->fDevNumOutChans; i++) { renderer->fOutChannel[i] = (float*)ioData->mBuffers[i].mData; } renderer->compute((int)inNumberFrames); return 0; } static CFStringRef GetDeviceName(AudioDeviceID id) { UInt32 size = sizeof(CFStringRef); CFStringRef UIname; OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); return (err == noErr) ? UIname : NULL; } OSStatus TCoreAudioRenderer::GetDeviceNameFromID(AudioDeviceID id, char* name) { UInt32 size = 256; return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name); } OSStatus TCoreAudioRenderer::GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id) { UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; AudioDeviceID outDefault; OSStatus res; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) return res; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) return res; // Duplex mode if (inChan > 0 && outChan > 0) { // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; } else { printf("GetDefaultDevice : input = %uld and output = %uld are not the same, create aggregate device...\n", inDefault, outDefault); if (CreateAggregateDevice(inDefault, outDefault, samplerate, id) != noErr) return kAudioHardwareBadDeviceError; } } else if (inChan > 0) { *id = inDefault; return noErr; } else if (outChan > 0) { *id = outDefault; return noErr; } else { return kAudioHardwareBadDeviceError; } return noErr; } OSStatus TCoreAudioRenderer::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice) { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector captureDeviceIDArray; if (err != noErr) { printf("Input device does not have subdevices\n"); captureDeviceIDArray.push_back(captureDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); printf("Input device has %d subdevices\n", num_devices); for (int i = 0; i < num_devices; i++) { captureDeviceIDArray.push_back(sub_device[i]); } } err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector playbackDeviceIDArray; if (err != noErr) { printf("Output device does not have subdevices\n"); playbackDeviceIDArray.push_back(playbackDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); printf("Output device has %d subdevices\n", num_devices); for (int i = 0; i < num_devices; i++) { playbackDeviceIDArray.push_back(sub_device[i]); } } return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); } OSStatus TCoreAudioRenderer::SRNotificationCallback(AudioDeviceID inDevice, UInt32 /*inChannel*/, Boolean /*isInput*/, AudioDevicePropertyID inPropertyID, void* inClientData) { TCoreAudioRenderer* driver = (TCoreAudioRenderer*)inClientData; switch (inPropertyID) { case kAudioDevicePropertyNominalSampleRate: { printf("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate\n"); driver->fState = true; // Check new sample rate Float64 sampleRate; UInt32 outSize = sizeof(Float64); OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); } else { printf("SRNotificationCallback : checked sample rate = %f\n", sampleRate); } break; } } return noErr; } int TCoreAudioRenderer::SetupSampleRateAux(AudioDeviceID inDevice, int samplerate) { OSStatus err = noErr; UInt32 outSize; Float64 sampleRate; // Get sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); return -1; } else { printf("Current sample rate = %f\n", sampleRate); } // If needed, set new sample rate if (samplerate != (int)sampleRate) { sampleRate = (Float64)samplerate; // To get SR change notification err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { printf("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate\n"); printError(err); return -1; } err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { printf("Cannot set sample rate = %d\n", samplerate); printError(err); return -1; } // Waiting for SR change notification int count = 0; while (!fState && count++ < WAIT_COUNTER) { usleep(100000); printf("Wait count = %d\n", count); } // Check new sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); } else { printf("Checked sample rate = %f\n", sampleRate); } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; } OSStatus TCoreAudioRenderer::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice) { OSStatus osErr = noErr; UInt32 outSize; Boolean outWritable; bool fClockDriftCompensate = true; // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; UInt32 theQualifierDataSize = sizeof(AudioObjectID); AudioClassID inClass = kAudioSubDeviceClassID; void* theQualifierData = &inClass; UInt32 subDevicesNum = 0; //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- UInt32 keptclockdomain = 0; UInt32 clockdomain = 0; outSize = sizeof(UInt32); bool need_clock_drift_compensation = false; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of input device\n"); } else { // Check clock domain osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; printf("TCoreAudioRenderer::CreateAggregateDevice : input clockdomain = %d\n", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n"); need_clock_drift_compensation = true; } } } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of output device\n"); } else { // Check clock domain osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; printf("TCoreAudioRenderer::CreateAggregateDevice : output clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n"); need_clock_drift_compensation = true; } } } } // If no valid clock domain was found, then assume we have to compensate... if (keptclockdomain == 0) { need_clock_drift_compensation = true; } //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin //--------------------------------------------------------------------------- char device_name[256]; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { GetDeviceNameFromID(captureDeviceID[i], device_name); printf("Separated input = '%s' \n", device_name); } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { GetDeviceNameFromID(playbackDeviceID[i], device_name); printf("Separated output = '%s' \n", device_name); } osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error\n"); printError(osErr); return osErr; } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); pluginAVT.mOutputData = &fPluginID; pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error\n"); printError(osErr); return osErr; } //------------------------------------------------- // Create a CFDictionary for our aggregate device //------------------------------------------------- CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); // add the name of the device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); // add our choice of UID for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); // add a "private aggregate key" to the dictionary int value = 1; CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); SInt32 system; Gestalt(gestaltSystemVersion, &system); printf("TCoreAudioRenderer::CreateAggregateDevice : system version = %x limit = %x\n", system, 0x00001054); // Starting with 10.5.4 systems, the AD can be internal... (better) if (system < 0x00001054) { printf("TCoreAudioRenderer::CreateAggregateDevice : public aggregate device....\n"); } else { printf("TCoreAudioRenderer::CreateAggregateDevice : private aggregate device....\n"); CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); } // Prepare sub-devices for clock drift compensation CFMutableArrayRef subDevicesArrayClock = NULL; /* if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(captureDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(playbackDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } // add sub-device clock array for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } */ //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); vector captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); if (ref == NULL) return -1; captureDeviceUID.push_back(ref); // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); if (ref == NULL) return -1; playbackDeviceUID.push_back(ref); // output sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } //----------------------------------------------------------------------- // Feed the dictionary to the plugin, to create a blank aggregate device //----------------------------------------------------------------------- AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyDataSize error\n"); printError(osErr); goto error; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyData error\n"); printError(osErr); goto error; } // pause for a bit to make sure that everything completed correctly // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //------------------------- // Set the sub-device list //------------------------- pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error\n"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //----------------------- // Set the master device //----------------------- // set the master device manually (this is the device which will act as the master clock for the aggregate device) // pass in the UID of the device you want to use pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for master device error\n"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 if (fClockDriftCompensate) { if (need_clock_drift_compensation) { printf("Clock drift compensation activated...\n"); // Get the property data size osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n"); printError(osErr); } // Calculate the number of object IDs subDevicesNum = outSize / sizeof(AudioObjectID); printf("TCoreAudioRenderer::CreateAggregateDevice clock drift compensation, number of sub-devices = %d\n", subDevicesNum); AudioObjectID subDevices[subDevicesNum]; outSize = sizeof(subDevices); osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n"); printError(osErr); } // Set kAudioSubDevicePropertyDriftCompensation property... for (UInt32 index = 0; index < subDevicesNum; ++index) { UInt32 theDriftCompensationValue = 1; osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error\n"); printError(osErr); } } } else { printf("Clock drift compensation was asked but is not needed (devices use the same clock domain)\n"); } } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //---------- // Clean up //---------- // release the private AD key CFRelease(AggregateDeviceNumberRef); // release the CF objects we have created - we don't need them any more CFRelease(aggDeviceDict); CFRelease(subDevicesArray); if (subDevicesArrayClock) CFRelease(subDevicesArrayClock); // release the device UID for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { CFRelease(captureDeviceUID[i]); } for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { CFRelease(playbackDeviceUID[i]); } printf("New aggregate device %d\n", *outAggregateDevice); return noErr; error: DestroyAggregateDevice(); return -1; } OSStatus TCoreAudioRenderer::DestroyAggregateDevice() { OSStatus osErr = noErr; AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; if (fPluginID > 0) { osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error\n"); printError(osErr); return osErr; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); if (osErr != noErr) { printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyData error\n"); printError(osErr); return osErr; } } return noErr; } long TCoreAudioRenderer::OpenDefault(dsp* dsp, long inChan, long outChan, long bufferSize, long samplerate) { OSStatus err = noErr; ComponentResult err1; UInt32 outSize; UInt32 enableIO; Boolean isWritable; AudioStreamBasicDescription srcFormat, dstFormat, sampleRate; long in_nChannels, out_nChannels; fDSP = dsp; fDevNumInChans = inChan; fDevNumOutChans = outChan; fInChannel = new float*[fDevNumInChans]; fOutChannel = new float*[fDevNumOutChans]; printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld samplerate = %ld\n", inChan, outChan, bufferSize, samplerate); SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (osErr != noErr) { printf("TCoreAudioRenderer::Open kAudioHardwarePropertyRunLoop error\n"); printError(osErr); } } if (GetDefaultDevice(inChan, outChan, samplerate,&fDeviceID) != noErr) { printf("Cannot open default device\n"); return OPEN_ERR; } // Setting buffer size outSize = sizeof(UInt32); err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &bufferSize); if (err != noErr) { printf("Cannot set buffer size %ld\n", bufferSize); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyBufferFrameSize, &outSize, &bufferSize); if (err != noErr) { printf("Cannot get buffer size %ld\n", bufferSize); printError(err); return OPEN_ERR; } else { printf("Use fixed buffer size %ld\n", bufferSize); } } // Setting sample rate outSize = sizeof(AudioStreamBasicDescription); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); return OPEN_ERR; } if (samplerate != long(sampleRate.mSampleRate)) { sampleRate.mSampleRate = (Float64)(samplerate); err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate); if (err != noErr) { printf("Cannot set sample rate = %ld\n", samplerate); printError(err); return OPEN_ERR; } } // AUHAL ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; Component HALOutput = FindNextComponent(NULL, &cd); err1 = OpenAComponent(HALOutput, &fAUHAL); if (err1 != noErr) { printf("Error calling OpenAComponent\n"); printError(err1); goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { printf("Cannot initialize AUHAL unit\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n"); printError(err1); } in_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0; printf("in_nChannels = %ld\n", in_nChannels); err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n"); printError(err1); } out_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0; printf("out_nChannels = %ld\n", out_nChannels); /* Just ignore this case : seems to work without any further change... if (outChan > out_nChannels) { printf("This device hasn't required output channels\n"); goto error; } if (inChan > in_nChannels) { printf("This device hasn't required input channels\n"); goto error; } */ if (outChan < out_nChannels) { SInt32 chanArr[out_nChannels]; for (int i = 0; i < out_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < outChan; i++) { chanArr[i] = i; } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n"); printError(err1); } } if (inChan < in_nChannels) { SInt32 chanArr[in_nChannels]; for (int i = 0; i < in_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < inChan; i++) { chanArr[i] = i; } AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n"); printError(err1); } } if (inChan > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&srcFormat); srcFormat.mSampleRate = samplerate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(float); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(float); srcFormat.mChannelsPerFrame = inChan; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (outChan > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&dstFormat); dstFormat.mSampleRate = samplerate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(float); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(float); dstFormat.mChannelsPerFrame = outChan; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (inChan > 0 && outChan == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); printError(err1); goto error; } } fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer)); if (fInputData == 0) { printf("Cannot allocate memory for input buffers\n"); goto error; } fInputData->mNumberBuffers = inChan; // Prepare buffers for (int i = 0; i < inChan; i++) { fInputData->mBuffers[i].mNumberChannels = 1; fInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float)); fInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float); } return NO_ERR; error: AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); return OPEN_ERR; } long TCoreAudioRenderer::Close() { if (!fAUHAL) { return CLOSE_ERR; } for (int i = 0; i < fDevNumInChans; i++) { free(fInputData->mBuffers[i].mData); } free(fInputData); AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); DestroyAggregateDevice(); delete[] fInChannel; delete[] fOutChannel; return NO_ERR; } long TCoreAudioRenderer::Start() { if (!fAUHAL) { return OPEN_ERR; } OSStatus err = AudioOutputUnitStart(fAUHAL); if (err != noErr) { printf("Error while opening device : device open error \n"); return OPEN_ERR; } else { return NO_ERR; } } long TCoreAudioRenderer::Stop() { if (!fAUHAL) { return OPEN_ERR; } OSStatus err = AudioOutputUnitStop(fAUHAL); if (err != noErr) { printf("Error while closing device : device close error \n"); return OPEN_ERR; } else { return NO_ERR; } } /****************************************************************************** ******************************************************************************* CORE AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class coreaudio : public audio { TCoreAudioRenderer audio_device; long fSampleRate, fFramesPerBuf; public: coreaudio(long srate, long fpb) : fSampleRate(srate), fFramesPerBuf(fpb) {} virtual ~coreaudio() {} virtual bool init(const char* /*name*/, dsp* DSP) { DSP->init(fSampleRate); if (audio_device.OpenDefault(DSP, DSP->getNumInputs(), DSP->getNumOutputs(), fFramesPerBuf, fSampleRate) < 0) { printf("Cannot open CoreAudio device\n"); return false; } return true; } virtual bool start() { if (audio_device.Start() < 0) { printf("Cannot start CoreAudio device\n"); return false; } return true; } virtual void stop() { audio_device.Stop(); audio_device.Close(); } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/dsp.h000066400000000000000000000025501210074205700267020ustar00rootroot00000000000000 /****************************************************************************** ******************************************************************************* FAUST DSP ******************************************************************************* *******************************************************************************/ #ifndef __dsp__ #define __dsp__ #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif class UI; //---------------------------------------------------------------- // signal processor definition //---------------------------------------------------------------- class dsp { protected: int fSamplingFreq; public: dsp() {} virtual ~dsp() {} virtual int getNumInputs() = 0; virtual int getNumOutputs() = 0; virtual void buildUserInterface(UI* interface) = 0; virtual void init(int samplingRate) = 0; virtual void instanceInit(int samplingFreq) = 0; virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0; }; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) // flags to avoid costly denormals #ifdef __SSE__ #include #ifdef __SSE2__ #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) #else #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) #endif #else #define AVOIDDENORMALS #endif #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/jack-dsp.h000066400000000000000000000106571210074205700276170ustar00rootroot00000000000000 #ifndef __jack_dsp__ #define __jack_dsp__ #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" static int _srate(jack_nframes_t nframes, void *); static void _jack_shutdown(void *); static int _process (jack_nframes_t nframes, void *client); #ifdef _OPENMP static void* _jackthread(void* arg); #endif /****************************************************************************** ******************************************************************************* JACK AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class jackaudio : public audio { dsp* fDsp; jack_client_t* fClient; int fNumInChans; // number of input channels int fNumOutChans; // number of output channels jack_port_t * fInput_ports[256]; // Jack input ports jack_port_t * fOutput_ports[256]; // Jack output ports float* fInChannel[256]; // tables of noninterleaved input channels for FAUST float* fOutChannel[256]; // tables of noninterleaved output channels for FAUST public: jackaudio() : fClient(0), fNumInChans(0), fNumOutChans(0) {} virtual ~jackaudio() { stop(); } virtual bool init(const char*name, dsp* DSP) { fDsp = DSP; if ((fClient = jack_client_open(name, JackNullOption, NULL)) == 0) { fprintf(stderr, "jack server not running?\n"); return false; } #ifdef _OPENMP jack_set_process_thread(fClient, _jackthread, this); #else jack_set_process_callback(fClient, _process, this); #endif jack_set_sample_rate_callback(fClient, _srate, 0); jack_on_shutdown(fClient, _jack_shutdown, 0); fNumInChans = fDsp->getNumInputs(); fNumOutChans = fDsp->getNumOutputs(); for (int i = 0; i < fNumInChans; i++) { char buf[256]; snprintf(buf, 256, "in_%d", i); fInput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); } for (int i = 0; i < fNumOutChans; i++) { char buf[256]; snprintf(buf, 256, "out_%d", i); fOutput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } fDsp->init(jack_get_sample_rate(fClient)); return true; } virtual bool start() { if (jack_activate(fClient)) { fprintf(stderr, "cannot activate client"); return false; } char** physicalInPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsInput); char** physicalOutPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (physicalOutPorts != NULL) { for (int i = 0; i < fNumInChans && physicalOutPorts[i]; i++) jack_connect(fClient, physicalOutPorts[i], jack_port_name(fInput_ports[i])); } if (physicalInPorts != NULL) { for (int i = 0; i < fNumOutChans && physicalInPorts[i]; i++) jack_connect(fClient, jack_port_name(fOutput_ports[i]), physicalInPorts[i]); } return true; } virtual void stop() { if (fClient) { jack_deactivate(fClient); for (int i = 0; i < fNumInChans; i++) jack_port_unregister(fClient, fInput_ports[i]); for (int i = 0; i < fNumOutChans; i++) jack_port_unregister(fClient, fOutput_ports[i]); jack_client_close(fClient); fClient = 0; } } // jack callbacks int process (jack_nframes_t nframes) { AVOIDDENORMALS; for (int i = 0; i < fNumInChans; i++) fInChannel[i] = (float *)jack_port_get_buffer(fInput_ports[i], nframes); for (int i = 0; i < fNumOutChans; i++) fOutChannel[i] = (float *)jack_port_get_buffer(fOutput_ports[i], nframes); fDsp->compute(nframes, fInChannel, fOutChannel); return 0; } #ifdef _OPENMP void process_thread () { jack_nframes_t nframes; while (1) { nframes = jack_cycle_wait(fClient); process (nframes); jack_cycle_signal(fClient, 0); } } #endif }; //---------------------------------------------------------------------------- // Jack Callbacks //---------------------------------------------------------------------------- static int _srate(jack_nframes_t nframes, void *) { printf("the sample rate is now %u/sec\n", nframes); return 0; } static void _jack_shutdown(void *) { exit(1); } static int _process(jack_nframes_t nframes, void *client) { jackaudio* jackclient = (jackaudio*)client; return jackclient->process (nframes); } #ifdef _OPENMP static void* _jackthread(void* arg) { jackaudio* jackclient = (jackaudio*)arg; jackclient->process_thread(); return 0; } #endif #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/netjack-dsp.h000066400000000000000000000103741210074205700303220ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __netjack_dsp__ #define __netjack_dsp__ #include "faust/audio/audio.h" #include "faust/audio/dsp.h" #include #include class netjackaudio : public audio { dsp* fDsp; jack_net_slave_t* fNet; int fCelt; std::string fMasterIP; int fMasterPort; static void net_shutdown(void *) { printf("Network failure, restart...\n"); } static int net_process(jack_nframes_t buffer_size, int, float** audio_input_buffer, int, void**, int, float** audio_output_buffer, int, void**, void* arg) { AVOIDDENORMALS; netjackaudio* obj = (netjackaudio*)arg; obj->fDsp->compute(buffer_size, audio_input_buffer, audio_output_buffer); return 0; } public: netjackaudio(int celt, const std::string master_ip, int master_port) :fCelt(celt), fMasterIP(master_ip), fMasterPort(master_port) {} bool init(const char* name, dsp* DSP) { fDsp = DSP; jack_slave_t request = { DSP->getNumInputs(), DSP->getNumOutputs(), 0, 0, DEFAULT_MTU, -1, (fCelt > 0) ? JackCeltEncoder: JackFloatEncoder, (fCelt > 0) ? fCelt : 0, 2 }; jack_master_t result; if ((fNet = jack_net_slave_open(fMasterIP.c_str(), fMasterPort, name, &request, &result)) == 0) { printf("jack remote server not running ?\n"); return false; } jack_set_net_slave_process_callback(fNet, net_process, this); jack_set_net_slave_shutdown_callback(fNet, net_shutdown, 0); fDsp->init(result.sample_rate); return true; } bool start() { if (jack_net_slave_activate(fNet)) { printf("cannot activate net"); return false; } return true; } void stop() { jack_net_slave_deactivate(fNet); jack_net_slave_close(fNet); } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/oscdsp.h000066400000000000000000000035451210074205700274140ustar00rootroot00000000000000 #ifndef __osc_dsp__ #define __osc_dsp__ #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" #include "OSCIO.h" /****************************************************************************** ******************************************************************************* OSC AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ #define kMaxBuffer 4096 class oscdsp : public audio, public oscfaust::OSCIO { dsp* fDsp; float ** fInBuffers, **fOutBuffers; public: oscdsp(const char * dst, int argc, char *argv[]) : OSCIO(dst), fDsp(0), fInBuffers(0), fOutBuffers(0) { for (int i = 1; i < argc-1; i++) if (!strcmp(argv[i], "-iodst")) setDest (argv[i+1]); } virtual ~oscdsp() { stop(); } virtual bool init(const char*name, dsp* DSP) { fDsp = DSP; fDsp->init(44100); fInBuffers = new float*[numInputs()]; fOutBuffers = new float*[numOutputs()]; for (int i= 0; i < numInputs(); i++) fInBuffers[i] = new float[kMaxBuffer]; for (int i= 0; i < numOutputs(); i++) fOutBuffers [i] = new float[kMaxBuffer]; return true; } virtual bool start() { return true; } virtual void stop() {} void compute( int nframes ) { fDsp->compute(nframes, fInBuffers, fOutBuffers); for (int i= 0; i < numOutputs(); i++) send( nframes, fOutBuffers [i], i); } void receive( int nvalues, float * val ) { int inChans = numInputs(); if (!inChans) { compute(nvalues); return; } for (int i=0; i < nvalues; i++) { int c = i % inChans; int frame = i / inChans; fInBuffers[c][frame] = val[i]; } compute (nvalues / inChans); } int numOutputs() const { return fDsp ? fDsp->getNumOutputs() : 0; } int numInputs() const { return fDsp ? fDsp->getNumInputs() : 0; } }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/audio/portaudio-dsp.h000066400000000000000000000177131210074205700307150ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __portaudio_dsp__ #define __portaudio_dsp__ #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void * drv); static bool pa_error(int err) { if (err != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return true; } else { return false; } } /****************************************************************************** ******************************************************************************* PORT AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class portaudio : public audio { private: dsp* fDsp; PaStream* fAudioStream; long fSampleRate; long fBufferSize; //---------------------------------------------------------------------------- // number of physical input and output channels of the PA device //---------------------------------------------------------------------------- int fDevNumInChans; int fDevNumOutChans; //---------------------------------------------------------------------------- // tables of noninterleaved input and output channels for FAUST //---------------------------------------------------------------------------- float** fInChannel; float** fOutChannel; //---------------------------------------------------------------------------- // allocated the noninterleaved input and output channels for FAUST //---------------------------------------------------------------------------- void allocChannels(int size, int numInChan, int numOutChan) { fInChannel = new float*[numInChan]; fOutChannel = new float*[numOutChan]; for (int i = 0; i < numInChan; i++) { fInChannel[i] = (float*) calloc (size, sizeof(float)); for (int j = 0; j < size; j++) fInChannel[i][j] = 0.0; } for (int i = 0; i < numOutChan; i++) { fOutChannel[i] = (float*) calloc (size, sizeof(float)); for (int j = 0; j < size; j++) fOutChannel[i][j] = 0.0; } } public: portaudio(long srate, long bsize) : fDsp(0), fAudioStream(0), fSampleRate(srate), fBufferSize(bsize), fDevNumInChans(0), fDevNumOutChans(0) {} virtual ~portaudio() { stop(); delete [] fInChannel; delete [] fOutChannel; } virtual bool init(const char* name, dsp* DSP) { fDsp = DSP; if (pa_error(Pa_Initialize())) { return false; } const PaDeviceInfo* idev = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice()); const PaDeviceInfo* odev = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice()); fDevNumInChans = (fDsp->getNumInputs() > 0) ? idev->maxInputChannels : 0; fDevNumOutChans = (fDsp->getNumOutputs() > 0) ? odev->maxOutputChannels : 0; PaStreamParameters inputParameters; PaStreamParameters outputParameters; inputParameters.device = Pa_GetDefaultInputDevice(); inputParameters.sampleFormat = paFloat32; inputParameters.channelCount = fDevNumInChans; inputParameters.hostApiSpecificStreamInfo = 0; outputParameters.device = Pa_GetDefaultOutputDevice(); outputParameters.sampleFormat = paFloat32; outputParameters.channelCount = fDevNumOutChans; outputParameters.hostApiSpecificStreamInfo = 0; PaError err; if ((err = Pa_IsFormatSupported( ((fDevNumInChans > 0) ? &inputParameters : 0), ((fDevNumOutChans > 0) ? &outputParameters : 0), fSampleRate)) != 0) { printf("stream format is not supported err = %d\n", err); return false; } allocChannels(fBufferSize, max(fDevNumInChans, fDsp->getNumInputs()), max(fDevNumOutChans, fDsp->getNumOutputs())); fDsp->init(fSampleRate); return true; } virtual bool start() { if (pa_error(Pa_OpenDefaultStream(&fAudioStream, fDevNumInChans, fDevNumOutChans, paFloat32, fSampleRate, fBufferSize, audioCallback, this))) { return false; } if (pa_error(Pa_StartStream(fAudioStream)) { return false; } return true; } virtual void stop() { if (fAudioStream) { Pa_StopStream (fAudioStream); Pa_CloseStream(fAudioStream); fAudioStream = 0; } } int processAudio(const float* ibuf, float* obuf, unsigned long frames) { const float* fInputBuffer = ibuf; float* fOutputBuffer = obuf; // split input samples for (unsigned long s = 0; s < frames; s++) { for (int c = 0; c < fDevNumInChans; c++) { fInChannel[c][s] = fInputBuffer[c + s*fDevNumInChans]; } } // process samples fDsp->compute(frames, fInChannel, fOutChannel); // merge output samples for (unsigned long s = 0; s < frames; s++) { for (int c = 0; c < fDevNumOutChans; c++) { fOutputBuffer[c + s*fDevNumOutChans] = fOutChannel[c][s]; } } return 0; } }; //---------------------------------------------------------------------------- // Port Audio Callback //---------------------------------------------------------------------------- static int audioCallback(const void* ibuf, void* obuf, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* drv) { portaudio* pa = (portaudio*) drv; return pa->processAudio((const float*)ibuf, (float*)obuf, frames); } #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/000077500000000000000000000000001210074205700254245ustar00rootroot00000000000000radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/FUI.h000066400000000000000000000075011210074205700262230ustar00rootroot00000000000000#ifndef FAUST_FUI_H #define FAUST_FUI_H #include "faust/gui/UI.h" #include #include #include #include #include #include #include using namespace std; #if 1 /******************************************************************************* * FUI : used to save and recall the state of the user interface * This class provides essentially two new methods saveState() and recallState() * used to save on file and recall from file the state of the user interface. * The file is human readble and editable ******************************************************************************/ class FUI : public UI { stack fGroupStack; vector fNameList; map fName2Zone; protected: // labels are normalized by replacing white spaces by underscores and by // removing parenthesis string normalizeLabel(const char* label) { string s; char c; while ((c=*label++)) { if (isspace(c)) { s += '_'; } //else if ((c == '(') | (c == ')') ) { } else { s += c; } } return s; } // add an element by relating its full name and memory zone virtual void addElement(const char* label, FAUSTFLOAT* zone) { string fullname (fGroupStack.top() + '/' + normalizeLabel(label)); fNameList.push_back(fullname); fName2Zone[fullname] = zone; } // keep track of full group names in a stack virtual void pushGroupLabel(const char* label) { if (fGroupStack.empty()) { fGroupStack.push(normalizeLabel(label)); } else { fGroupStack.push(fGroupStack.top() + '/' + normalizeLabel(label)); } } virtual void popGroupLabel() { fGroupStack.pop(); }; public: FUI() {} virtual ~FUI() {} // -- Save and recall methods // save the zones values and full names virtual void saveState(const char* filename) { ofstream f(filename); for (unsigned int i=0; i> v >> n; if (fName2Zone.count(n)>0) { *(fName2Zone[n]) = v; } else { cerr << "recallState : parameter not found : " << n.c_str() << " with value : " << v << endl; } } f.close(); } // -- widget's layouts (just keep track of group labels) virtual void openTabBox(const char* label) { pushGroupLabel(label); } virtual void openHorizontalBox(const char* label) { pushGroupLabel(label); } virtual void openVerticalBox(const char* label) { pushGroupLabel(label); } virtual void closeBox() { popGroupLabel(); }; // -- active widgets (just add an element) virtual void addButton(const char* label, FAUSTFLOAT* zone) { addElement(label, zone); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { addElement(label, zone); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } // -- passive widgets (are ignored) virtual void addHorizontalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {}; virtual void addVerticalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {}; // -- metadata are not used virtual void declare(FAUSTFLOAT*, const char*, const char*) {} }; #endif #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/GUI.h000066400000000000000000000062261210074205700262270ustar00rootroot00000000000000#ifndef FAUST_GUI_H #define FAUST_GUI_H #include "faust/gui/UI.h" #include #include using namespace std; /******************************************************************************* * GUI : Abstract Graphic User Interface * Provides additional macchanismes to synchronize widgets and zones. Widgets * should both reflect the value of a zone and allow to change this value. ******************************************************************************/ struct uiItem; typedef void (*uiCallback)(FAUSTFLOAT val, void* data); class GUI : public UI { typedef list clist; typedef map zmap; private: static list fGuiList; zmap fZoneMap; bool fStopped; public: GUI() : fStopped(false) { fGuiList.push_back(this); } virtual ~GUI() { // suppression de this dans fGuiList } // -- registerZone(z,c) : zone management void registerZone(FAUSTFLOAT* z, uiItem* c) { if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist(); fZoneMap[z]->push_back(c); } void updateAllZones(); void updateZone(FAUSTFLOAT* z); static void updateAllGuis() { list::iterator g; for (g = fGuiList.begin(); g != fGuiList.end(); g++) { (*g)->updateAllZones(); } } void addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data); virtual void show() {}; virtual void run() {}; void stop() { fStopped = true; } bool stopped() { return fStopped; } virtual void declare(FAUSTFLOAT* , const char* , const char* ) {} }; /** * User Interface Item: abstract definition */ class uiItem { protected : GUI* fGUI; FAUSTFLOAT* fZone; FAUSTFLOAT fCache; uiItem (GUI* ui, FAUSTFLOAT* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321) { ui->registerZone(zone, this); } public : virtual ~uiItem() {} void modifyZone(FAUSTFLOAT v) { fCache = v; if (*fZone != v) { *fZone = v; fGUI->updateZone(fZone); } } FAUSTFLOAT cache() { return fCache; } virtual void reflectZone() = 0; }; /** * Callback Item */ struct uiCallbackItem : public uiItem { uiCallback fCallback; void* fData; uiCallbackItem(GUI* ui, FAUSTFLOAT* zone, uiCallback foo, void* data) : uiItem(ui, zone), fCallback(foo), fData(data) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fCallback(v, fData); } }; // en cours d'installation de call back. a finir!!!!! /** * Update all user items reflecting zone z */ inline void GUI::updateZone(FAUSTFLOAT* z) { FAUSTFLOAT v = *z; clist* l = fZoneMap[z]; for (clist::iterator c = l->begin(); c != l->end(); c++) { if ((*c)->cache() != v) (*c)->reflectZone(); } } /** * Update all user items not up to date */ inline void GUI::updateAllZones() { for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) { FAUSTFLOAT* z = m->first; clist* l = m->second; FAUSTFLOAT v = *z; for (clist::iterator c = l->begin(); c != l->end(); c++) { if ((*c)->cache() != v) (*c)->reflectZone(); } } } inline void GUI::addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data) { new uiCallbackItem(this, zone, foo, data); }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/OSCUI.h000066400000000000000000000104511210074205700264600ustar00rootroot00000000000000/* Copyright (C) 2011 Grame - Lyon All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted. */ #include "faust/gui/OSCControler.h" #include "faust/gui/GUI.h" #include /****************************************************************************** ******************************************************************************* OSC (Open Sound Control) USER INTERFACE ******************************************************************************* *******************************************************************************/ /* Note about the OSC addresses and the Faust UI names: ---------------------------------------------------- There are potential conflicts between the Faust UI objects naming scheme and the OSC address space. An OSC symbolic names is an ASCII string consisting of printable characters other than the following: space # number sign * asterisk , comma / forward ? question mark [ open bracket ] close bracket { open curly brace } close curly brace a simple solution to address the problem consists in replacing space or tabulation with '_' (underscore) all the other osc excluded characters with '-' (hyphen) This solution is implemented in the proposed OSC UI; */ using namespace std; //class oscfaust::OSCIO; class OSCUI : public GUI { oscfaust::OSCControler* fCtrl; vector fAlias; const char* tr(const char* label) const; // add all accumulated alias void addalias(FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max) { for (unsigned int i=0; iaddfullpathnode(fAlias[i], zone, (FAUSTFLOAT)0, (FAUSTFLOAT)1, init, min, max); } fAlias.clear(); } public: OSCUI(char* /*applicationname*/, int argc, char *argv[], oscfaust::OSCIO* io=0) : GUI() { fCtrl = new oscfaust::OSCControler(argc, argv, io); // fCtrl->opengroup(applicationname); } virtual ~OSCUI() { delete fCtrl; } // -- widget's layouts virtual void openTabBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void openHorizontalBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void openVerticalBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void closeBox() { fCtrl->closegroup(); } // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) { addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } // -- passive widgets virtual void addHorizontalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {} virtual void addVerticalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {} // -- metadata declarations virtual void declare(FAUSTFLOAT* , const char* key , const char* alias) { if (strcasecmp(key,"OSC")==0) fAlias.push_back(alias); } virtual void show() {} void run() { fCtrl->run(); } const char* getRootName() { return fCtrl->getRootName(); } }; const char* OSCUI::tr(const char* label) const { static char buffer[1024]; char * ptr = buffer; int n=1; while (*label && (n++ < 1024)) { switch (*label) { case ' ': case ' ': *ptr++ = '_'; break; case '#': case '*': case ',': case '/': case '?': case '[': case ']': case '{': case '}': *ptr++ = '_'; break; default: *ptr++ = *label; } label++; } *ptr = 0; return buffer; } radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/UI.h000066400000000000000000000031441210074205700261140ustar00rootroot00000000000000#ifndef FAUST_UI_H #define FAUST_UI_H #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif /******************************************************************************* * UI : Faust User Interface * This abstract class contains only the method that the faust compiler can * generate to describe a DSP interface. ******************************************************************************/ class UI { public: UI() {} virtual ~UI() {} // -- widget's layouts virtual void openTabBox(const char* label) = 0; virtual void openHorizontalBox(const char* label) = 0; virtual void openVerticalBox(const char* label) = 0; virtual void closeBox() = 0; // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0; virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0; virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0; virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0; // -- metadata declarations virtual void declare(FAUSTFLOAT*, const char*, const char*) {} }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/console.h000066400000000000000000000130241210074205700272370ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __faustconsole__ #define __faustconsole__ #include #include #include #include #include #include #include #include "faust/gui/GUI.h" using namespace std; /****************************************************************************** ******************************************************************************* USER INTERFACE ******************************************************************************* *******************************************************************************/ struct param { FAUSTFLOAT* fZone; FAUSTFLOAT fMin; FAUSTFLOAT fMax; param(FAUSTFLOAT* z, FAUSTFLOAT a, FAUSTFLOAT b) : fZone(z), fMin(a), fMax(b) {} }; class CMDUI : public GUI { int fArgc; char** fArgv; stack fPrefix; map fKeyParam; void addOption(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { string fullname = fPrefix.top() + label; fKeyParam.insert(make_pair(fullname, param(zone, min, max))); } void openAnyBox(const char* label) { string prefix; if (label && label[0]) { prefix = fPrefix.top() + "-" + label; } else { prefix = fPrefix.top(); } fPrefix.push(prefix); } public: CMDUI(int argc, char *argv[]) : GUI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } virtual ~CMDUI() {} virtual void openTabBox(const char* label) { openAnyBox(label); } virtual void openHorizontalBox(const char* label) { openAnyBox(label); } virtual void openVerticalBox(const char* label) { openAnyBox(label); } virtual void closeBox() { fPrefix.pop(); } virtual void addButton(const char* label, FAUSTFLOAT* zone) {}; virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) {}; virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {} virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {} virtual void show() {} virtual void run() { char c; printf("Type 'q' to quit\n"); while ((c = getchar()) != 'q') { sleep(1); } } void print() { map::iterator i; cout << fArgc << "\n"; cout << fArgv[0] << " option list : "; for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; } cout << endl; } void process_command() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; print(); exit(1); } char* end; *(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end)); i++; } } } void process_init() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; exit(1); } char* end; *(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end)); i++; } } } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/faustgtk.h000066400000000000000000001320711210074205700274310ustar00rootroot00000000000000#ifndef FAUST_GTKUI_H #define FAUST_GTKUI_H #include "faust/gui/GUI.h" /****************************************************************************** ******************************************************************************* GRAPHIC USER INTERFACE gtk interface ******************************************************************************* *******************************************************************************/ #include #include #include #include #include #include #include #include using namespace std; #define stackSize 256 // Insertion modes #define kSingleMode 0 #define kBoxMode 1 #define kTabMode 2 //------------ calculate needed precision static int precision(double n) { if (n < 0.009999) return 3; else if (n < 0.099999) return 2; else if (n < 0.999999) return 1; else return 0; } namespace gtk_knob { class GtkKnob { private: double start_x, start_y, max_value; public: GtkRange parent; int last_quadrant; GtkKnob(); ~GtkKnob(); GtkWidget *gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment); }; #define GTK_TYPE_KNOB (gtk_knob_get_type()) #define GTK_KNOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob)) #define GTK_IS_KNOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB)) #define GTK_KNOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_KNOB, GtkKnobClass)) #define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_KNOB)) GtkKnob::GtkKnob() // GtkKnob constructor {} GtkKnob::~GtkKnob() { // Nothing specific to do... } struct GtkKnobClass { GtkRangeClass parent_class; int knob_x; int knob_y; int knob_step; int button_is; }; //------forward declaration GType gtk_knob_get_type (); /**************************************************************** ** calculate the knop pointer with dead zone */ const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs static void knob_expose(GtkWidget *widget, int knob_x, int knob_y, GdkEventExpose *event, int arc_offset) { /** check resize **/ int grow; if(widget->allocation.width > widget->allocation.height) { grow = widget->allocation.height; } else { grow = widget->allocation.width; } knob_x = grow-4; knob_y = grow-4; /** get values for the knob **/ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int knobx = (widget->allocation.x+2 + (widget->allocation.width-4 - knob_x) * 0.5); int knoby = (widget->allocation.y+2 + (widget->allocation.height-4 - knob_y) * 0.5); int knobx1 = (widget->allocation.x+2 + (widget->allocation.width-4)* 0.5); int knoby1 = (widget->allocation.y+2 + (widget->allocation.height-4) * 0.5); double knobstate = (adj->value - adj->lower) / (adj->upper - adj->lower); double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero); double knobstate1 = (0. - adj->lower) / (adj->upper - adj->lower); double pointer_off = knob_x/6; double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2; double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle); double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle); double radius1 = min(knob_x, knob_y) / 2 ; /** get widget forground color convert to cairo **/ GtkStyle *style = gtk_widget_get_style (widget); double r = min(0.6,style->fg[gtk_widget_get_state(widget)].red/65535.0), g = min(0.6,style->fg[gtk_widget_get_state(widget)].green/65535.0), b = min(0.6,style->fg[gtk_widget_get_state(widget)].blue/65535.0); /** paint focus **/ if (GTK_WIDGET_HAS_FOCUS(widget)== TRUE) { gtk_paint_focus(widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, NULL, knobx-2, knoby-2, knob_x+4, knob_y+4); } /** create clowing knobs with cairo **/ cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); GdkRegion *region; region = gdk_region_rectangle (&widget->allocation); gdk_region_intersect (region, event->region); gdk_cairo_region (cr, region); cairo_clip (cr); cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI ); cairo_pattern_t*pat = cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 ); if(adj->lower<0 && adj->value>0.) { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } else if(adj->lower<0 && adj->value<=0.) { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } else { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 +knobstate, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + knobstate*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } cairo_set_source (cr, pat); cairo_fill_preserve (cr); gdk_cairo_set_source_color(cr, gtk_widget_get_style (widget)->fg); cairo_set_line_width(cr, 2.0); cairo_stroke(cr); /** create a rotating pointer on the kob**/ cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); cairo_set_line_width(cr,max(3, min(7, knob_x/15))); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); cairo_move_to(cr, knobx+radius1, knoby+radius1); cairo_line_to(cr,lengh_x,lengh_y); cairo_stroke(cr); cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); cairo_set_line_width(cr,min(5, max(1,knob_x/30))); cairo_move_to(cr, knobx+radius1, knoby+radius1); cairo_line_to(cr,lengh_x,lengh_y); cairo_stroke(cr); cairo_pattern_destroy (pat); gdk_region_destroy (region); cairo_destroy(cr); } /**************************************************************** ** general expose events for all "knob" controllers */ //----------- draw the Knob when moved static gboolean gtk_knob_expose (GtkWidget *widget, GdkEventExpose *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); knob_expose(widget, klass->knob_x, klass->knob_y, event, 0); return TRUE; } /**************************************************************** ** set initial size for GdkDrawable per type */ static void gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); requisition->width = klass->knob_x; requisition->height = klass->knob_y; } /**************************************************************** ** set value from key bindings */ static void gtk_knob_set_value (GtkWidget *widget, int dir_down) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment); int step; int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment); if (dir_down) step = oldstep - 1; else step = oldstep + 1; FAUSTFLOAT value = adj->lower + step * double(adj->upper - adj->lower) / nsteps; gtk_widget_grab_focus(widget); gtk_range_set_value(GTK_RANGE(widget), value); } /**************************************************************** ** keyboard bindings */ static gboolean gtk_knob_key_press (GtkWidget *widget, GdkEventKey *event) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); switch (event->keyval) { case GDK_Home: gtk_range_set_value(GTK_RANGE(widget), adj->lower); return TRUE; case GDK_End: gtk_range_set_value(GTK_RANGE(widget), adj->upper); return TRUE; case GDK_Up: gtk_knob_set_value(widget, 0); return TRUE; case GDK_Right: gtk_knob_set_value(widget, 0); return TRUE; case GDK_Down: gtk_knob_set_value(widget, 1); return TRUE; case GDK_Left: gtk_knob_set_value(widget, 1); return TRUE; } return FALSE; } /**************************************************************** ** alternative (radial) knob motion mode (ctrl + mouse pressed) */ static void knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, int knob_x, int knob_y, bool drag, int state) { static double last_y = 2e20; GtkKnob *knob = GTK_KNOB(widget); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); double radius = min(knob_x, knob_y) / 2; int knobx = (widget->allocation.width - knob_x) / 2; int knoby = (widget->allocation.height - knob_y) / 2; double posx = (knobx + radius) - x; // x axis right -> left double posy = (knoby + radius) - y; // y axis top -> bottom double value; if (!drag) { if (state & GDK_CONTROL_MASK) { last_y = 2e20; return; } else { last_y = posy; } } if (last_y < 1e20) { // in drag started with Control Key const double scaling = 0.005; double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling); value = (last_y - posy) * scal; last_y = posy; gtk_range_set_value(GTK_RANGE(widget), adj->value - value * (adj->upper - adj->lower)); return; } double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI if (drag) { // block "forbidden zone" and direct moves between quadrant 1 and 4 int quadrant = 1 + int(angle/M_PI_2); if (knob->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) { angle = scale_zero; } else if (knob->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) { angle = 2*M_PI - scale_zero; } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } knob->last_quadrant = quadrant; } } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } knob->last_quadrant = 0; } angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1 gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower)); } /**************************************************************** ** mouse button pressed set value */ static gboolean gtk_knob_button_press (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); switch (event->button) { case 1: // left button gtk_widget_grab_focus(widget); gtk_widget_grab_default (widget); gtk_grab_add(widget); klass->button_is = 1; knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y, false, event->state); break; case 2: //wheel klass->button_is = 2; break; case 3: // right button klass->button_is = 3; break; default: // do nothing break; } return TRUE; } /**************************************************************** ** mouse button release */ static gboolean gtk_knob_button_release (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->button_is = 0; if (GTK_WIDGET_HAS_GRAB(widget)) gtk_grab_remove(widget); return FALSE; } /**************************************************************** ** set the value from mouse movement */ static gboolean gtk_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); gdk_event_request_motions (event); if (GTK_WIDGET_HAS_GRAB(widget)) { knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y, true, event->state); } return FALSE; } /**************************************************************** ** set value from mouseweel */ static gboolean gtk_knob_scroll (GtkWidget *widget, GdkEventScroll *event) { usleep(5000); gtk_knob_set_value(widget, event->direction); return FALSE; } /**************************************************************** ** init the GtkKnobClass */ static void gtk_knob_class_init (GtkKnobClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); /** set here the sizes and steps for the used knob **/ //--------- small knob size and steps klass->knob_x = 30; klass->knob_y = 30; klass->knob_step = 86; //--------- event button klass->button_is = 0; //--------- connect the events with funktions widget_class->expose_event = gtk_knob_expose; widget_class->size_request = gtk_knob_size_request; widget_class->button_press_event = gtk_knob_button_press; widget_class->button_release_event = gtk_knob_button_release; widget_class->motion_notify_event = gtk_knob_pointer_motion; widget_class->key_press_event = gtk_knob_key_press; widget_class->scroll_event = gtk_knob_scroll; } /**************************************************************** ** init the Knob type/size */ static void gtk_knob_init (GtkKnob *knob) { GtkWidget *widget = GTK_WIDGET(knob); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_DEFAULT); widget->requisition.width = klass->knob_x; widget->requisition.height = klass->knob_y; } /**************************************************************** ** redraw when value changed */ static gboolean gtk_knob_value_changed(gpointer obj) { GtkWidget *widget = (GtkWidget *)obj; gtk_widget_queue_draw(widget); return FALSE; } /**************************************************************** ** create small knob */ GtkWidget *GtkKnob::gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment) { GtkWidget *widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL )); GtkKnob *knob = GTK_KNOB(widget); knob->last_quadrant = 0; if (widget) { gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment); g_signal_connect(GTK_OBJECT(widget), "value-changed", G_CALLBACK(gtk_knob_value_changed), widget); } return widget; } /**************************************************************** ** get the Knob type */ GType gtk_knob_get_type (void) { static GType kn_type = 0; if (!kn_type) { static const GTypeInfo kn_info = { sizeof(GtkKnobClass), NULL, NULL, (GClassInitFunc)gtk_knob_class_init, NULL, NULL, sizeof(GtkKnob), 0, (GInstanceInitFunc)gtk_knob_init, NULL }; kn_type = g_type_register_static(GTK_TYPE_RANGE, "GtkKnob", &kn_info, (GTypeFlags)0); } return kn_type; } }/* end of gtk_knob namespace */ gtk_knob::GtkKnob myGtkKnob; /** * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string * (but not those in the middle of the string) */ static string rmWhiteSpaces(const string& s) { size_t i = s.find_first_not_of(" \t"); size_t j = s.find_last_not_of(" \t"); if (i != string::npos & j != string::npos) { return s.substr(i, 1+j-i); } else { return ""; } } /** * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata */ static void extractMetadata(const string& fulllabel, string& label, map& metadata) { enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue}; int state = kLabel; int deep = 0; string key, value; for (unsigned int i=0; i < fulllabel.size(); i++) { char c = fulllabel[i]; switch (state) { case kLabel : assert (deep == 0); switch (c) { case '\\' : state = kEscape1; break; case '[' : state = kKey; deep++; break; default : label += c; } break; case kEscape1 : label += c; state = kLabel; break; case kEscape2 : key += c; state = kKey; break; case kEscape3 : value += c; state = kValue; break; case kKey : assert (deep > 0); switch (c) { case '\\' : state = kEscape2; break; case '[' : deep++; key += c; break; case ':' : if (deep == 1) { state = kValue; } else { key += c; } break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)] = ""; state = kLabel; key=""; value=""; } else { key += c; } break; default : key += c; } break; case kValue : assert (deep > 0); switch (c) { case '\\' : state = kEscape3; break; case '[' : deep++; value += c; break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value); state = kLabel; key=""; value=""; } else { value += c; } break; default : value += c; } break; default : cerr << "ERROR unrecognized state " << state << endl; } } label = rmWhiteSpaces(label); } class GTKUI : public GUI { private : static bool fInitialized; static map fGuiSize; // map widget zone with widget size coef static map fTooltip; // map widget zone with tooltip strings static set fKnobSet; // set of widget zone to be knobs string gGroupTooltip; bool isKnob(FAUSTFLOAT* zone) {return fKnobSet.count(zone) > 0;} protected : GtkWidget* fWindow; int fTop; GtkWidget* fBox[stackSize]; int fMode[stackSize]; bool fStopped; GtkWidget* addWidget(const char* label, GtkWidget* w); virtual void pushBox(int mode, GtkWidget* w); public : static const gboolean expand = TRUE; static const gboolean fill = TRUE; static const gboolean homogene = FALSE; GTKUI(char * name, int* pargc, char*** pargv); // -- Labels and metadata virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value); virtual int checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel); virtual void checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget); // -- layout groups virtual void openTabBox(const char* label = ""); virtual void openHorizontalBox(const char* label = ""); virtual void openVerticalBox(const char* label = ""); virtual void closeBox(); // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone); virtual void addCheckButton(const char* label, FAUSTFLOAT* zone); virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); // -- passive display widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max); virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max); // -- layout groups - internal virtual void openFrameBox(const char* label); // -- extra widget's layouts virtual void openDialogBox(const char* label, FAUSTFLOAT* zone); virtual void openEventBox(const char* label = ""); virtual void openHandleBox(const char* label = ""); virtual void openExpanderBox(const char* label, FAUSTFLOAT* zone); virtual void adjustStack(int n); // -- active widgets - internal virtual void addToggleButton(const char* label, FAUSTFLOAT* zone); virtual void addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); // -- passive display widgets - internal virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision); virtual void addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT min, FAUSTFLOAT max); virtual void show(); virtual void run(); }; /****************************************************************************** ******************************************************************************* GRAPHIC USER INTERFACE (v2) gtk implementation ******************************************************************************* *******************************************************************************/ // global static fields bool GTKUI::fInitialized = false; map GTKUI::fGuiSize; map GTKUI::fTooltip; set GTKUI::fKnobSet; // set of widget zone to be knobs /** * Format tooltip string by replacing some white spaces by * return characters so that line width doesn't exceed n. * Limitation : long words exceeding n are not cut */ static string formatTooltip(unsigned int n, const string& tt) { string ss = tt; // ss string we are going to format unsigned int lws = 0; // last white space encountered unsigned int lri = 0; // last return inserted for (unsigned int i = 0; i < tt.size(); i++) { if (tt[i] == ' ') lws = i; if (((i-lri) >= n) && (lws > lri)) { // insert return here ss[lws] = '\n'; lri = lws; } } cout << ss; return ss; } static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { return FALSE; } static void destroy_event( GtkWidget *widget, gpointer data ) { gtk_main_quit (); } GTKUI::GTKUI(char * name, int* pargc, char*** pargv) { if (!fInitialized) { gtk_init(pargc, pargv); fInitialized = true; } fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10); gtk_window_set_title (GTK_WINDOW (fWindow), name); gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL); fTop = 0; fBox[fTop] = gtk_vbox_new (homogene, 4); fMode[fTop] = kBoxMode; gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]); fStopped = false; } // empilement des boites void GTKUI::pushBox(int mode, GtkWidget* w) { ++fTop; assert(fTop < stackSize); fMode[fTop] = mode; fBox[fTop] = w; } /** * Remove n levels from the stack S before the top level * adjustStack(n): S -> S' with S' = S(0),S(n+1),S(n+2),... */ void GTKUI::adjustStack(int n) { if (n > 0) { assert(fTop >= n); fTop -= n; fMode[fTop] = fMode[fTop+n]; fBox[fTop] = fBox[fTop+n]; } } void GTKUI::closeBox() { --fTop; assert(fTop >= 0); } /** * Analyses the widget zone metadata declarations and takes * appropriate actions */ void GTKUI::declare(FAUSTFLOAT* zone, const char* key, const char* value) { if (zone == 0) { // special zone 0 means group metadata if (strcmp(key,"tooltip") == 0) { // only group tooltip are currently implemented gGroupTooltip = formatTooltip(30, value); } } else { if (strcmp(key,"size")==0) { fGuiSize[zone] = atof(value); } else if (strcmp(key,"tooltip") == 0) { fTooltip[zone] = formatTooltip(30,value) ; } else if (strcmp(key,"style") == 0) { if (strcmp(value,"knob") == 0) { fKnobSet.insert(zone); } } } } /** * Analyses a full label and activates the relevant options. returns a simplified * label (without options) and an amount of stack adjustement (in case additional * containers were pushed on the stack). */ int GTKUI::checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel) { map metadata; extractMetadata(fullLabel, simplifiedLabel, metadata); if (metadata.count("tooltip")) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, metadata["tooltip"].c_str(), NULL); } if (metadata["option"] == "detachable") { openHandleBox(simplifiedLabel.c_str()); return 1; } //--------------------- if (gGroupTooltip != string()) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, gGroupTooltip.c_str(), NULL); gGroupTooltip = string(); } //---------------------- // no adjustement of the stack needed return 0; } /** * Check if a tooltip is associated to a zone and add it to the corresponding widget */ void GTKUI::checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget) { if (fTooltip.count(zone)) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, fTooltip[zone].c_str(), NULL); } } // les differentes boites void GTKUI::openFrameBox(const char* label) { GtkWidget * box = gtk_frame_new (label); //gtk_container_set_border_width (GTK_CONTAINER (box), 10); pushBox(kSingleMode, addWidget(label, box)); } void GTKUI::openTabBox(const char* fullLabel) { string label; GtkWidget* widget = gtk_notebook_new(); int adjust = checkLabelOptions(widget, fullLabel, label); pushBox(kTabMode, addWidget(label.c_str(), widget)); // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openHorizontalBox(const char* fullLabel) { string label; GtkWidget* box = gtk_hbox_new (homogene, 4); int adjust = checkLabelOptions(box, fullLabel, label); gtk_container_set_border_width (GTK_CONTAINER (box), 10); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str())); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label.c_str(), box)); } // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openVerticalBox(const char* fullLabel) { string label; GtkWidget * box = gtk_vbox_new (homogene, 4); int adjust = checkLabelOptions(box, fullLabel, label); gtk_container_set_border_width (GTK_CONTAINER (box), 10); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str())); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label.c_str(), box)); } // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openHandleBox(const char* label) { GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_handle_box_new ()); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } void GTKUI::openEventBox(const char* label) { GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_event_box_new ()); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } struct uiExpanderBox : public uiItem { GtkExpander* fButton; uiExpanderBox(GUI* ui, FAUSTFLOAT* zone, GtkExpander* b) : uiItem(ui, zone), fButton(b) {} static void expanded (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = gtk_expander_get_expanded (GTK_EXPANDER(widget)); if (v == 1.000000) { v = 0; } else { v = 1; } ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_expander_set_expanded(GTK_EXPANDER(fButton), v); } }; void GTKUI::openExpanderBox(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_expander_new (label)); gtk_container_add (GTK_CONTAINER(frame), box); uiExpanderBox* c = new uiExpanderBox(this, zone, GTK_EXPANDER(frame)); gtk_signal_connect (GTK_OBJECT (frame), "activate", GTK_SIGNAL_FUNC (uiExpanderBox::expanded), (gpointer)c); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w) { switch (fMode[fTop]) { case kSingleMode : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w); break; case kBoxMode : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0); break; case kTabMode : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break; } gtk_widget_show (w); return w; } // --------------------------- Press button --------------------------- struct uiButton : public uiItem { GtkButton* fButton; uiButton(GUI* ui, FAUSTFLOAT* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {} static void pressed(GtkWidget *widget, gpointer data) { uiItem* c = (uiItem*) data; c->modifyZone(1.0); } static void released(GtkWidget *widget, gpointer data) { uiItem* c = (uiItem*) data; c->modifyZone(0.0); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton); } }; void GTKUI::addButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_button_new_with_label (label); addWidget(label, button); uiButton* c = new uiButton(this, zone, GTK_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c); gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c); checkForTooltip(zone, button); } // --------------------------- Toggle Buttons --------------------------- struct uiToggleButton : public uiItem { GtkToggleButton* fButton; uiToggleButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {} static void toggled (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_toggle_button_set_active(fButton, v > 0.0); } }; void GTKUI::addToggleButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_toggle_button_new_with_label (label); addWidget(label, button); uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c); checkForTooltip(zone, button); } void show_dialog(GtkWidget *widget, gpointer data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == TRUE) { gtk_widget_show(GTK_WIDGET(data)); gint root_x, root_y; gtk_window_get_position (GTK_WINDOW(data), &root_x, &root_y); root_y -= 120; gtk_window_move(GTK_WINDOW(data), root_x, root_y); } else gtk_widget_hide(GTK_WIDGET(data)); } static gboolean deleteevent( GtkWidget *widget, gpointer data ) { return TRUE; } void GTKUI::openDialogBox(const char* label, FAUSTFLOAT* zone) { // create toplevel window and set properties GtkWidget * dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_decorated(GTK_WINDOW(dialog), TRUE); gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE); gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_SOUTH); gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(fWindow)); gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); gtk_window_set_keep_below (GTK_WINDOW(dialog), FALSE); gtk_window_set_title (GTK_WINDOW (dialog), label); g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (deleteevent), NULL); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); GtkWidget * box = gtk_hbox_new (homogene, 4); *zone = 0.0; GtkWidget* button = gtk_toggle_button_new (); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (show_dialog), (gpointer) dialog); gtk_container_add (GTK_CONTAINER(fBox[fTop]), button); gtk_container_add (GTK_CONTAINER(dialog), box); gtk_widget_show (button); gtk_widget_show(box); pushBox(kBoxMode, box); } // --------------------------- Check Button --------------------------- struct uiCheckButton : public uiItem { GtkToggleButton* fButton; uiCheckButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {} static void toggled (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_toggle_button_set_active(fButton, v > 0.0); } }; void GTKUI::addCheckButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_check_button_new_with_label (label); addWidget(label, button); uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c); checkForTooltip(zone, button); } // --------------------------- Adjustmenty based widgets --------------------------- struct uiAdjustment : public uiItem { GtkAdjustment* fAdj; uiAdjustment(GUI* ui, FAUSTFLOAT* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {} static void changed (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = GTK_ADJUSTMENT (widget)->value; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_adjustment_set_value(fAdj, v); } }; // --------------------------- format knob value display --------------------------- struct uiValueDisplay : public uiItem { GtkLabel* fLabel; int fPrecision ; uiValueDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision) : uiItem(ui, zone), fLabel(label), fPrecision(precision) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; char s[64]; if (fPrecision <= 0) snprintf(s, 63, "%d", int(v)); else if (fPrecision > 3) snprintf(s, 63, "%f", v); else if (fPrecision == 1) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[1-1], v); } else if (fPrecision == 2) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[2-1], v); } else { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[3-1], v); } gtk_label_set_text(fLabel, s); } }; // ------------------------------- Knob ----------------------------------------- void GTKUI::addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_vbox_new (FALSE, 0); GtkWidget* fil = gtk_vbox_new (FALSE, 0); GtkWidget* rei = gtk_vbox_new (FALSE, 0); GtkWidget* re =myGtkKnob.gtk_knob_new_with_adjustment(GTK_ADJUSTMENT(adj)); GtkWidget* lw = gtk_label_new(""); new uiValueDisplay(this, zone, GTK_LABEL(lw),precision(step)); gtk_container_add (GTK_CONTAINER(rei), re); if(fGuiSize[zone]) { FAUSTFLOAT size = 30 * fGuiSize[zone]; gtk_widget_set_size_request(rei, size, size ); gtk_box_pack_start (GTK_BOX(slider), fil, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(slider), rei, FALSE, FALSE, 0); } else { gtk_container_add (GTK_CONTAINER(slider), fil); gtk_container_add (GTK_CONTAINER(slider), rei); } gtk_container_add (GTK_CONTAINER(slider), lw); gtk_widget_show_all(slider); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // -------------------------- Vertical Slider ----------------------------------- void GTKUI::addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj)); gtk_scale_set_digits(GTK_SCALE(slider), precision(step)); FAUSTFLOAT size = 160; if(fGuiSize[zone]) { size = 160 * fGuiSize[zone]; } gtk_widget_set_size_request(slider, -1, size); gtk_range_set_inverted (GTK_RANGE(slider), TRUE); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // -------------------------- Horizontal Slider ----------------------------------- void GTKUI::addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj)); gtk_scale_set_digits(GTK_SCALE(slider), precision(step)); FAUSTFLOAT size = 160; if(fGuiSize[zone]) { size = 160 * fGuiSize[zone]; } gtk_widget_set_size_request(slider, size, -1); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // ------------------------------ Num Entry ----------------------------------- void GTKUI::addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step)); openFrameBox(label); addWidget(label, spinner); closeBox(); checkForTooltip(zone, spinner); } // ========================== passive widgets =============================== // ------------------------------ Progress Bar ----------------------------------- struct uiBargraph : public uiItem { GtkProgressBar* fProgressBar; FAUSTFLOAT fMin; FAUSTFLOAT fMax; uiBargraph(GUI* ui, FAUSTFLOAT* zone, GtkProgressBar* pbar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {} FAUSTFLOAT scale(FAUSTFLOAT v) { return (v-fMin)/(fMax-fMin); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_progress_bar_set_fraction(fProgressBar, scale(v)); } }; void GTKUI::addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* pb = gtk_progress_bar_new(); gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP); gtk_widget_set_size_request(pb, 8, -1); new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi); openFrameBox(label); addWidget(label, pb); closeBox(); checkForTooltip(zone, pb); } void GTKUI::addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* pb = gtk_progress_bar_new(); gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT); gtk_widget_set_size_request(pb, -1, 8); new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi); openFrameBox(label); addWidget(label, pb); closeBox(); checkForTooltip(zone, pb); } // ------------------------------ Num Display ----------------------------------- struct uiNumDisplay : public uiItem { GtkLabel* fLabel; int fPrecision; uiNumDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision) : uiItem(ui, zone), fLabel(label), fPrecision(precision) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; char s[64]; if (fPrecision <= 0) { snprintf(s, 63, "%d", int(v)); } else if (fPrecision>3) { snprintf(s, 63, "%f", v); } else { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[fPrecision-1], v); } gtk_label_set_text(fLabel, s); } }; void GTKUI::addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision) { GtkWidget* lw = gtk_label_new(""); new uiNumDisplay(this, zone, GTK_LABEL(lw), precision); openFrameBox(label); addWidget(label, lw); closeBox(); checkForTooltip(zone, lw); } // ------------------------------ Text Display ----------------------------------- struct uiTextDisplay : public uiItem { GtkLabel* fLabel; const char** fNames; FAUSTFLOAT fMin; FAUSTFLOAT fMax; int fNum; uiTextDisplay (GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi) { fNum = 0; while (fNames[fNum] != 0) fNum++; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; int idx = int(fNum*(v-fMin)/(fMax-fMin)); if (idx < 0) idx = 0; else if (idx >= fNum) idx = fNum-1; gtk_label_set_text(fLabel, fNames[idx]); } }; void GTKUI::addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* lw = gtk_label_new(""); new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi); openFrameBox(label); addWidget(label, lw); closeBox(); checkForTooltip(zone, lw); } void GTKUI::show() { assert(fTop == 0); gtk_widget_show (fBox[0]); gtk_widget_show (fWindow); } /** * Update all user items reflecting zone z */ static gboolean callUpdateAllGuis(gpointer) { GUI::updateAllGuis(); return TRUE; } void GTKUI::run() { assert(fTop == 0); gtk_widget_show (fBox[0]); gtk_widget_show (fWindow); gtk_timeout_add(40, callUpdateAllGuis, 0); gtk_main (); stop(); } #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/faustqt.h000066400000000000000000001543511210074205700272750ustar00rootroot00000000000000/************************************************************************ ************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . ************************************************************************ ************************************************************************/ #ifndef __faustqt__ #define __faustqt__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include "faust/gui/GUI.h" //---------------------------------- // for compatibility #define minValue minimum #define maxValue maximum using namespace std; //==============================BEGIN QSYNTHKNOB===================================== // // qsynthknob and qsynthDialVokiStyle borrowed from qsynth-0.3.3 by Rui Nuno Capela // This widget is based on a design by Thorsten Wilms, // implemented by Chris Cannam in Rosegarden, // adapted for QSynth by Pedro Lopez-Cabanillas, // improved for Qt4 by David Garcia Garzon. // #define DIAL_MIN (0.25 * M_PI) #define DIAL_MAX (1.75 * M_PI) #define DIAL_RANGE (DIAL_MAX - DIAL_MIN) class qsynthDialVokiStyle : public QCommonStyle { public: qsynthDialVokiStyle() {}; virtual ~qsynthDialVokiStyle() {}; virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget = 0) const { if (cc != QStyle::CC_Dial) { QCommonStyle::drawComplexControl(cc, opt, p, widget); return; } const QStyleOptionSlider *dial = qstyleoption_cast(opt); if (dial == NULL) return; double angle = DIAL_MIN // offset + (DIAL_RANGE * (double(dial->sliderValue - dial->minimum) / (double(dial->maximum - dial->minimum)))); int degrees = int(angle * 180.0 / M_PI); int side = dial->rect.width() < dial->rect.height() ? dial->rect.width() : dial->rect.height(); int xcenter = dial->rect.width() / 2; int ycenter = dial->rect.height() / 2; int notchWidth = 1 + side / 400; int pointerWidth = 2 + side / 30; int scaleShadowWidth = 1 + side / 100; int knobBorderWidth = 0; int ns = dial->tickInterval; int numTicks = 1 + (dial->maximum + ns - dial->minimum) / ns; int indent = int(0.15 * side) + 2; int knobWidth = side - 2 * indent; int shineFocus = knobWidth / 4; int shineCenter = knobWidth / 5; int shineExtension = shineCenter * 4; int shadowShift = shineCenter * 2; int meterWidth = side - 2 * scaleShadowWidth; QPalette pal = opt->palette; QColor knobColor = pal.mid().color(); QColor borderColor = knobColor.light(); QColor meterColor = (dial->state & State_Enabled) ? QColor("orange") : pal.mid().color(); // pal.highlight().color() : pal.mid().color(); QColor background = pal.window().color(); p->save(); p->setRenderHint(QPainter::Antialiasing, true); // The bright metering bit... QConicalGradient meterShadow(xcenter, ycenter, -90); meterShadow.setColorAt(0, meterColor.dark()); meterShadow.setColorAt(0.5, meterColor); meterShadow.setColorAt(1.0, meterColor.light().light()); p->setBrush(meterShadow); p->setPen(Qt::transparent); p->drawPie(xcenter - meterWidth / 2, ycenter - meterWidth / 2, meterWidth, meterWidth, (180 + 45) * 16, -(degrees - 45) * 16); // Knob projected shadow QRadialGradient projectionGradient( xcenter + shineCenter, ycenter + shineCenter, shineExtension, xcenter + shadowShift, ycenter + shadowShift); projectionGradient.setColorAt(0, QColor( 0, 0, 0, 100)); projectionGradient.setColorAt(1, QColor(200, 0, 0, 10)); QBrush shadowBrush(projectionGradient); p->setBrush(shadowBrush); p->drawEllipse(xcenter - shadowShift, ycenter - shadowShift, knobWidth, knobWidth); // Knob body and face... QPen pen; pen.setColor(knobColor); pen.setWidth(knobBorderWidth); p->setPen(pen); QRadialGradient gradient( xcenter - shineCenter, ycenter - shineCenter, shineExtension, xcenter - shineFocus, ycenter - shineFocus); gradient.setColorAt(0.2, knobColor.light().light()); gradient.setColorAt(0.5, knobColor); gradient.setColorAt(1.0, knobColor.dark(150)); QBrush knobBrush(gradient); p->setBrush(knobBrush); p->drawEllipse(xcenter - knobWidth / 2, ycenter - knobWidth / 2, knobWidth, knobWidth); // Tick notches... p->setBrush(Qt::NoBrush); if (dial->subControls & QStyle::SC_DialTickmarks) { pen.setColor(pal.dark().color()); pen.setWidth(notchWidth); p->setPen(pen); double hyp = double(side - scaleShadowWidth) / 2.0; double len = hyp / 4; for (int i = 0; i < numTicks; ++i) { int div = numTicks; if (div > 1) --div; bool internal = (i != 0 && i != numTicks - 1); double angle = DIAL_MIN + (DIAL_MAX - DIAL_MIN) * i / div; double dir = (internal ? -1 : len); double sinAngle = sin(angle); double cosAngle = cos(angle); double x0 = xcenter - (hyp - len) * sinAngle; double y0 = ycenter + (hyp - len) * cosAngle; double x1 = xcenter - (hyp + dir) * sinAngle; double y1 = ycenter + (hyp + dir) * cosAngle; p->drawLine(QLineF(x0, y0, x1, y1)); } } // Shadowing... // Knob shadow... if (knobBorderWidth > 0) { QLinearGradient inShadow(xcenter - side / 4, ycenter - side / 4, xcenter + side / 4, ycenter + side / 4); inShadow.setColorAt(0.0, borderColor.light()); inShadow.setColorAt(1.0, borderColor.dark()); p->setPen(QPen(QBrush(inShadow), knobBorderWidth * 7 / 8)); p->drawEllipse(xcenter - side / 2 + indent, ycenter - side / 2 + indent, side - 2 * indent, side - 2 * indent); } // Scale shadow... QLinearGradient outShadow(xcenter - side / 3, ycenter - side / 3, xcenter + side / 3, ycenter + side / 3); outShadow.setColorAt(0.0, background.dark().dark()); outShadow.setColorAt(1.0, background.light().light()); p->setPen(QPen(QBrush(outShadow), scaleShadowWidth)); p->drawArc(xcenter - side / 2 + scaleShadowWidth / 2, ycenter - side / 2 + scaleShadowWidth / 2, side - scaleShadowWidth, side - scaleShadowWidth, -45 * 16, 270 * 16); // Pointer notch... double hyp = double(side) / 2.0; double len = hyp - indent - 1; double x = xcenter - len * sin(angle); double y = ycenter + len * cos(angle); QColor pointerColor = pal.dark().color(); pen.setColor((dial->state & State_Enabled) ? pointerColor.dark(140) : pointerColor); pen.setWidth(pointerWidth + 2); p->setPen(pen); p->drawLine(QLineF(xcenter, ycenter, x, y)); pen.setColor((dial->state & State_Enabled) ? pointerColor.light() : pointerColor.light(140)); pen.setWidth(pointerWidth); p->setPen(pen); p->drawLine(QLineF(xcenter - 1, ycenter - 1, x - 1, y - 1)); // done p->restore(); } }; // //===============================END QSYNTHKNOB====================================== //==============================BEGIN DISPLAYS=================================== // // This section constains displays, passive QT widgets that displays values in // different ways, in particular bargraphs // /** * An abstract widget that display a value in a range */ class AbstractDisplay : public QWidget { protected : FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fValue; public: AbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : fMin(lo), fMax(hi), fValue(lo) {} /** * set the range of displayed values */ virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi) { fMin = lo; fMax = hi; } /** * set the value to be displayed */ virtual void setValue(FAUSTFLOAT v) { if (v < fMin) v = fMin; else if (v > fMax) v = fMax; if (v != fValue) { fValue = v; update(); } } }; /** * Displays dB values using a scale of colors */ class dbAbstractDisplay : public AbstractDisplay { protected : FAUSTFLOAT fScaleMin; FAUSTFLOAT fScaleMax; vector fLevel; vector fBrush; /** * Convert a dB value into a scale between 0 and 1 (following IEC standard ?) */ FAUSTFLOAT dB2Scale(FAUSTFLOAT dB) const { FAUSTFLOAT fScale = 1.0; /*if (dB < -70.0f) fScale = 0.0f; else*/ if (dB < -60.0) fScale = (dB + 70.0) * 0.0025; else if (dB < -50.0) fScale = (dB + 60.0) * 0.005 + 0.025; else if (dB < -40.0) fScale = (dB + 50.0) * 0.0075 + 0.075; else if (dB < -30.0) fScale = (dB + 40.0) * 0.015 + 0.15; else if (dB < -20.0) fScale = (dB + 30.0) * 0.02 + 0.3; else if (dB < -0.001 || dB > 0.001) /* if (dB < 0.0) */ fScale = (dB + 20.0f) * 0.025 + 0.5; return fScale; } /** * Create the scale of colors used to paint the bargraph in relation to the levels * The parameter x indicates the direction of the gradient. x=1 means an horizontal * gradient typically used by a vertical bargraph, and x=0 a vertical gradient. */ void initLevelsColors(int x) { int alpha = 200; { // level until -10 dB QColor c(40, 160, 40, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-10); fBrush.push_back(QBrush(g)); } { // level until -6 dB QColor c(160, 220, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-6); fBrush.push_back(QBrush(g)); } { // level until -3 dB QColor c(220, 220, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-3); fBrush.push_back(QBrush(g)); } { // level until -0 dB QColor c(240, 160, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(0); fBrush.push_back(QBrush(g)); } { // until 10 dB (and over because last one) QColor c(240, 0, 20, alpha); // ColorOver QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(+10); fBrush.push_back(QBrush(g)); } } public: dbAbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo, hi) {} /** * set the range of displayed values */ virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi) { AbstractDisplay::setRange(lo, hi); fScaleMin = dB2Scale(fMin); fScaleMax = dB2Scale(fMax); } }; /** * Small rectangular LED display which color changes with the level in dB */ class dbLED : public dbAbstractDisplay { protected: /** * Draw the LED using a color depending of its value in dB */ virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); painter.drawRect(rect()); if (fValue <= fLevel[0]) { // interpolate the first color on the alpha channel QColor c(40, 160, 40) ; FAUSTFLOAT a = (fValue-fMin)/(fLevel[0]-fMin); c.setAlphaF(a); painter.fillRect(rect(), c); } else { // find the minimal level > value int l = fLevel.size()-1; while (fValue < fLevel[l] && l > 0) l--; painter.fillRect(rect(), fBrush[l]); } } public: dbLED(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); initLevelsColors(1); } virtual QSize sizeHint () const { return QSize(16, 8); } }; /** * Small rectangular LED display which intensity (alpha channel) changes according to the value */ class LED : public AbstractDisplay { QColor fColor; protected: /** * Draw the LED using a transparency depending of its value */ virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); painter.drawRect(rect()); // interpolate the first color on the alpha channel QColor c = fColor ; FAUSTFLOAT a = (fValue-fMin)/(fMax-fMin); c.setAlphaF(a); painter.fillRect(rect(), c); } public: LED(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi), fColor("yellow") { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } virtual QSize sizeHint () const { return QSize(16, 8); } }; /** * A simple bargraph that detect automatically its direction */ class linBargraph : public AbstractDisplay { protected : QBrush fBrush; /** * No scale implemented yet */ void paintScale(QPainter* painter) const { painter->drawRect(0,0,width(),height()); } /** * The length of the rectangle is proportional to the value */ void paintContent (QPainter* painter) const { int w = width(); int h = height(); FAUSTFLOAT v = (fValue-fMin)/(fMax-fMin); if (h>w) { // draw vertical rectangle painter->fillRect(0,(1-v)*h,w, v*h, fBrush); } else { // draw horizontal rectangle painter->fillRect(0, 0, h, v*w, fBrush); } } virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); paintContent(&painter); paintScale(&painter); } public: linBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi) { // compute the brush that will be used to // paint the value QColor c(0xffa500); // orange int x = int(height() < width()); // gradient direction QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fBrush = QBrush(g); } }; /** * A simple vertical bargraph */ class linVerticalBargraph : public linBargraph { public: linVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); } virtual QSize sizeHint () const { return QSize(16, 128); } }; /** * A simple horizontal bargraph */ class linHorizontalBargraph : public linBargraph { public: linHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } virtual QSize sizeHint () const { return QSize(128, 16); } }; /** * A dB Bargraph with a scale of colors */ class dbBargraph : public dbAbstractDisplay { QBrush fBackColor; protected : // These two abstract methods are implemented // according to the vertical or horizontal direction // in dbVerticalBargraph and dbHorizontalBargraph virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const = 0; virtual int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const = 0; /** * Draw the logarithmic scale */ void paintScale(QPainter* painter) const { painter->fillRect(0,0,width(),height(), fBackColor); painter->save(); painter->setPen(QColor(0x6699aa)); //0xffa500)); for (FAUSTFLOAT v = -10; v > fMin; v -= 10) paintMark(painter, v); for (FAUSTFLOAT v = -6; v < fMax; v += 3) paintMark(painter, v); painter->restore(); } /** * Draw the content using colored segments */ void paintContent (QPainter* painter) const { int l = fLevel.size(); FAUSTFLOAT p = -1; // fake value indicates to start from border int n = 0; // paint all the full segments < fValue for (n=0; (n < l) && (fValue > fLevel[n]); n++) { p = paintSegment(painter, p, fLevel[n], fBrush[n]); } // paint the last segment if (n == l) n = n-1; p=paintSegment(painter, p, fValue, fBrush[n]); painter->drawRect(0,0,width(),height()); } virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); paintScale(&painter); paintContent(&painter); } public: dbBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi) { QFont f = this->font(); f.setPointSize(6); this->setFont(f); fBackColor = QBrush(QColor(20,20,20)); } }; /** * Vertical dB Bargraph */ class dbVerticalBargraph : public dbBargraph { protected: /** * Convert a dB value into a vertical position */ FAUSTFLOAT dB2y(FAUSTFLOAT dB) const { FAUSTFLOAT s0 = fScaleMin; FAUSTFLOAT s1 = fScaleMax; FAUSTFLOAT sx = dB2Scale(dB); int h = height(); return h - h*(s0-sx)/(s0-s1); } /** * Paint a vertical graduation mark */ virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const { int n = 10; int y = dB2y(v); QRect r(0,y-n,width()-1,2*n); if (v > 0.0) { painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v).prepend('+')); } else { painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v)); } } /** * Paint a color segment */ virtual int paintSegment(QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const { if (pos == -1) pos = height(); FAUSTFLOAT y = dB2y(v); painter->fillRect(0, y, width(), pos-y+1, b); return y; } public: dbVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); initLevelsColors(1); } virtual QSize sizeHint () const { return QSize(18, 256); } }; /** * Horizontal dB Bargraph */ class dbHorizontalBargraph : public dbBargraph { protected: /** * Convert a dB value into an horizontal position */ FAUSTFLOAT dB2x(FAUSTFLOAT dB) const { FAUSTFLOAT s0 = fScaleMin; FAUSTFLOAT s1 = fScaleMax; FAUSTFLOAT sx = dB2Scale(dB); int w = width(); return w - w*(s1-sx)/(s1-s0); } /** * Paint an horizontal graduation mark */ void paintMark(QPainter* painter, FAUSTFLOAT v) const { int n = 10; int x = dB2x(v); QRect r(x-n,0,2*n, height()); painter->drawText(r, Qt::AlignHCenter|Qt::AlignVCenter, QString::number(v)); } /** * Paint a horizontal color segment */ int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const { if (pos == -1) pos = 0; FAUSTFLOAT x = dB2x(v); painter->fillRect(pos, 0, x-pos, height(), b); return x; } public: dbHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); initLevelsColors(0); } virtual QSize sizeHint () const { return QSize(256, 18); } }; // //===============================END DISPLAYS==================================== //============================= BEGIN GROUP LABEL METADATA=========================== // Unlike widget's label, metadata inside group's label are not extracted directly by // the Faust compiler. Therefore they must be extracted within the architecture file //----------------------------------------------------------------------------------- // /** * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string * (but not those in the middle of the string) */ static string rmWhiteSpaces(const string& s) { size_t i = s.find_first_not_of(" \t"); size_t j = s.find_last_not_of(" \t"); if ( (i != string::npos) && (j != string::npos) ) { return s.substr(i, 1+j-i); } else { return ""; } } /** * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata(unit=dB) */ static void extractMetadata(const string& fulllabel, string& label, map& metadata) { enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue}; int state = kLabel; int deep = 0; string key, value; for (unsigned int i=0; i < fulllabel.size(); i++) { char c = fulllabel[i]; switch (state) { case kLabel : assert (deep == 0); switch (c) { case '\\' : state = kEscape1; break; case '[' : state = kKey; deep++; break; default : label += c; } break; case kEscape1 : label += c; state = kLabel; break; case kEscape2 : key += c; state = kKey; break; case kEscape3 : value += c; state = kValue; break; case kKey : assert (deep > 0); switch (c) { case '\\' : state = kEscape2; break; case '[' : deep++; key += c; break; case ':' : if (deep == 1) { state = kValue; } else { key += c; } break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)] = ""; state = kLabel; key=""; value=""; } else { key += c; } break; default : key += c; } break; case kValue : assert (deep > 0); switch (c) { case '\\' : state = kEscape3; break; case '[' : deep++; value += c; break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value); state = kLabel; key=""; value=""; } else { value += c; } break; default : value += c; } break; default : cerr << "ERROR unrecognized state " << state << endl; } } label = rmWhiteSpaces(label); } // //============================= END GROUP LABEL METADATA=========================== /****************************************************************************** ******************************************************************************* IMPLEMENTATION OF GUI ITEMS (QT 4.3 for FAUST) ******************************************************************************* *******************************************************************************/ class uiButton : public QObject, public uiItem { Q_OBJECT public : QAbstractButton* fButton; uiButton (GUI* ui, FAUSTFLOAT* zone, QAbstractButton* b) : uiItem(ui, zone), fButton(b) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fButton->setDown( v > 0.0 ); } public slots : void pressed() { modifyZone(1.0); } void released() { modifyZone(0.0); } }; class uiCheckButton : public QObject, public uiItem { Q_OBJECT public : QCheckBox* fCheckBox; uiCheckButton (GUI* ui, FAUSTFLOAT* zone, QCheckBox* b) : uiItem(ui, zone), fCheckBox(b) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fCheckBox->setCheckState( (v < 0.5) ? Qt::Unchecked : Qt::Checked ); } public slots : void setState(int v) { modifyZone(FAUSTFLOAT(v>0)); } }; class uiSlider : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/fStep); } FAUSTFLOAT qt2faust (int v) { return fMin + v*fStep; } int optimalTick() { FAUSTFLOAT x = fStep; while ((fMax-fMin)/x > 50) x*=10; while ((fMax-fMin)/x < 10) x/=2; return faust2qt(fMin+x); } public : QSlider* fSlider; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; uiSlider (GUI* ui, FAUSTFLOAT* zone, QSlider* slider, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fSlider->setMinimum(0); fSlider->setMaximum(faust2qt(fMax)); fSlider->setValue(faust2qt(fCur)); fSlider->setTickInterval(optimalTick()); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fSlider->setValue(faust2qt(v)); } public slots : void setValue(int v) { modifyZone(qt2faust(v)); } }; class uiKnob : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/fStep); } FAUSTFLOAT qt2faust (int v) { return fMin + v*fStep; } int optimalTick() { FAUSTFLOAT x = fStep; while ((fMax-fMin)/x > 50) x*=10; while ((fMax-fMin)/x < 10) x/=2; return faust2qt(fMin+x); } public : QAbstractSlider* fSlider; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; uiKnob (GUI* ui, FAUSTFLOAT* zone, QAbstractSlider* slider, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fSlider->setMinimum(0); fSlider->setMaximum(faust2qt(fMax)); fSlider->setValue(faust2qt(fCur)); //fSlider->setTickInterval(optimalTick()); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fSlider->setValue(faust2qt(v)); } public slots : void setValue(int v) { modifyZone(qt2faust(v)); } }; class uiBargraph : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/(fMax-fMin)*fStep); } public : QProgressBar* fBar; FAUSTFLOAT fMin; FAUSTFLOAT fMax; int fStep; uiBargraph (GUI* ui, FAUSTFLOAT* zone, QProgressBar* bar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fBar(bar), fMin(lo), fMax(hi), fStep(1024) { fBar->setRange(0, fStep); fBar->setValue(0); *fZone = 0; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; int x = faust2qt(v); //std::cout << "update *" << fBar << " = " << x << std::endl; fBar->setValue(x); } }; class uiBargraph2 : public QObject, public uiItem { Q_OBJECT public : AbstractDisplay* fBar; uiBargraph2 (GUI* ui, FAUSTFLOAT* zone, AbstractDisplay* bar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fBar(bar) { fBar->setRange(lo, hi); fBar->setValue(lo); *fZone = lo; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fBar->setValue(v); } }; class uiNumEntry : public QObject, public uiItem { Q_OBJECT public : QDoubleSpinBox* fNumEntry; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; int fDecimals; uiNumEntry (GUI* ui, FAUSTFLOAT* zone, QDoubleSpinBox* numEntry, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fNumEntry(numEntry), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fDecimals = (fStep >= 1.0) ? 0 : int(0.5+log10(1.0/fStep)); fNumEntry->setMinimum(fMin); fNumEntry->setMaximum(fMax); fNumEntry->setSingleStep(fStep); fNumEntry->setDecimals(fDecimals); fNumEntry->setValue(fCur); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fNumEntry->setValue(v); } public slots : void setValue(double v) { modifyZone(FAUSTFLOAT(v)); } }; /****************************************************************************** ******************************************************************************* IMPLEMENTATION OF THE USER INTERFACE (QT 4.3 for FAUST) ******************************************************************************* *******************************************************************************/ class QTGUI : public QObject, public GUI { Q_OBJECT QApplication fAppl; QTimer* fTimer; QStyle* fStyle; string gGroupTooltip; stack fGroupStack; map fGuiSize; // map widget zone with widget size coef map fTooltip; // map widget zone with tooltip strings map fUnit; // map widget zone to unit string (i.e. "dB") set fKnobSet; // set of widget zone to be knobs set fLedSet; // set of widget zone to be LEDs /** * Format tooltip string by replacing some white spaces by * return characters so that line width doesn't exceed n. * Limitation : long words exceeding n are not cut */ virtual string formatTooltip(int n, const string& tt) { string ss = tt; // ss string we are going to format int lws = 0; // last white space encountered int lri = 0; // last return inserted for (int i=0; i< (int)tt.size(); i++) { if (tt[i] == ' ') lws = i; if (((i-lri) >= n) && (lws > lri)) { // insert return here ss[lws] = '\n'; lri = lws; } } return ss; } /** * Analyses the widget zone metadata declarations and takes * appropriate actions */ virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value) { if (zone == 0) { // special zone 0 means group metadata if (strcmp(key,"tooltip")==0) { // only group tooltip are currently implemented gGroupTooltip = formatTooltip(30, value); } } else { if (strcmp(key,"size")==0) { fGuiSize[zone]=atof(value); } else if (strcmp(key,"tooltip")==0) { fTooltip[zone] = formatTooltip(30, value) ; } else if (strcmp(key,"unit")==0) { fUnit[zone] = value ; } else if (strcmp(key,"style")==0) { // else if ((strcmp(key,"style")==0) || (strcmp(key,"type")==0)) { if (strcmp(value,"knob") == 0) { fKnobSet.insert(zone); } else if (strcmp(value,"led") == 0) { fLedSet.insert(zone); } } } } bool isTabContext() { //return fGroupStack.empty() || ((!fGroupStack.empty()) && (dynamic_cast(fGroupStack.top()) != 0)); return ((!fGroupStack.empty()) && (dynamic_cast(fGroupStack.top()) != 0)); } void insert(const char* label, QWidget* widget) { if (fStyle) widget->setStyle(fStyle); if (!fGroupStack.empty()) { QWidget* mother = fGroupStack.top(); QTabWidget* tab = dynamic_cast(mother); if (tab) { tab->addTab(widget,label); } else { widget->setParent(mother); mother->layout()->addWidget(widget); } } } /** * Analyses a full label and activates the relevant options. returns a simplified * label (without options) and an amount of stack adjustement (in case additional * containers were pushed on the stack). */ int checkLabelOptions(QWidget* widget, const string& fullLabel, string& simplifiedLabel) { map metadata; extractMetadata(fullLabel, simplifiedLabel, metadata); if (metadata.count("tooltip")) { widget->setToolTip(metadata["tooltip"].c_str()); } if (metadata["option"] == "detachable") { //openHandleBox(simplifiedLabel.c_str()); return 1; } // no adjustement of the stack needed return 0; } /** * Check if a tooltip is associated to a zone and add it to the corresponding widget */ void checkForTooltip(FAUSTFLOAT* zone, QWidget* widget) { if (fTooltip.count(zone)) { widget->setToolTip(fTooltip[zone].c_str()); } } /** * Check if a knob is required */ bool isKnob(FAUSTFLOAT* zone) { return fKnobSet.count(zone) > 0; } void openBox(const char* fulllabel, QLayout* layout) { map metadata; string label; extractMetadata(fulllabel, label, metadata); layout->setMargin(5); QWidget* box; if (isTabContext()) { box = new QWidget(); // set background color QPalette pal = box->palette(); pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150) ); box->setPalette(pal); } else if (label.size()>0) { QGroupBox* group = new QGroupBox(); group->setTitle(label.c_str()); box = group; } else { // no label here we use simple widget layout->setMargin(0); box = new QWidget(); } box->setLayout(layout); /* if (metadata.count("tooltip")) { box->setToolTip(metadata["tooltip"].c_str()); }*/ if (gGroupTooltip != string()) { box->setToolTip(gGroupTooltip.c_str()); gGroupTooltip = string(); } insert(label.c_str(), box); fGroupStack.push(box); } void openTab(const char* label) { QTabWidget* group = new QTabWidget(); if (fStyle) group->setStyle(fStyle); insert(label, group); fGroupStack.push(group); } public slots : void update() { //std::cout << '.' << std::endl; updateAllZones(); } public: QTGUI(int &argc, char* argv[], QStyle* style = 0) : fAppl(argc, argv), fTimer(0), fStyle(style){ //fGroupStack.push(new QMainWindow()); } virtual ~QTGUI() {} virtual void run() { if (fTimer == 0) { fTimer = new QTimer(this); QObject::connect(fTimer, SIGNAL(timeout()), this, SLOT(update())); fTimer->start(100); } #if 0 fAppl.setStyleSheet( // BUTTONS "QPushButton {" "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," "stop: 0 #B0B0B0, stop: 1 #404040);" "border: 2px solid grey;" "border-radius: 6px;" "margin-top: 1ex;" "}" "QPushButton:hover {" "border: 2px solid orange;" "}" "QPushButton:pressed {" //"border: 1px solid orange;" "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #404040, stop: 1 #B0B0B0);" "}" // GROUPS "QGroupBox {" "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," "stop: 0 #A0A0A0, stop: 1 #202020);" "border: 2px solid gray;" "border-radius: 5px;" "margin-top: 3ex;" "font-size:10pt;" "font-weight:bold;" //"color: dark grey;" "color: white;" "}" "QGroupBox::title {" "subcontrol-origin: margin;" "subcontrol-position: top center;" /* position at the top center */ "padding: 0 5px;" "}" // SLIDERS // horizontal sliders "QSlider::groove:vertical {" "background: red;" "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ "left: 13px; right: 13px;" "}" "QSlider::handle:vertical {" "height: 40px;" "width: 30px;" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" "margin: 0 -5px; /* expand outside the groove */" "border-radius: 5px;" "}" "QSlider::add-page:vertical {" "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 yellow, stop : 0.5 orange);" "}" "QSlider::sub-page:vertical {" "background: grey;" "}" // horizontal sliders "QSlider::groove:horizontal {" "background: red;" "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ "top: 14px; bottom: 14px;" "}" "QSlider::handle:horizontal {" "width: 40px;" "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" "margin: -5px 0; /* expand outside the groove */" "border-radius: 5px;" "}" "QSlider::sub-page:horizontal {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 yellow, stop : 0.5 orange);" "}" "QSlider::add-page:horizontal {" "background: grey;" "}" // TABS //TabWidget and TabBar "QTabWidget::pane {" /* The tab widget frame */ //"border-top: 2px solid #C2C7CB;" "border-top: 2px solid orange;" "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #A0A0A0, stop: 1 #202020);" "}" "QTabWidget::tab-bar {" "left: 5px;" /* move to the right by 5px */ "}" /* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */ "QTabBar::tab {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #909090, stop: 0.4 #888888," "stop: 0.5 #808080, stop: 1.0 #909090);" "border: 2px solid #808080;" //"border-bottom-color: #C2C7CB;" /* same as the pane color */ "border-bottom-color: orange;" /* same as the pane color */ "border-top-left-radius: 4px;" "border-top-right-radius: 4px;" "min-width: 8ex;" "padding: 2px;" "}" "QTabBar::tab:selected, QTabBar::tab:hover {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #D0D0D0, stop: 0.4 #A0A0A0," "stop: 0.5 #808080, stop: 1.0 #A0A0A0);" //"stop: 0.5 #A0A0A0, stop: 1.0 #C0C0C0);" //"stop: 0 #fafafa, stop: 0.4 #f4f4f4," //"stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);" //"border-bottom-color: orange;" /* same as the pane color */ "}" "QTabBar::tab:selected {" "border-color: orange;" "border-bottom-color: #A0A0A0;" /* same as pane color */ "}" "QTabBar::tab:!selected {" " margin-top: 2px;" /* make non-selected tabs look smaller */ "}" ); #endif fAppl.exec(); stop(); } // ------------------------- Groups ----------------------------------- virtual void openHorizontalBox(const char* label) { openBox(label, new QHBoxLayout()); } virtual void openVerticalBox(const char* label) { openBox(label, new QVBoxLayout()); } virtual void openFrameBox(const char* ) { } virtual void openTabBox(const char* label) { openTab(label); } virtual void closeBox() { QWidget* group = fGroupStack.top(); fGroupStack.pop(); if (fGroupStack.empty()) { group->show(); group->adjustSize();} } // ------------------------- active widgets ----------------------------------- virtual void addButton(const char* label, FAUSTFLOAT* zone) { QAbstractButton* w = new QPushButton(label); uiButton* c = new uiButton(this, zone, w); insert(label, w); QObject::connect(w, SIGNAL(pressed()), c, SLOT(pressed())); QObject::connect(w, SIGNAL(released()), c, SLOT(released())); checkForTooltip(zone, w); } virtual void addToggleButton(const char*, FAUSTFLOAT*) {} virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { QCheckBox* w = new QCheckBox(label); uiCheckButton* c = new uiCheckButton(this, zone, w); insert(label, w); QObject::connect(w, SIGNAL(stateChanged(int)), c, SLOT(setState(int))); checkForTooltip(zone, w); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addVerticalKnob(label, zone, init, min, max, step); return; } //insert(label, new QDoubleSpinBox()); if (label && label[0]) openVerticalBox(label); QDoubleSpinBox* w = new QDoubleSpinBox(); uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); insert(label, w); w->setSuffix(fUnit[zone].c_str()); QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); if (label && label[0]) closeBox(); checkForTooltip(zone, w); } // special num entry without buttons virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { //insert(label, new QDoubleSpinBox()); if (label && label[0]) openVerticalBox(label); QDoubleSpinBox* w = new QDoubleSpinBox(); w->setAlignment(Qt::AlignHCenter); #if 1 w->setStyleSheet( "QDoubleSpinBox {" "border: 2px solid orange;" "border-radius: 5px;" "font-size: 8pt;" "}" ); #endif uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); insert(label, w); w->setButtonSymbols(QAbstractSpinBox::NoButtons); w->setSuffix(fUnit[zone].c_str()); QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); if (label && label[0]) closeBox(); checkForTooltip(zone, w); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // KNOBS // ////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void addVerticalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { openHorizontalBox(label); QAbstractSlider* w = new QDial(); //qsynthKnob(); uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); insert(label, w); w->setStyle(new qsynthDialVokiStyle()); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); // compute the size of the knob+display int width = int(64*pow(2,fGuiSize[zone])); int height = int(100*pow(2,fGuiSize[zone])); fGroupStack.top()->setMinimumSize(width,height); fGroupStack.top()->setMaximumSize(width,height); closeBox(); checkForTooltip(zone, w); } virtual void addHorizontalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { openHorizontalBox(label); QAbstractSlider* w = new QDial(); //new qsynthKnob(); uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); insert(label, w); w->setStyle(new qsynthDialVokiStyle()); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SLIDERS // ////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addVerticalKnob(label, zone, init, min, max, step); return; } openVerticalBox(label); QSlider* w = new QSlider(Qt::Vertical); w->setMinimumHeight(160); w->setMinimumWidth(34); //w->setTickPosition(QSlider::TicksBothSides); uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); insert(label, w); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addHorizontalKnob(label, zone, init, min, max, step); return; } openHorizontalBox(label); QSlider* w = new QSlider(Qt::Horizontal); w->setMinimumHeight(34); w->setMinimumWidth(160); //w->setTickPosition(QSlider::TicksBothSides); uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); insert(label, w); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } // ------------------------- passive widgets ----------------------------------- virtual void addNumDisplay(const char*, FAUSTFLOAT*, int) {} virtual void addTextDisplay(const char*, FAUSTFLOAT*, const char* [], FAUSTFLOAT, FAUSTFLOAT) {} virtual void addHorizontalBargraph(const char* label , FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { AbstractDisplay* bargraph; openVerticalBox(label); bool db = (fUnit[zone] == "dB"); if (fLedSet.count(zone)) { if (db) { bargraph = new dbLED(min, max); } else { bargraph = new LED(min,max); } } else { if (db) { bargraph = new dbHorizontalBargraph(min, max); } else { bargraph = new linHorizontalBargraph(min, max); } } new uiBargraph2(this, zone, bargraph, min, max); insert(label, bargraph); closeBox(); checkForTooltip(zone, bargraph); } virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { AbstractDisplay* bargraph; openVerticalBox(label); bool db = (fUnit[zone] == "dB"); if (fLedSet.count(zone)) { if (db) { bargraph = new dbLED(min, max); } else { bargraph = new LED(min,max); } } else { if (db) { bargraph = new dbVerticalBargraph(min, max); } else { bargraph = new linVerticalBargraph(min, max); } } new uiBargraph2(this, zone, bargraph, min, max); insert(label, bargraph); closeBox(); checkForTooltip(zone, bargraph); } }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/httpdUI.h000066400000000000000000000075371210074205700271720ustar00rootroot00000000000000/* Copyright (C) 2012 Grame - Lyon All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted. */ #ifndef __httpdUI__ #define __httpdUI__ #include "faust/gui/HTTPDControler.h" #include "faust/gui/GUI.h" /****************************************************************************** ******************************************************************************* HTTPD USER INTERFACE ******************************************************************************* *******************************************************************************/ /* Note about URLs and the Faust UI names: ---------------------------------------------------- Characters in a url could be: 1. Reserved: ; / ? : @ & = + $ , These characters delimit URL parts. 2. Unreserved: alphanum - _ . ! ~ * ' ( ) These characters have no special meaning and can be used as is. 3. Excluded: control characters, space, < > # % ", { } | \ ^ [ ] ` To solve potential conflicts between the Faust UI objects naming scheme and the URL allowed characters, the reserved and excluded characters are replaced with '-' (hyphen). Space or tabulation are replaced with '_' (underscore) */ using namespace std; class httpdUI : public UI { httpdfaust::HTTPDControler* fCtrl; const char* tr(const char* label) const; public: httpdUI(const char* applicationname, int argc, char *argv[]) { fCtrl = new httpdfaust::HTTPDControler(argc, argv, applicationname); } virtual ~httpdUI() { delete fCtrl; } // -- widget's layouts virtual void openTabBox(const char* label) { fCtrl->opengroup( "tgroup", tr(label)); } virtual void openHorizontalBox(const char* label) { fCtrl->opengroup( "hgroup", tr(label)); } virtual void openVerticalBox(const char* label) { fCtrl->opengroup( "vgroup", tr(label)); } virtual void closeBox() { fCtrl->closegroup(); } // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) { fCtrl->addnode( "button", tr(label), zone); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { fCtrl->addnode( "checkbox", tr(label), zone); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "vslider", tr(label), zone, init, min, max, step); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "hslider", tr(label), zone, init, min, max, step); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "nentry", tr(label), zone, init, min, max, step); } // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fCtrl->addnode( "hbargraph", tr(label), zone, min, max); } virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fCtrl->addnode( "vbargraph", tr(label), zone, min, max); } virtual void declare (FAUSTFLOAT* , const char* key, const char* val ) { fCtrl->declare(key, val); } void run() { fCtrl->run(); } }; const char* httpdUI::tr(const char* label) const { static char buffer[1024]; char * ptr = buffer; int n=1; while (*label && (n++ < 1024)) { switch (*label) { case ' ': case ' ': *ptr++ = '_'; break; case ';': case '/': case '?': case ':': case '@': case '&': case '=': case '+': case '$': case ',': case '<': case '>': case '#': case '%': case '"': case '{': case '}': case '|': case '\\': case '^': case '[': case ']': case '`': *ptr++ = '_'; break; default: *ptr++ = *label; } label++; } *ptr = 0; return buffer; } #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/meta.h000066400000000000000000000023451210074205700265270ustar00rootroot00000000000000/************************************************************************ ************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . ************************************************************************ ************************************************************************/ #ifndef __meta__ #define __meta__ struct Meta { virtual void declare(const char* key, const char* value) = 0; }; #endif radium_compressor-0.5.1/audio/faudiostream/architecture/faust/gui/mocfaustqt.cpp000066400000000000000000000324171210074205700303250ustar00rootroot00000000000000/**************************************************************************** ** Meta object code from reading C++ file 'faustqt.h' ** ** Created: Fri Feb 25 08:07:38 2011 ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include "faustqt.h" #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'faustqt.h' doesn't include ." #elif Q_MOC_OUTPUT_REVISION != 62 #error "This file was generated using the moc from 4.7.0. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE static const uint qt_meta_data_uiButton[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 2, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 10, 9, 9, 9, 0x0a, 20, 9, 9, 9, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiButton[] = { "uiButton\0\0pressed()\0released()\0" }; const QMetaObject uiButton::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiButton, qt_meta_data_uiButton, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiButton::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiButton::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiButton::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiButton)) return static_cast(const_cast< uiButton*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiButton*>(this)); return QObject::qt_metacast(_clname); } int uiButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: pressed(); break; case 1: released(); break; default: ; } _id -= 2; } return _id; } static const uint qt_meta_data_uiCheckButton[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 17, 15, 14, 14, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiCheckButton[] = { "uiCheckButton\0\0v\0setState(int)\0" }; const QMetaObject uiCheckButton::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiCheckButton, qt_meta_data_uiCheckButton, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiCheckButton::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiCheckButton::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiCheckButton::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiCheckButton)) return static_cast(const_cast< uiCheckButton*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiCheckButton*>(this)); return QObject::qt_metacast(_clname); } int uiCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setState((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiSlider[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 12, 10, 9, 9, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiSlider[] = { "uiSlider\0\0v\0setValue(int)\0" }; const QMetaObject uiSlider::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiSlider, qt_meta_data_uiSlider, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiSlider::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiSlider::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiSlider::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiSlider)) return static_cast(const_cast< uiSlider*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiSlider*>(this)); return QObject::qt_metacast(_clname); } int uiSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiKnob[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 10, 8, 7, 7, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiKnob[] = { "uiKnob\0\0v\0setValue(int)\0" }; const QMetaObject uiKnob::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiKnob, qt_meta_data_uiKnob, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiKnob::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiKnob::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiKnob::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiKnob)) return static_cast(const_cast< uiKnob*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiKnob*>(this)); return QObject::qt_metacast(_clname); } int uiKnob::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiBargraph[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; static const char qt_meta_stringdata_uiBargraph[] = { "uiBargraph\0" }; const QMetaObject uiBargraph::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph, qt_meta_data_uiBargraph, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiBargraph::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiBargraph::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiBargraph::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiBargraph)) return static_cast(const_cast< uiBargraph*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiBargraph*>(this)); return QObject::qt_metacast(_clname); } int uiBargraph::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; return _id; } static const uint qt_meta_data_uiBargraph2[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; static const char qt_meta_stringdata_uiBargraph2[] = { "uiBargraph2\0" }; const QMetaObject uiBargraph2::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph2, qt_meta_data_uiBargraph2, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiBargraph2::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiBargraph2::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiBargraph2::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiBargraph2)) return static_cast(const_cast< uiBargraph2*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiBargraph2*>(this)); return QObject::qt_metacast(_clname); } int uiBargraph2::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; return _id; } static const uint qt_meta_data_uiNumEntry[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 14, 12, 11, 11, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiNumEntry[] = { "uiNumEntry\0\0v\0setValue(double)\0" }; const QMetaObject uiNumEntry::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiNumEntry, qt_meta_data_uiNumEntry, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiNumEntry::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiNumEntry::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiNumEntry::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiNumEntry)) return static_cast(const_cast< uiNumEntry*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiNumEntry*>(this)); return QObject::qt_metacast(_clname); } int uiNumEntry::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< double(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_QTGUI[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 7, 6, 6, 6, 0x0a, 0 // eod }; static const char qt_meta_stringdata_QTGUI[] = { "QTGUI\0\0update()\0" }; const QMetaObject QTGUI::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_QTGUI, qt_meta_data_QTGUI, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &QTGUI::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *QTGUI::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *QTGUI::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_QTGUI)) return static_cast(const_cast< QTGUI*>(this)); if (!strcmp(_clname, "UI")) return static_cast< UI*>(const_cast< QTGUI*>(this)); return QObject::qt_metacast(_clname); } int QTGUI::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: update(); break; default: ; } _id -= 1; } return _id; } QT_END_MOC_NAMESPACE radium_compressor-0.5.1/audio/system_compressor.cpp000066400000000000000000000261031210074205700226570ustar00rootroot00000000000000//----------------------------------------------------- // // Code generated with Faust 0.9.46 (http://faust.grame.fr) //----------------------------------------------------- #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif typedef long double quad; /* link with : "" */ #include "typepunning.h" #include #define FAUSTCLASS mydsp class mydsp : public dsp { private: FAUSTFLOAT fcheckbox0; int iConst0; float fConst1; FAUSTFLOAT fslider0; float fRec2_perm[4]; FAUSTFLOAT fslider1; float fRec1_perm[4]; float fConst2; FAUSTFLOAT fslider2; FAUSTFLOAT fbargraph0; FAUSTFLOAT fslider3; FAUSTFLOAT fbargraph1; float fRec0_perm[4]; FAUSTFLOAT fslider4; public: static void metadata(Meta* m) { m->declare("filter.lib/name", "Faust Filter Library"); m->declare("filter.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)"); m->declare("filter.lib/copyright", "Julius O. Smith III"); m->declare("filter.lib/version", "1.29"); m->declare("filter.lib/license", "STK-4.3"); m->declare("filter.lib/reference", "https://ccrma.stanford.edu/~jos/filters/"); m->declare("music.lib/name", "Music Library"); m->declare("music.lib/author", "GRAME"); m->declare("music.lib/copyright", "GRAME"); m->declare("music.lib/version", "1.0"); m->declare("music.lib/license", "LGPL"); m->declare("math.lib/name", "Math Library"); m->declare("math.lib/author", "GRAME"); m->declare("math.lib/copyright", "GRAME"); m->declare("math.lib/version", "1.0"); m->declare("math.lib/license", "LGPL"); m->declare("effect.lib/name", "Faust Audio Effect Library"); m->declare("effect.lib/author", "Julius O. Smith (jos at ccrma.stanford.edu)"); m->declare("effect.lib/copyright", "Julius O. Smith III"); m->declare("effect.lib/version", "1.33"); m->declare("effect.lib/license", "STK-4.3"); m->declare("effect.lib/reference", "https://ccrma.stanford.edu/realsimple/faust_strings/"); } virtual int getNumInputs() { return 2; } virtual int getNumOutputs() { return 2; } static void classInit(int samplingFreq) { } virtual void instanceInit(int samplingFreq) { fSamplingFreq = samplingFreq; fcheckbox0 = 0.0; iConst0 = min(192000, max(1, fSamplingFreq)); fConst1 = (1.0f / iConst0); fslider0 = 100.237f; for (int i=0; i<4; i++) fRec2_perm[i]=0; fslider1 = 50.148f; for (int i=0; i<4; i++) fRec1_perm[i]=0; fConst2 = (2.0f / iConst0); fslider2 = -2e+01f; fslider3 = 2.0f; for (int i=0; i<4; i++) fRec0_perm[i]=0; fslider4 = 0.0f; } virtual void init(int samplingFreq) { classInit(samplingFreq); instanceInit(samplingFreq); } virtual void buildUserInterface(UI* interface) { interface->openVerticalBox("system_compressor"); interface->declare(&fslider3, "0", ""); interface->declare(&fslider3, "style", "slider"); interface->declare(&fslider3, "tooltip", "A compression Ratio of N means that for each N dB increase in input signal level above Threshold, the output level goes up 1 dB"); interface->addHorizontalSlider("Ratio", &fslider3, 2.0f, 1.0f, 2e+01f, 0.1f); interface->declare(&fslider2, "1", ""); interface->declare(&fslider2, "style", "slider"); interface->declare(&fslider2, "tooltip", "When the signal level exceeds the Threshold (in dB), its level is compressed according to the Ratio"); interface->declare(&fslider2, "unit", "dB"); interface->addHorizontalSlider("Threshold", &fslider2, -2e+01f, -2e+01f, 2e+01f, 0.1f); interface->declare(&fslider1, "2", ""); interface->declare(&fslider1, "style", "slider"); interface->declare(&fslider1, "tooltip", "Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new lower target level (the compression `kicking in')"); interface->declare(&fslider1, "unit", "ms"); interface->addHorizontalSlider("Attack", &fslider1, 50.148f, 0.0f, 5e+02f, 0.1f); interface->declare(&fslider0, "3", ""); interface->declare(&fslider0, "style", "slider"); interface->declare(&fslider0, "tooltip", "Time constant in ms (1/e smoothing time) for the compression gain to approach (exponentially) a new higher target level (the compression 'releasing')"); interface->declare(&fslider0, "unit", "ms"); interface->addHorizontalSlider("Release", &fslider0, 100.237f, 0.0f, 1e+03f, 0.1f); interface->declare(&fslider4, "5", ""); interface->declare(&fslider4, "tooltip", "The compressed-signal output level is increased by this amount (in dB) to make up for the level lost due to compression"); interface->declare(&fslider4, "unit", "dB"); interface->addHorizontalSlider("Output Gain", &fslider4, 0.0f, -4e+01f, 4e+01f, 0.1f); interface->declare(&fcheckbox0, "6", ""); interface->addCheckButton("bypass", &fcheckbox0); interface->declare(&fbargraph0, "0", ""); interface->declare(&fbargraph0, "7", ""); interface->addHorizontalBargraph("Gakk", &fbargraph0, -5e+01f, 1e+01f); interface->declare(&fbargraph1, "1", ""); interface->declare(&fbargraph1, "7", ""); interface->addHorizontalBargraph("Gakk", &fbargraph1, -5e+01f, 1e+01f); interface->closeBox(); } virtual void compute (int fullcount, FAUSTFLOAT** input, FAUSTFLOAT** output) { float fZec0[32]; float fZec1[32]; float fZec2[32]; float fRec2_tmp[32+4]; float fRec1_tmp[32+4]; float fZec3[32]; float fZec4[32]; float fRec0_tmp[32+4]; float fZec5[32]; int iSlow0 = int(fcheckbox0); float fSlow1 = expf((0 - (fConst1 / max(fConst1, (0.001f * fslider0))))); float fSlow2 = (1.0f - fSlow1); float* fRec2 = &fRec2_tmp[4]; float fSlow3 = max(fConst1, (0.001f * fslider1)); float fSlow4 = expf((0 - (fConst1 / fSlow3))); float fSlow5 = (1.0f - fSlow4); float* fRec1 = &fRec1_tmp[4]; float fSlow6 = expf((0 - (fConst2 / fSlow3))); float fSlow7 = fslider2; float fSlow8 = ((1.0f / float(fslider3)) - 1.0f); float fSlow9 = (1.0f - fSlow6); float* fRec0 = &fRec0_tmp[4]; float fSlow10 = powf(10,(0.05f * fslider4)); int index; for (index = 0; index <= fullcount - 32; index += 32) { // compute by blocks of 32 samples const int count = 32; FAUSTFLOAT* input0 = &input[0][index]; FAUSTFLOAT* input1 = &input[1][index]; FAUSTFLOAT* output0 = &output[0][index]; FAUSTFLOAT* output1 = &output[1][index]; // SECTION : 1 // LOOP 0x2a67980 // exec code for (int i=0; imin_db, 0.0, select2(x>min_linear_db, scale(x, min_db, min_linear_db, 0.0, db2linear(min_linear_db)), select2(xmin_linear, min_db, select2(x>min_linear_linear, scale(x, 0.0, min_linear_db, min_linear, min_linear_linear), select2(x 1! }; compressor_stereo(ratio,thresh,att,rel,x,y) = cgm*x, cgm*y with { cgm = compression_gain_mono(ratio,thresh,att,rel,abs(x)+abs(y)); }; compressor_stereo_demo = effect.bypass2(checkbox("[6] bypass"), compressor) with{ compressor = (_,_) //: *(ingain), *(ingain) // : displaygain(0) : compressor_stereo(ratio,threshold,attack,release) // : displaygain(1) : *(outgain), *(outgain) // : displaygain(2) ; }; process = compressor_stereo_demo; //(x,0) : (_,!); radium_compressor-0.5.1/audio/typepunning.h000066400000000000000000000020151210074205700211000ustar00rootroot00000000000000/* Copyright 2013 Kjetil S. Matheussen 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. */ #ifndef AUDIO_TYPEPUNNING_H #define AUDIO_TYPEPUNNING_H #include static inline int pun_float_to_int(float x){ union { float f; uint32_t i; } vx = { x }; return vx.i; } static inline float pun_int_to_float(int x){ union { uint32_t i; float f; } mx = { .i=(uint32_t)x }; return mx.f; } #endif radium_compressor-0.5.1/audio/undo_audio_effect_proc.h000066400000000000000000000014501210074205700232070ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ extern LANGSPEC void Undo_AudioEffect_CurrPos(struct Patch *patch, int effect_num); radium_compressor-0.5.1/benchmark.cpp000066400000000000000000000000441210074205700177040ustar00rootroot00000000000000#include "compressor_benchmark.cpp" radium_compressor-0.5.1/common/000077500000000000000000000000001210074205700165405ustar00rootroot00000000000000radium_compressor-0.5.1/common/OS_Semaphores.h000077500000000000000000000030641210074205700214260ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ struct _RSemaphore; typedef struct _RSemaphore RSemaphore; // waiters/signallers??? It's not complicated: // num_signallers == -num_waiters // num_waiters == -num_signallers extern LANGSPEC RSemaphore *RSEMAPHORE_create(int num_signallers); extern LANGSPEC void RSEMAPHORE_delete(RSemaphore *semaphore); extern LANGSPEC void RSEMAPHORE_reset(RSemaphore *semaphore); extern LANGSPEC void RSEMAPHORE_set_num_waiters(RSemaphore *semaphore, int num_waiters); extern LANGSPEC void RSEMAPHORE_get_num_waiters(RSemaphore *semaphore); extern LANGSPEC void RSEMAPHORE_set_num_signallers(RSemaphore *semaphore, int num_signallers); extern LANGSPEC void RSEMAPHORE_get_num_signallers(RSemaphore *semaphore); extern LANGSPEC void RSEMAPHORE_wait(RSemaphore *semaphore, int num_waiters); extern LANGSPEC void RSEMAPHORE_signal(RSemaphore *semaphore, int num_signallers); radium_compressor-0.5.1/common/OS_error_proc.h000077500000000000000000000016371210074205700215000ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #ifndef TRACKER_INCLUDE extern bool Error_init(void); extern LANGSPEC void RError(const char *fmt,...); extern LANGSPEC void RWarning(const char *fmt,...); extern void Error_uninit(void); #endif radium_compressor-0.5.1/common/OS_visual_input.h000077500000000000000000000074271210074205700220510ustar00rootroot00000000000000/* Copyright 2003 Kjetil S. Matheussen 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. */ extern LANGSPEC void GFX_ConfigSystemFont(void); //extern LANGSPEC char *GFX_SelectEditFont(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_ResetFontSize(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_IncFontSize(struct Tracker_Windows *tvisual, int pixels); extern LANGSPEC void GFX_SetDefaultFont(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_SetDefaultSystemFont(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_SetStatusBar(struct Tracker_Windows *tvisual,const char *title); extern LANGSPEC void GFX_SetWindowTitle(struct Tracker_Windows *tvisual,const char *title); extern LANGSPEC void SetNormalPointer(struct Tracker_Windows *tvisual); extern LANGSPEC void SetResizePointer(struct Tracker_Windows *tvisual); // Note that For the ReqType functions, tvisual might be NULL. The reasons is that it can be called when loading, or when starting up. extern LANGSPEC ReqType GFX_OpenReq(struct Tracker_Windows *tvisual,int width,int height,const char *title); extern LANGSPEC void GFX_CloseReq(struct Tracker_Windows *tvisual,ReqType reqtype); extern LANGSPEC void GFX_WriteString(ReqType reqtype,const char *text); extern LANGSPEC void GFX_ReadString(ReqType reqtype,char *buffer,int bufferlength); extern LANGSPEC int GFX_ReqTypeMenu( struct Tracker_Windows *tvisual, ReqType reqtype, const char *seltext, vector_t *v ); extern LANGSPEC int GFX_GetInteger(struct Tracker_Windows *tvisual,ReqType reqtype,char *text,int min,int max); extern LANGSPEC float GFX_GetFloat(struct Tracker_Windows *tvisual,ReqType reqtype,char *text,float min,float max); extern LANGSPEC char *GFX_GetString(struct Tracker_Windows *tvisual,ReqType reqtype,char *text); extern LANGSPEC int GFX_Menu( struct Tracker_Windows *tvisual, ReqType reqtype, const char *seltext, vector_t *v ); extern LANGSPEC const char *GFX_GetLoadFileName( struct Tracker_Windows *tvisual, ReqType reqtype, char *seltext, char *dir ); extern LANGSPEC const char *GFX_GetSaveFileName( struct Tracker_Windows *tvisual, ReqType reqtype, char *seltext, char *dir ); extern LANGSPEC void GFX_OS_UpdateKeyOctave(void); extern LANGSPEC void OS_GFX_NumUndosHaveChanged(int num_undos, bool redos_are_available); extern LANGSPEC void OS_GFX_SetVolume(int value); extern LANGSPEC void GFX_update_instrument_patch_gui(struct Patch *patch); extern LANGSPEC void GFX_remove_patch_gui(struct Patch *patch); // Also deletes the audio object itself. (yes, it's messy) extern LANGSPEC float *OS_SLIDER_obtain_automation_value_pointer(struct Patch *patch,int effect_num); extern LANGSPEC int *OS_SLIDER_obtain_automation_color_pointer(struct Patch *patch,int effect_num); extern LANGSPEC void OS_SLIDER_release_automation_pointers(struct Patch *patch,int effect_num); extern LANGSPEC float *GFX_OS_get_system_volume_peak_pointers(int num_channels); extern LANGSPEC void GFX_update_all_instrument_widgets(void); extern LANGSPEC void GFX_PP_Update(struct Patch *patch); extern LANGSPEC const char *OS_get_resolved_file_path(const char *path); extern LANGSPEC void OS_VST_config(struct Tracker_Windows *window); radium_compressor-0.5.1/common/debug_proc.h000077500000000000000000000015571210074205700210350ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #include extern char debugg[]; extern void debug(const char *fmt, ...); extern void Pdebug(const char *fmt, ...); extern void DoPdebug(void); radium_compressor-0.5.1/common/hashmap_proc.h000066400000000000000000000060371210074205700213630ustar00rootroot00000000000000/* Copyright 2012 Kjetil S. Matheussen 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. */ #ifndef HASHMAP_PROC_H #define HASHMAP_PROC_H // Warning: Writing two elements with the same key to the same hash table just adds two elements with the same key into the table. // Nothing is ever deleted from the tables. // A key can not contain lineshift since lineshifts are used as delimiter character when loading/saving. extern LANGSPEC hash_t *HASH_create(int approx_size); extern LANGSPEC bool HASH_has_key(hash_t *hash, const char *key); extern LANGSPEC int HASH_get_num_elements(hash_t *hash); extern LANGSPEC hash_t *HASH_get_keys(hash_t *hash); // Returns all keys in a new hash array. // HASH_put_*: char *key is not copied. I.e. the key is used directly, not a copy of it. // HASH_put_string: A copy of char *val is used, not val itself. extern LANGSPEC void HASH_put_string(hash_t *hash, const char *key, const char *val); extern LANGSPEC void HASH_put_int(hash_t *hash, const char *key, int64_t val); extern LANGSPEC void HASH_put_float(hash_t *hash, const char *key, double val); extern LANGSPEC void HASH_put_hash(hash_t *hash, const char *key, hash_t *val); extern LANGSPEC const char *HASH_get_string(hash_t *hash, const char *key); extern LANGSPEC int64_t HASH_get_int(hash_t *hash, const char *key); extern LANGSPEC double HASH_get_float(hash_t *hash, const char *key); extern LANGSPEC hash_t *HASH_get_hash(hash_t *hash, const char *key); // Array interface extern LANGSPEC int HASH_get_array_size(hash_t *hash); extern LANGSPEC void HASH_put_string_at(hash_t *hash, int i, const char *val); extern LANGSPEC void HASH_put_int_at(hash_t *hash, int i, int64_t val); extern LANGSPEC void HASH_put_float_at(hash_t *hash, int i, double val); extern LANGSPEC void HASH_put_hash_at(hash_t *hash, int i, hash_t *val); extern LANGSPEC const char *HASH_get_string_at(hash_t *hash, int i); extern LANGSPEC int64_t HASH_get_int_at(hash_t *hash, int i); extern LANGSPEC double HASH_get_float_at(hash_t *hash, int i); extern LANGSPEC hash_t *HASH_get_hash_at(hash_t *hash, int i); // Loading and saving (serializing and deserializing to string. (The 'file' argument can be stdout for debugging)) extern LANGSPEC void HASH_save(hash_t *hash, FILE *file); extern LANGSPEC hash_t *HASH_load(FILE *file); // This function was used before the array interface was introduced. // extern LANGSPEC const char *HASH_get_int_hash(int i); #endif // HASHMAP_PROC_H radium_compressor-0.5.1/common/instruments_proc.h000077500000000000000000000024251210074205700223350ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ extern bool OpenInstruments(void); extern void CloseAllInstruments(void); extern void StopAllInstruments(void); extern void InitAllInstrumentsForPlaySongFromStart(void); extern LANGSPEC struct Instruments *get_all_instruments(void); extern LANGSPEC struct Instruments *get_default_instrument(void); extern LANGSPEC struct Instruments *get_MIDI_instrument(void); extern LANGSPEC struct Instruments *get_audio_instrument(void); extern LANGSPEC struct Instruments *get_instrument_from_type(int type); extern LANGSPEC int get_type_from_instrument(struct Instruments *instrument); radium_compressor-0.5.1/common/keyboard_sub_ids.h000066400000000000000000000026451210074205700222300ustar00rootroot00000000000000/* This file is automatically generated by bin/generate_keyboard_sub_ids.py */ #ifndef TRACKER_SUBIDS #define TRACKER_SUBIDS enum SubIds { EVENT_NO, EVENT_CTRL_L, EVENT_CTRL_R, EVENT_CAPS, EVENT_SHIFT_L, EVENT_SHIFT_R, EVENT_ALT_L, EVENT_ALT_R, EVENT_EXTRA_L, EVENT_EXTRA_R, EVENT_UP, EVENT_FIRST_NON_QUALIFIER, EVENT_ESC, EVENT_F1, EVENT_F2, EVENT_F3, EVENT_F4, EVENT_F5, EVENT_F6, EVENT_F7, EVENT_F8, EVENT_F9, EVENT_F10, EVENT_F11, EVENT_F12, EVENT_F13, EVENT_F14, EVENT_F15, EVENT_F16, EVENT_F20, EVENT_1L1, EVENT_1, EVENT_2, EVENT_3, EVENT_4, EVENT_5, EVENT_6, EVENT_7, EVENT_8, EVENT_9, EVENT_0, EVENT_0R1, EVENT_0R2, EVENT_0R3, EVENT_BACKSPACE, EVENT_TAB, EVENT_Q, EVENT_W, EVENT_E, EVENT_R, EVENT_T, EVENT_Y, EVENT_U, EVENT_I, EVENT_O, EVENT_P, EVENT_PR1, EVENT_PR2, EVENT_RETURN, EVENT_A, EVENT_S, EVENT_D, EVENT_F, EVENT_G, EVENT_H, EVENT_J, EVENT_K, EVENT_L, EVENT_LR1, EVENT_LR2, EVENT_LR3, EVENT_ZL1, EVENT_Z, EVENT_X, EVENT_C, EVENT_V, EVENT_B, EVENT_N, EVENT_M, EVENT_MR1, EVENT_MR2, EVENT_MR3, EVENT_INSERT, EVENT_HOME, EVENT_PAGE_UP, EVENT_DEL, EVENT_END, EVENT_PAGE_DOWN, EVENT_DOWNARROW, EVENT_UPARROW, EVENT_RIGHTARROW, EVENT_LEFTARROW, EVENT_KP_E1, EVENT_KP_E2, EVENT_KP_DIV, EVENT_KP_MUL, EVENT_KP_SUB, EVENT_KP_ADD, EVENT_KP_0, EVENT_KP_DOT, EVENT_KP_ENTER, EVENT_KP_1, EVENT_KP_2, EVENT_KP_3, EVENT_KP_4, EVENT_KP_5, EVENT_KP_6, EVENT_KP_7, EVENT_KP_8, EVENT_KP_9, EVENT_SPACE, EVENT_DASMAX }; #endif //TRACKER_SUBIDS radium_compressor-0.5.1/common/memory_proc.h000077500000000000000000000027551210074205700212600ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #include #ifndef TRACKER_INCLUDE extern void init_memory(void); extern void tfree(void *element); extern LANGSPEC void *tracker_alloc_clean(size_t size,void *(*AllocFunction)(size_t size2)); extern LANGSPEC void *tracker_alloc(size_t size,void *(*AllocFunction)(size_t size2)); extern LANGSPEC void *tralloc(size_t size); extern LANGSPEC void *tralloc_atomic(size_t size); extern LANGSPEC void *talloc(size_t size); extern LANGSPEC void *talloc_atomic(size_t size); extern LANGSPEC void *talloc_atomic_uncollectable(size_t size); extern LANGSPEC void *talloc_realloc(void *v, size_t new_size); extern LANGSPEC char *talloc_strdup(const char *input); extern LANGSPEC char *talloc_numberstring(int number); extern LANGSPEC char *talloc_floatstring(float number); #endif radium_compressor-0.5.1/common/mouse.h000077500000000000000000000032041210074205700200430ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #ifndef TRACKER_MOUSE_H #define TRACKER_MOUSE_H #include "nsmtracker.h" struct MouseAction{ int action; int eint1; int eint2; int eint3; void *pointer1; void *pointer2; void *pointer3; void *pointer4; int (*MouseUpFunction)( struct Tracker_Windows *window, int x,int y ); }; // MouseAction actions: #define NOACTION 0 #define LEFTSLIDER 2 #define BOTTOMSLIDER 3 #define ZOOM 4 #define TRACKNAME 5 #define INSTRUMENTNAME 6 #define TEMPOLINE 7 #define TEMPONODE 8 #define NOTESTART 9 #define NOTEEND 10 #define VELLINE 11 #define VELNODE 12 #define FXNODE 13 #define FXLINE 14 #define NOTE 15 #define LEVELBORDER 16 #define LINEBORDER 17 #define LPBBORDER 18 #define TEMPOBORDER 19 #define TEMPONODEBORDER 20 #define FXBORDER 21 #define TRACKBORDER 22 #define VOLUMESLIDER 23 #define PANSLIDER 24 #define MAINBPM 25 #define MAINLPB 26 #define RELTEMPO 27 #define RELTEMPOSLIDER 28 #endif /* TRACKER_MOUSE_H */ radium_compressor-0.5.1/common/nsmtracker.h000077500000000000000000000600011210074205700210620ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ /****************************************************************** Main header file for the tracker. Each struct often has a source- file with the same, or nearly the same, name. Note, the file OS_Visual.h is OS spesific and must be put into the OS directory it belongs te. The other OS_*_proc.h files are not. ******************************************************************/ #ifndef TRACKER_DEFINE #define TRACKER_DEFINE 1 #ifdef __cplusplus # define LANGSPEC "C" #else # define LANGSPEC #endif #ifndef DEBUG # error "Missing DEBUG option. Edit the Makefile." #endif #if !USE_GTK_VISUAL && !USE_GTK_REQTYPE && !USE_GTK_MENU # define GTK_IS_USED 0 #else # define GTK_IS_USED 1 #endif #include #include #include #include #include #include "debug_proc.h" #include "memory_proc.h" #include "nsmtracker_events.h" #include "OS_error_proc.h" #include "OS_Semaphores.h" /* Unfortunately, AmigaOS has one absolute address that is legal to read from; 4, which often makes MuForce not to report reading from the wrong address (radiums fault, not MuFurces). By inserting SDB at all 4 offsets, we never read from 4 if a pointer is NULL. */ #ifdef SYSBASEDEBUG # define SDB int sysbasedebug; #else # define SDB #endif /* Next two lines must be placed in its own OS_depend file later. */ typedef uint32_t uint_32; /* A type that should be 64 bits, but may be 32 if 64 is _really_ slow or 64 is not available. */ /* uint_32 is allways loaded/saved as 64, and converted to 64 bit if uint_32 is 32 bit. */ #define MAX_UINT32 65534 /* Sqr(max(uint_32))-1 (rounded down)*/ //typedef int32_t STime; /* Time can be negative. */ typedef int64_t STime; /* Time can be negative. */ //typedef STime NInt; typedef int32_t NInt; //#define PFREQ (48000*8) /* Subseconds for STime */ /* Replaced by samplerate */ //#define LATENCY (PFREQ/200) #define LATENCY 0 // Dont need this when the player is called from the jack thread. #define MAXBLOCKRELTIME 6.0f #define MINBLOCKRELTIME 0.001f // Higher than 255 is no point. #define MAX_BRIGHTNESS 63 enum{ PAINT_DIRECTLY = 0, PAINT_BUFFER = 1 }; #include #define R_MAX(a,b) (((a)>(b))?(a):(b)) #define R_MIN(a,b) (((a)<(b))?(a):(b)) #define R_ABS(a) ((a)<0?(-(a)):(a)) #define R_BOUNDARIES(a,b,c) (R_MIN(R_MAX((a),(b)),(c))) static inline float scale(float x, float x1, float x2, float y1, float y2){ return y1 + ( ((x-x1)*(y2-y1)) / (x2-x1) ); } /********************************************************************* placement.h *********************************************************************/ struct Placement{ int line; SDB uint_32 counter; uint_32 dividor; }; typedef struct Placement Place; /********************************************************************* list.h *********************************************************************/ struct ListHeader1{ struct ListHeader1 *next; SDB NInt num; }; struct ListHeader3{ struct ListHeader3 *next; SDB Place p; }; #define Tline l.p.line #define Tcounter l.p.counter #define Tdividor l.p.dividor struct ListHeaderP{ struct ListHeaderP *next; SDB STime time; }; /********************************************************************* hashmap.h *********************************************************************/ struct _hash_t; typedef struct _hash_t hash_t; /********************************************************************* vector.h *********************************************************************/ typedef struct{ int num_elements; int num_elements_allocated; void **elements; } vector_t; /********************************************************************* velocities.h *********************************************************************/ #define MAX_VELOCITY (1<<16) struct Velocities{ struct ListHeader3 l; int velocity; }; #define NextVelocity(a) ((struct Velocities *)((a)->l.next)) /********************************************************************* notes.h *********************************************************************/ struct Notes{ struct ListHeader3 l; int note; int cents; int velocity; Place end; int velocity_end; struct Velocities *velocities; int noend; }; #define NextNote(a) ((struct Notes *)((a)->l.next)) /********************************************************************* patch.h *********************************************************************/ struct Tracks; struct Instruments; union SuperType{ void *pointer; int64_t int_num; double float_num; }; enum TimeFormat{ TIME_IN_BEATS = 0, TIME_IN_MS = 1, TIME_IN_S = 2 }; struct PatchVoice{ bool is_on; int transpose; float volume; float start; float length; enum TimeFormat time_format; }; #define MAX_PATCH_VOICES 6 // Note that Patch objects are stored directly in undo/redo (not copied), so it must not be freed, reused for other purposes, or othervice manipulated when not available. struct Patch{ int id; const char *name; STime last_time; // player lock must be held when setting this value. void (*playnote)(struct Patch *patch,int notenum,int velocity,STime time,float pan); void (*changevelocity)(struct Patch *patch,int notenum,int velocity,STime time); void (*stopnote)(struct Patch *patch,int notenum,int velocity,STime time); void (*closePatch)(struct Patch *patch); struct Instruments *instrument; void *patchdata; // Free use by the instrument plug-in. void (*changeTrackPan)(int newpan,struct Tracks *track); struct PatchVoice voices[MAX_PATCH_VOICES]; int num_ons[128]; /* To keep track of how many times a voice has to be turned off. */ int notes_num_ons[128]; /* To keep track of which notes are playing. (Useful to avoid hanging notes when turning on and off voices)*/ bool peaks_are_dirty; /* Can be set to true by any thread. */ }; #define PATCH_FAILED 0 #define PATCH_SUCCESS 1 #define NextPatch(a) ((struct Patch *)((a)->l.next)) /********************************************************************* fx.h *********************************************************************/ struct FX{ // struct ListHeader1 l; // The next field in 'l' is not used. FX objects are stored one by one in the FXs object. int num; const char *name; int color; void (*configureFX)(struct FX *fx,struct Tracks *track); int min; int max; int effect_num; // Set by the instrument plugin. // Having pointers to variables in sliders is a bit strange, but letting sliders reference FX instead would cause bookkeeping of live and not alive FX objects. // Not getting that bookkeeping correct would mean crashes that could be difficult to track. // This, on the other hand, is safe, since sliders are always alive as long as the Patch is alive, and the patch always outlives an FX object. // (The refactor to let Patch own FX hasn't been done yet. It didn't make sense when there were only MIDI instrument, but now it's too complicated to let FX live independently. // However, when an instrument is deleted, all tracks are scanned, and FX are deleted when a patch is deleted. Same when changing patch for a track.) float *slider_automation_value; // Pointer to the float value showing automation in slider. Value is scaled between 0-1. May be NULL. int *slider_automation_color; // Pointer to the integer holding color number for showing automation in slider. May be NULL. void (*treatFX)(struct FX *fx,int val,struct Tracks *track,STime time,int skip); void (*closeFX)(struct FX *fx,struct Tracks *track); void *fxdata; //Free use for the instrument plug-in. void (*SaveFX)(struct FX *fx,struct Tracks *track); }; #define FX_FAILED 0 #define FX_SUCCESS 1 /********************************************************************* instruments.h *********************************************************************/ // These constants are not only used internally, but they are also saved to disk. enum{ NO_INSTRUMENT_TYPE = 0, MIDI_INSTRUMENT_TYPE, AUDIO_INSTRUMENT_TYPE }; struct Tracker_Windows; struct Instruments{ struct ListHeader1 l; const char *instrumentname; vector_t patches; // Not safe to traverse from player thread. int (*getMaxVelocity)(struct Patch *patch); int (*getFX)(struct Tracker_Windows *window,struct Tracks *track,struct FX *fx); int (*getPatch)(struct Tracker_Windows *window,ReqType reqtype,struct Tracks *track,struct Patch *patch); //void (*treatSpecialCommand)(char *command,struct Tracks *track); void (*CloseInstrument)(struct Instruments *instrument); void (*StopPlaying)(struct Instruments *instrument); void (*PP_Update)(struct Instruments *instrument,struct Patch *patch); void *(*CopyInstrumentData)(struct Tracks *track); //Necesarry for undo. void (*PlayFromStartHook)(struct Instruments *instrument); void *(*LoadFX)(struct FX *fx,struct Tracks *track); void (*handle_fx_when_theres_a_new_patch_for_track)(struct Tracks *track, struct Patch *old_patch, struct Patch *new_patch); void (*remove_patch)(struct Patch *patch); void (*setPatchData)(struct Patch *patch, char *key, char *value); char *(*getPatchData)(struct Patch *patch, char *key); }; #define INSTRUMENT_FAILED 0 #define INSTRUMENT_SUCCESS 1 #define NextInstrument(a) ((struct Instruments *)((a)->l.next)) /********************************************************************* stops.h *********************************************************************/ struct Stops{ struct ListHeader3 l; }; #define NextStop(a) ((struct Stops *)((a)->l.next)) /********************************************************************* fxnodelines.h *********************************************************************/ struct FXNodeLines{ struct ListHeader3 l; int val; }; #define NextFXNodeLine(a) ((struct FXNodeLines *)((a)->l.next)) struct FXs{ struct ListHeader1 l; /* l.num=fxnum */ struct FX *fx; struct FXNodeLines *fxnodelines; }; #define NextFX(a) ((struct FXs *)((a)->l.next)) /********************************************************************* tracks.h *********************************************************************/ struct Tracks{ struct ListHeader1 l; struct Notes *notes; struct Stops *stops; int onoff; const char *trackname; struct Patch *patch; struct FXs *fxs; void *midi_instrumentdata; /* Used by the midi instrument. */ int pan; int volume; bool panonoff; bool volumeonoff; /* The volume-button on/off, not track on/off. */ }; #define NextTrack(a) ((struct Tracks *)((a)->l.next)) #define MAXTRACKVOL 1000 #define MAXTRACKPAN 1000 /********************************************************************* area.h *********************************************************************/ typedef struct{ int x,x2; }Area; typedef struct{ int y,y2; }YArea; typedef struct{ int width; int x,x2; }WArea; /********************************************************************* trackreallines.h *********************************************************************/ #define NUM_PEAKS_PER_LINE 8 struct APoint{ float x,y; }; #define TRE_Max INT16_MAX struct TrackReallineElements{ struct TrackReallineElements *next; struct Notes *note; int type; int subtype; float y1,y2; float x1,x2; void *pointer; struct APoint *velocity_polygon; int num_peaks; struct APoint *peaks[2]; }; /************* Types: */ #define TRE_THISNOTELINES 0 #define TRE_VELLINECENTS 0x5 #define TRE_VELLINENODE 0x10 #define TRE_VELLINE 0x20 #define TRE_VELLINESTART 0x30 #define TRE_VELLINEEND 0x40 #define TRE_STOPLINE 0x90 #define TRE_REALSTARTSTOP 0xa0 /* Subtype for 0-0x40 is the same as subtrack for the note. */ struct TrackRealline{ int note; /* Is 0 if no note. */ struct TrackReallineElements *trackreallineelements; }; #define NOTE_MUL 128 #define NOTE_STP 129 #define NOTE_MUR 130 /********************************************************************* wfxnodes.h *********************************************************************/ typedef struct TrackReallineElements WFXNodes; /* struct WFXNodes{ struct WFXNodes *next; SDB unsigned char type; unsigned char subtype; // not used. unsigned char y1,y2; unsigned short x1,x2; void *pointer; // Only referenced. }; */ /************* Types: */ #define TRE_FXNODE 0x50 #define TRE_FXLINE 0x60 /********************************************************************* tbox.h *********************************************************************/ struct TBoxstruct{ int x1,y1,x2,y2; }; typedef struct TBoxstruct TBox; /********************************************************************* wtracks.h *********************************************************************/ struct WTracks{ struct ListHeader1 l; // l.num=wtracknum; int x,y,x2,y2; /* GFX area. */ int notesonoff; /* notearea and placementarea on/off. */ int notelength; /* Number of characters the notes is. Usually 2 or 3. */ int notewidth; Area notearea; /* These are all parts of the GFX area. */ int fxonoff; /* FX area on/off */ int fxwidth; /* is fxarea.x2-fxarea.x */ Area fxarea; int num_vel; /* Max number of velocity lines showed simultaniously. (I.e the number of subtracks)*/ struct Tracks *track; /* Only referenced. wtracknum=track->tracknum */ struct TrackRealline *trackreallines; WFXNodes **wfxnodes; TBox pan; TBox volume; TBox panonoff; TBox volumeonoff; int noteshowtype; }; #define NextWTrack(a) ((struct WTracks *)((a)->l.next)) #define TEXTTYPE 0 #define GFXTYPE1 1 #define MAXTYPE 1 /********************************************************************* lpb.h *********************************************************************/ struct LPBs{ struct ListHeader3 l; int lpb; }; #define NextLPB(a) (struct LPBs *)((a)->l.next) struct WLPBs{ int lpb; int type; /* 0=normal, 1=below positioned, 2=mul. */ struct LPBs *LPB; /* Only referenced. */ }; #define LPB_NORMAL 0 #define LPB_BELOW 1 #define LPB_MUL 2 /********************************************************************* tempos.h *********************************************************************/ struct Tempos{ struct ListHeader3 l; int tempo; }; #define NextTempo(a) (struct Tempos *)((a)->l.next) struct WTempos{ int tempo; int type; /* 0=normal, 1=below positioned, 2=mul. */ SDB struct Tempos *Tempo; /* Only referenced. */ }; /* Types */ #define TEMPO_NORMAL 0 #define TEMPO_BELOW 1 #define TEMPO_MUL 2 /********************************************************************* temponodes.h *********************************************************************/ struct TempoNodes{ struct ListHeader3 l; float reltempo; }; #define NextTempoNode(a) ((struct TempoNodes *)((a)->l.next)) typedef struct TrackReallineElements WTempoNodes; /* struct WTempoNodes{ struct WTempoNodes *next; unsigned char type; unsigned char subtype; // Currently not used. unsigned char y1,y2; unsigned short x1,x2; void *temponode; // Only referenced. }; */ /* Types */ #define TEMPONODE_NODE 0 #define TEMPONODE_LINE 1 /********************************************************************* time.h *********************************************************************/ struct STimeChanges{ struct ListHeader3 l; STime time; float tempo1; // tempo (tempo*lpb) at this->l.p float rel; // reltempo for this->l.p float deltarel; // rel+deltarel is reltempo for this->l.next->l.p }; #define NextSTimeChange(a) (struct STimeChanges *)((a)->l.next) struct STimes{ /* One element for each line. */ STime time; /* Start-time for the line. */ SDB struct STimeChanges *timechanges; }; /********************************************************************* blocks.h *********************************************************************/ struct Blocks{ struct ListHeader1 l; char *name; NInt num_tracks; int num_lines; struct Tracks *tracks; struct LPBs *lpbs; struct Tempos *tempos; struct TempoNodes *temponodes; struct TempoNodes *lasttemponode; struct STimes *times; /* Pointer to array. Last element (times[num_lines]) is the playtime of the block. */ float reltempo; /* factor that the tempo is multiplied with when playing this block. */ // This variable is checked after each keyboard or menu event. If true, trackreallines, wtracks, etc. will be updated. bool is_dirty; }; #define NextBlock(a) (struct Blocks *)((a)->l.next) /********************************************************************* localzooms.h *********************************************************************/ struct LocalZooms{ struct ListHeader3 l; // struct LocalZooms *next; /* Next on the same level. */ // int line; /* The same type of line that note has. */ // uint_32 counter; /* Same type of counter that line has. */ // uint_32 dividor; /* Same type of dividor that line has. */ int zoomline; /* The linetype that is showed in the editor. */ int level; int realline; struct LocalZooms *uplevel; /* Contains 'num_newlines' # of elements. */ }; #define NextLocalZoom(a) ((struct LocalZooms *)((a)->l.next)) /********************************************************************* wblocks.h *********************************************************************/ struct WBlocks{ struct ListHeader1 l; int tempotrackonoff; /* 1=on, 0=off */ int temponodetrackonoff; /* 1=on, 0=off */ TBox a; // everything // int x,y,x2,y2; /* GFX area. */ TBox t; // int tx,ty,tx2,ty2; /* lines, nodes, etc. GFX area. */ //WArea zoomlevelarea; WArea linenumarea; WArea zoomlinearea; WArea tempocolorarea; WArea lpbTypearea; WArea lpbarea; WArea tempoTypearea; // When one character signals whether the tempo is down "d", or multi "m" WArea tempoarea; WArea temponodearea; YArea linearea; int maxwtracksize; /* The size of the widest wtrack. */ int num_visiblelines; int top_realline; int curr_realline; int till_curr_realline; /* The player-routine sets this on. */ int bot_realline; int mouse_track; // The track the mouse is currently above. -1 if not on a track. struct Notes *mouse_note; // The note the mouse is currently above. NULL if mouse is not above a note. struct Blocks *block; /* Only referenced. wblocknum=block->blocknum */ struct LocalZooms *localzooms; struct LocalZooms **reallines; int num_reallines; int num_reallines_last; struct WTracks *wtracks; struct WTracks *wtrack; /* Current track. Only referenced. */ char *title; /* Window title. */ NInt left_track; /* The leftmost visible track. */ int left_subtrack; NInt right_track; /* The rightmost visible track. */ int right_subtrack; struct WTempos *wtempos; WTempoNodes **wtemponodes; struct WLPBs *wlpbs; float reltempomax; bool isranged; NInt rangex1; NInt rangex2; NInt rangey1; NInt rangey2; bool isgfxdatahere; TBox reltempo; //tempocolor stuff bool tc_onoff; int tc_numcolors; int tc_maxtime; int tc_mintime; int tc_type; }; #define NextWBlock(a) (struct WBlocks *)((a)->l.next) /********************************************************************* slider.h *********************************************************************/ struct Slider{ int show; int width; int x,x2; int lx,lx2; }; /********************************************************************* blts.h ********************************************************************/ typedef struct{ /* Used by Blt_blt Blt_mark */ bool blt_do; int x1;int x2; int startrealline; int endrealline; /* Used by Blt_blt and Blt_marktrackheader */ bool blt_doheader; NInt starttrack; NInt endtrack; /* Used by Blt_clearNotUsedVisible and Blt_markVisible */ bool clear_do; int v_x1;int v_x2; int v_y1;int v_y2; }Blt; /********************************************************************* windows.h *********************************************************************/ #include "mouse.h" struct Tracker_Windows{ struct ListHeader1 l; struct OS_visual os_visual; int x,y; /* Where window is placed. (for amiga: screen-pos)*/ int width,height; /* Size of area to use. */ char *fontname; int fontID; /* System spesific. For amiga: fontsize. */ int fontTags; /* System spesific. For amiga: nothing. */ int fontwidth,fontheight; /* Proportional fonts not so very allowed. */ NInt curr_track; int curr_track_sub; /* -1=note, 0,1,2,...,n=vel */ NInt curr_block; int maxwtracksize; /* The size of the widest wtrack for all wblocks. */ struct Slider bottomslider; struct Slider leftslider; struct Slider rightslider; bool playalong; /* If true, this window allso shows whats being played if any other window is playing. default=true. */ struct WBlocks *wblock; /* Current wblock. Only referenced. */ struct WBlocks *wblocks; struct TEventFIFO *TELroot; struct TEventFIFO *TELlast; uint32_t event_treat; /* Chooses which event type(s) to treat. (0=all)*/ int dontbuffer; struct MouseAction curraction; struct MouseAction prevaction; int org_fontheight; #ifdef _AMIGA char *h_fontname; int h_fontID; /* System spesific. For amiga: fontsize. */ int h_fontTags; /* System spesific. For amiga: nothing. */ int h_fontwidth; #endif int num_pixmapdefs; int *pixmapdefs; int *pixmapdefs_calc; Blt blt; #ifdef USE_GFX_OP_QUEUE void *op_queue; #endif bool must_redraw; }; #define NextWindow(a) (struct Tracker_Windows *)((a)->l.next) /* curr_track types */ #define TEMPONODETRACK -1 #define TEMPOTRACK -2 #define LPBTRACK -3 #define LINENUMBTRACK -4 #define TEMPOCOLORTRACK -5 #define NOTRACK -10000 /********************************************************************* song.h *********************************************************************/ struct Song{ struct Tracker_Windows *tracker_windows; struct Blocks *blocks; struct Blocks **playlist; /* This variable is just temporarily. Later, the playlist will be much more advanced. */ NInt num_blocks; int length; /* Playlist length. */ char *songname; NInt maxtracks; /* The highest number of tracks in a block. (changed when exceeding) */ hash_t *mixerwidget_state; // Only used during loading. hash_t *instrument_widget_order_state; // Only used during loading. }; /********************************************************************* root.h *********************************************************************/ struct Root{ struct Song *song; int curr_playlist; NInt curr_block; bool setfirstpos; int tempo; /* Standard tempo. */ int lpb; /* Standard lpb. */ float quantitize; int keyoct; int min_standardvel; int standardvel; bool editonoff; bool scrollplayonoff; }; /************************************************* Structures for the advanced functions. (especially made for extension language support.) *************************************************/ struct NoteAdds_track{ float place; // A placement type represented as float int notenum; float volume; // 0.0 is off, 1.0 is max, -0.0 - -2.0 is default float endplace; // The end place. A value -0.0 - -2.0 means no spesified end-place (end-place is set to the same as the start-place of the next note in the array). }; struct NoteAdds_track_do{ NInt tracknum; int num_nats; struct NoteAdds_track *nats; float startplace; int sort; }; struct NoteAdds_block{ NInt blocknum; int num_nats_do; struct NoteAdds_track_do **nats_do; }; #endif radium_compressor-0.5.1/common/nsmtracker_events.h000077500000000000000000000047251210074205700224610ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #ifndef TRACKER_EVENTS_DEFINE #define TRACKER_EVENTS_DEFINE 1 #include "keyboard_sub_ids.h" /* Event IDs: */ #define TR_MOUSEMOVE 0 #define TR_LEFTMOUSEDOWN 1 #define TR_LEFTMOUSEUP 2 #define TR_MIDDLEMOUSEDOWN 3 #define TR_MIDDLEMOUSEUP 4 #define TR_RIGHTMOUSEDOWN 5 #define TR_RIGHTMOUSEUP 6 #define TR_KEYBOARD 7 #define TR_WINDOWMOVE 8 #define TR_WINDOWRESIZE 9 #define TR_WINDOWVISIBLE 10 #define TR_WINDOWNOTVISIBLE 11 #define TR_WINDOWCLOSE 12 #define TR_KEYBOARDUP 13 /* KEYSWITCHes: */ #define EVENT_LEFTCTRL (1<num_elements;iterator666++){ \ type varname = (type)((vector)->elements[iterator666]); #else #define VECTOR_FOR_EACH(var,vector) { \ int iterator666; \ for(iterator666=0;iterator666<(vector)->num_elements;iterator666++){ \ var = (vector)->elements[iterator666]; #endif #define END_VECTOR_FOR_EACH }} #endif radium_compressor-0.5.1/common/visual_op_queue_proc.h000066400000000000000000000032701210074205700231430ustar00rootroot00000000000000// This file is automatically generated from gfx_op_queue.scm #ifndef VISUAL_OP_QUEUE_PROC_H #define VISUAL_OP_QUEUE_PROC_H extern LANGSPEC void OS_GFX_C2V_bitBlt(struct Tracker_Windows* window,int from_x1,int from_x2,int to_y); extern LANGSPEC void OS_GFX_C_DrawCursor(struct Tracker_Windows* window,int x1,int x2,int x3,int x4,int height,int y_pixmap); extern LANGSPEC void OS_GFX_P2V_bitBlt(struct Tracker_Windows* window,int from_x,int from_y,int to_x,int to_y,int width,int height); extern LANGSPEC void OS_GFX_FilledBox(struct Tracker_Windows* tvisual,int color,int x,int y,int x2,int y2,int where); extern LANGSPEC void OS_GFX_Box(struct Tracker_Windows* tvisual,int color,int x,int y,int x2,int y2,int where); extern LANGSPEC void OS_GFX_SetClipRect(struct Tracker_Windows* tvisual,int x,int y,int x2,int y2,int where); extern LANGSPEC void OS_GFX_CancelClipRect(struct Tracker_Windows* tvisual,int where); extern LANGSPEC void OS_GFX_Line(struct Tracker_Windows* tvisual,int color,int x,int y,int x2,int y2,int where); extern LANGSPEC void OS_GFX_Polygon(struct Tracker_Windows* tvisual,int color,int x1,int y1,int x2,int y2,int num_points,struct APoint* peaks,int where); extern LANGSPEC void OS_GFX_Polyline(struct Tracker_Windows* tvisual,int color,int x1,int y1,int x2,int y2,int num_points,struct APoint* peaks,int where); extern LANGSPEC void OS_GFX_SetMixColor(struct Tracker_Windows* tvisual,int color1,int color2,int mix_factor); extern LANGSPEC void OS_GFX_Text(struct Tracker_Windows* tvisual,int color,const char* text,int x,int y,int width,int flags,int where); extern LANGSPEC void OS_GFX_BitBlt(struct Tracker_Windows* tvisual,int dx,int dy,int x,int y,int x2,int y2); #endif radium_compressor-0.5.1/common/visual_proc.h000077500000000000000000000340141210074205700212440ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #ifndef RADIUM_VISUAL_PROC_H #define RADIUM_VISUAL_PROC_H #include "OS_visual_input.h" #define TEXT_IGNORE_WIDTH -99999 // Can be used instead of width, not a flag // flags: #define TEXT_NOFLAGS 0 #define TEXT_CLEAR 1 #define TEXT_INVERT 2 #define TEXT_CENTER 4 #define TEXT_CLIPRECT 8 #define TEXT_NOTEXT 16 #define TEXT_BOLD 32 #define TEXT_SCALE 64 // Scales the text into the box. extern LANGSPEC int GFX_Message(vector_t *buttons,const char *fmt,...); extern LANGSPEC void GFX_AddMenuItem(struct Tracker_Windows *tvisual, const char *name, const char *python_command); extern LANGSPEC void GFX_AddCheckableMenuItem(struct Tracker_Windows *tvisual, const char *name, const char *python_command, int checkval); extern LANGSPEC void GFX_AddMenuSeparator(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_AddMenuMenu(struct Tracker_Windows *tvisual, const char *name, const char *command); extern LANGSPEC void GFX_GoPreviousMenuLevel(struct Tracker_Windows *tvisual); extern LANGSPEC void QUEUE_GFX_C2V_bitBlt( struct Tracker_Windows *window, int from_x1,int from_x2, int to_y ); /* window,x1,x2,x3,x4,height, y pixmap */ extern LANGSPEC void QUEUE_GFX_C_DrawCursor( struct Tracker_Windows *window, int x1,int x2,int x3,int x4,int height, int y_pixmap ); extern LANGSPEC void QUEUE_GFX_P2V_bitBlt( struct Tracker_Windows *window, int from_x,int from_y, int to_x,int to_y, int width,int height ); extern LANGSPEC void QUEUE_GFX_P_FilledBox(struct Tracker_Windows *tvisual,int color,int x,int y,int x2,int y2); extern LANGSPEC void GFX_disable_mouse_keyboard(void); extern LANGSPEC void GFX_enable_mouse_keyboard(void); extern LANGSPEC int GFX_CreateVisual(struct Tracker_Windows *tvisual); extern LANGSPEC int GFX_ShutDownVisual(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_SetMinimumWindowWidth(struct Tracker_Windows *tvisual, int width); extern LANGSPEC void GFX_EditorWindowToFront(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_PlayListWindowToFront(void); extern LANGSPEC void GFX_PlayListWindowToBack(void); extern LANGSPEC void GFX_InstrumentWindowToFront(void); extern LANGSPEC void GFX_InstrumentWindowToBack(void); extern LANGSPEC void GFX_HelpWindowToFront(void); extern LANGSPEC void GFX_toggleFullScreen(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_showHideInstrumentWidget(struct Tracker_Windows *window); extern LANGSPEC void GFX_showHidePlaylist(struct Tracker_Windows *window); extern LANGSPEC void GFX_showHideEditor(void); extern LANGSPEC void GFX_showHideMixerWidget(void); extern LANGSPEC void GFX_SetMinimalInstrumentWindow(void); extern LANGSPEC bool GFX_EditorIsVisible(void); extern LANGSPEC void GFX_ShowEditor(void); extern LANGSPEC void GFX_HideEditor(void); extern LANGSPEC bool GFX_MixerIsVisible(void); extern LANGSPEC void GFX_ShowMixer(void); extern LANGSPEC void GFX_HideMixer(void); extern LANGSPEC bool GFX_InstrumentWindowIsVisible(void); extern LANGSPEC void GFX_MaximizeEditorWindow(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_MinimizeEditorWindow(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_ConfigColors(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_ConfigFonts(struct Tracker_Windows *tvisual); extern LANGSPEC void GFX_SetDefaultColors(struct Tracker_Windows *tvisual); //bool GFX_SelectEditFont(struct Tracker_Windows *tvisual){ extern LANGSPEC void QUEUE_GFX_FilledBox(struct Tracker_Windows *tvisual,int color,int x,int y,int x2,int y2, int where); extern LANGSPEC void QUEUE_GFX_Box(struct Tracker_Windows *tvisual,int color,int x,int y,int x2,int y2, int where); extern LANGSPEC void QUEUE_GFX_SetClipRect( struct Tracker_Windows *tvisual, int x,int y, int x2,int y2, int where ); extern LANGSPEC void QUEUE_GFX_CancelClipRect(struct Tracker_Windows *tvisual, int where); extern LANGSPEC void PREOS_GFX_Line(struct Tracker_Windows *window,int color,int x,int y,int x2,int y2,int where); extern LANGSPEC void QUEUE_GFX_Line(struct Tracker_Windows *tvisual,int color,int x,int y,int x2,int y2,int where); extern LANGSPEC void GFX_Point(struct Tracker_Windows *tvisual,int color,int brightness,int x,int y,int where); // brigtness is between 0 and MAX_BRIGHTNESS. Used by aa lines. extern LANGSPEC void QUEUE_GFX_Point(struct Tracker_Windows* tvisual,int color,int brightness,int x,int y,int where); extern LANGSPEC void QUEUE_GFX_Points(struct Tracker_Windows* tvisual,int color,int brightness,int num_points, uint16_t *x,uint16_t *y,int where); extern LANGSPEC void OS_GFX_Point( struct Tracker_Windows *tvisual, int color, int brightness, int x,int y, int where ); extern LANGSPEC void OS_GFX_Points( struct Tracker_Windows *tvisual, int color, int brightness, int num_points, uint16_t *x,uint16_t *y, int where ); extern LANGSPEC void OS_GFX_SetMixColor(struct Tracker_Windows *tvisual,int color1,int color2,int mix_factor); extern LANGSPEC void QUEUE_GFX_SetMixColor(struct Tracker_Windows *tvisual,int color1,int color2,int mix_factor); extern LANGSPEC void OS_GFX_Polygon( struct Tracker_Windows *tvisual, int color, int x1, int y1, int x2, int y2, int num_points, struct APoint *peaks, int where ); extern LANGSPEC void OS_GFX_Polyline( struct Tracker_Windows *tvisual, int color, int x1, int y1, int x2, int y2, int num_points, struct APoint *peaks, int where ); extern LANGSPEC void QUEUE_GFX_Polygon( struct Tracker_Windows *tvisual, int color, int x1, int y1, int x2, int y2, int num_points, struct APoint *peaks, int where ); extern LANGSPEC void QUEUE_GFX_Polyline( struct Tracker_Windows *tvisual, int color, int x1, int y1, int x2, int y2, int num_points, struct APoint *peaks, int where ); extern LANGSPEC int GFX_get_text_width(struct Tracker_Windows *tvisual, const char *text); extern LANGSPEC int GFX_get_num_characters(struct Tracker_Windows *tvisual, const char *text, int max_width); extern LANGSPEC void PREOS_GFX_Text( struct Tracker_Windows *tvisual, int color, const char *text, int x, int y, int width, int flags, int where ); extern LANGSPEC void QUEUE_GFX_Text( struct Tracker_Windows *tvisual, int color, const char *text, int x, int y, int width, int flags, int where ); extern LANGSPEC void GFX_DrawTrackBorderSingle( struct Tracker_Windows *tvisual, int x, int y, int y2, int where ); extern LANGSPEC void GFX_DrawTrackBorderDouble( struct Tracker_Windows *tvisual, int x, int y, int y2, int where ); extern LANGSPEC void QUEUE_GFX_BitBlt( struct Tracker_Windows *tvisual, int dx,int dy, int x,int y, int x2,int y2 ); extern LANGSPEC int GFX_ResizeWindow(struct Tracker_Windows *tvisual,int x,int y); void GFXS_LineType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ), struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ); void GFXS_BoxType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ), struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ); void GFXS_TextType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color,const char *text, int x,int y, int width, int flags, int where ), struct Tracker_Windows *window, int color,const char *text, int x,int y, int width, int flags, int where ); void GFXS_BorderType( void (*GFX_P_OSFunc)( struct Tracker_Windows *tvisual, int x, int y, int y2, int where ), struct Tracker_Windows *tvisual, int x, int y, int y2, int where ); void GFXS_BorderType2( void (*GFX_P_OSFunc)( struct Tracker_Windows *tvisual, int x, int y, int y2, int where ), struct Tracker_Windows *tvisual, int x, int y, int y2, int where ); void GFXS_BitBltType( void (*GFX_P_OSFunc)( struct Tracker_Windows *tvisual, int dx,int dy, int x,int y, int x2,int y2 ), struct Tracker_Windows *tvisual, int dx,int dy, int x,int y, int x2,int y2 ); void GFXST_LineType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ), struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ); void GFXST_BoxType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ), struct Tracker_Windows *window, int color, int x,int y,int x2,int y2, int where ); void GFXST_TextType( void (*GFX_OSFunc)( struct Tracker_Windows *window, int color,const char *text, int x,int y, int width, int flags, int where ), struct Tracker_Windows *window, int color,const char *text, int x,int y, int width, int flags, int where ); void GFXST_BorderType( void (*GFX_P_OSFunc)( struct Tracker_Windows *window, int x, int y, int y2, int where ), struct Tracker_Windows *window, int x, int y, int y2, int where ); void GFXST_BorderType2( void (*GFX_P_OSFunc)( struct Tracker_Windows *window, int x, int y, int y2, int where ), struct Tracker_Windows *window, int x, int y, int y2, int where ); #ifndef GFX_DONTSHRINK #define GFX_FilledBox(a,b,c,d,e,f,g) GFXS_BoxType(QUEUE_GFX_FilledBox,a,b,c,d,e,f,g) #define GFX_Box(a,b,c,d,e,f,g) GFXS_BoxType(QUEUE_GFX_Box,a,b,c,d,e,f,g) #define GFX_Line(a,b,c,d,e,f,g) GFXS_LineType(QUEUE_GFX_Line,a,b,c,d,e,f,g) #define GFX_Text(a,b,c,d,e,f,g,h) GFXS_TextType(QUEUE_GFX_Text,a,b,c,d,e,f,g,h) #define GFX_DrawTrackBorderSingle(a,b,c,d,e) GFXS_BorderType(GFX_DrawTrackBorderSingle,a,b,c,d,e) #define GFX_DrawTrackBorderDouble(a,b,c,d,e) GFXS_BorderType2(GFX_DrawTrackBorderDouble,a,b,c,d,e) #define GFX_BitBlt(a,b,c,d,e,f,g) GFXS_BitBltType(QUEUE_GFX_BitBlt,a,b,c,d,e,f,g) #define GFX_T_FilledBox(a,b,c,d,e,f,g) GFXST_BoxType(QUEUE_GFX_FilledBox,a,b,c,d,e,f,g) #define GFX_T_Box(a,b,c,d,e,f,g) GFXST_BoxType(QUEUE_GFX_Box,a,b,c,d,e,f,g) #define GFX_T_Line(a,b,c,d,e,f,g) GFXST_LineType(QUEUE_GFX_Line,a,b,c,d,e,f,g) #define GFX_T_Text(a,b,c,d,e,f,g,h) GFXST_TextType(QUEUE_GFX_Text,a,b,c,d,e,f,g,h) #define GFX_T_DrawTrackBorderSingle(a,b,c,d,e) GFXST_BorderType(GFX_DrawTrackBorderSingle,a,b,c,d,e) #define GFX_T_DrawTrackBorderDouble(a,b,c,d,e) GFXST_BorderType2(GFX_DrawTrackBorderDouble,a,b,c,d,e) #define GFX_SetMixColor QUEUE_GFX_SetMixColor #define GFX_Polygon QUEUE_GFX_Polygon #define GFX_Polyline QUEUE_GFX_Polyline #define GFX_SetClipRect QUEUE_GFX_SetClipRect #define GFX_CancelClipRect QUEUE_GFX_CancelClipRect #endif #endif radium_compressor-0.5.1/common/windows_proc.h000077500000000000000000000025711210074205700214360ustar00rootroot00000000000000/* Copyright 2000 Kjetil S. Matheussen 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. */ #ifdef TRACKER_INCLUDE extern LANGSPEC void DrawUpTrackerWindow(struct Tracker_Windows *window); extern LANGSPEC void UpdateTrackerWindow(struct Tracker_Windows *window); #endif #ifndef TRACKER_INCLUDE extern LANGSPEC void UpdateTrackerWindowCoordinates(struct Tracker_Windows *window); extern LANGSPEC void UpdateTrackerWindow(struct Tracker_Windows *window); extern LANGSPEC void DrawUpTrackerWindow(struct Tracker_Windows *window); extern LANGSPEC int OpenTrackerWindow(int x,int y,int width,int height); extern LANGSPEC int CloseTrackerWindow(NInt place); extern LANGSPEC void CloseAllTrackerWindows(void); extern LANGSPEC void checkIfWBlocksAreDirty(void); #endif radium_compressor-0.5.1/faudiostream/000077500000000000000000000000001210074205700177335ustar00rootroot00000000000000radium_compressor-0.5.1/faudiostream/architecture/000077500000000000000000000000001210074205700224155ustar00rootroot00000000000000radium_compressor-0.5.1/faudiostream/architecture/faust/000077500000000000000000000000001210074205700235375ustar00rootroot00000000000000radium_compressor-0.5.1/faudiostream/architecture/faust/audio/000077500000000000000000000000001210074205700246405ustar00rootroot00000000000000radium_compressor-0.5.1/faudiostream/architecture/faust/audio/alsa-dsp.h000066400000000000000000000527121210074205700265240ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __alsa_dsp__ #define __alsa_dsp__ #include #include #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" /** DEFAULT ALSA PARAMETERS CONTROLLED BY ENVIRONMENT VARIABLES Some default parameters of Faust's ALSA applications are controlled by the following environment variables : FAUST2ALSA_DEVICE = "hw:0" FAUST2ALSA_FREQUENCY= 44100 FAUST2ALSA_BUFFER = 1024 FAUST2ALSA_PERIODS = 2 */ using namespace std; // handle 32/64 bits int size issues #ifdef __x86_64__ #define uint32 unsigned int #define uint64 unsigned long int #define int32 int #define int64 long int #else #define uint32 unsigned int #define uint64 unsigned long long int #define int32 int #define int64 long long int #endif // check 32/64 bits issues are correctly handled #define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); } #define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); } #define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); } /** * Used to set the priority and scheduling of the audi#include #include o thread */ static bool setRealtimePriority () { struct passwd * pw; int err; uid_t uid; struct sched_param param; uid = getuid (); pw = getpwnam ("root"); setuid (pw->pw_uid); param.sched_priority = 50; /* 0 to 99 */ err = sched_setscheduler(0, SCHED_RR, ¶m); setuid (uid); return (err != -1); } /****************************************************************************** ******************************************************************************* AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; /** * A convenient class to pass parameters to AudioInterface */ class AudioParam { public: const char* fCardName; unsigned int fFrequency; unsigned int fBuffering; unsigned int fPeriods; unsigned int fSoftInputs; unsigned int fSoftOutputs; public : AudioParam() : fCardName("hw:0"), fFrequency(44100), fBuffering(512), fPeriods(2), fSoftInputs(2), fSoftOutputs(2) {} AudioParam& cardName(const char* n) { fCardName = n; return *this; } AudioParam& frequency(int f) { fFrequency = f; return *this; } AudioParam& buffering(int fpb) { fBuffering = fpb; return *this; } AudioParam& periods(int p) { fPeriods = p; return *this; } AudioParam& inputs(int n) { fSoftInputs = n; return *this; } AudioParam& outputs(int n) { fSoftOutputs = n; return *this; } }; /** * An ALSA audio interface */ class AudioInterface : public AudioParam { public : snd_pcm_t* fOutputDevice ; snd_pcm_t* fInputDevice ; snd_pcm_hw_params_t* fInputParams; snd_pcm_hw_params_t* fOutputParams; snd_pcm_format_t fSampleFormat; snd_pcm_access_t fSampleAccess; unsigned int fCardInputs; unsigned int fCardOutputs; unsigned int fChanInputs; unsigned int fChanOutputs; // interleaved mode audiocard buffers void* fInputCardBuffer; void* fOutputCardBuffer; // non interleaved mode audiocard buffers void* fInputCardChannels[256]; void* fOutputCardChannels[256]; // non interleaved mod, floating point software buffers float* fInputSoftChannels[256]; float* fOutputSoftChannels[256]; public : const char* cardName() { return fCardName; } int frequency() { return fFrequency; } int buffering() { return fBuffering; } int periods() { return fPeriods; } float** inputSoftChannels() { return fInputSoftChannels; } float** outputSoftChannels() { return fOutputSoftChannels; } AudioInterface(const AudioParam& ap = AudioParam()) : AudioParam(ap) { fInputDevice = 0; fOutputDevice = 0; fInputParams = 0; fOutputParams = 0; } /** * Open the audio interface */ void open() { int err; // allocation d'un stream d'entree et d'un stream de sortie err = snd_pcm_open( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ); check_error(err) err = snd_pcm_open( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ); check_error(err) // recherche des parametres d'entree err = snd_pcm_hw_params_malloc ( &fInputParams ); check_error(err); setAudioParams(fInputDevice, fInputParams); // recherche des parametres de sortie err = snd_pcm_hw_params_malloc ( &fOutputParams ); check_error(err) setAudioParams(fOutputDevice, fOutputParams); // set the number of physical input and output channels close to what we need fCardInputs = fSoftInputs; fCardOutputs = fSoftOutputs; snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); printf("inputs : %u, outputs : %u\n", fCardInputs, fCardOutputs); // enregistrement des parametres d'entree-sortie err = snd_pcm_hw_params (fInputDevice, fInputParams ); check_error (err); err = snd_pcm_hw_params (fOutputDevice, fOutputParams ); check_error (err); //assert(snd_pcm_hw_params_get_period_size(fInputParams,NULL) == snd_pcm_hw_params_get_period_size(fOutputParams,NULL)); // allocation of alsa buffers if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { fInputCardBuffer = calloc(interleavedBufferSize(fInputParams), 1); fOutputCardBuffer = calloc(interleavedBufferSize(fOutputParams), 1); } else { for (unsigned int i = 0; i < fCardInputs; i++) { fInputCardChannels[i] = calloc(noninterleavedBufferSize(fInputParams), 1); } for (unsigned int i = 0; i < fCardOutputs; i++) { fOutputCardChannels[i] = calloc(noninterleavedBufferSize(fOutputParams), 1); } } // allocation of floating point buffers needed by the dsp code fChanInputs = max(fSoftInputs, fCardInputs); assert (fChanInputs < 256); fChanOutputs = max(fSoftOutputs, fCardOutputs); assert (fChanOutputs < 256); for (unsigned int i = 0; i < fChanInputs; i++) { fInputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); for (unsigned int j = 0; j < fBuffering; j++) { fInputSoftChannels[i][j] = 0.0; } } for (unsigned int i = 0; i < fChanOutputs; i++) { fOutputSoftChannels[i] = (float*) calloc (fBuffering, sizeof(float)); for (unsigned int j = 0; j < fBuffering; j++) { fOutputSoftChannels[i][j] = 0.0; } } } void setAudioParams(snd_pcm_t* stream, snd_pcm_hw_params_t* params) { int err; // set params record with initial values err = snd_pcm_hw_params_any ( stream, params ); check_error_msg(err, "unable to init parameters") // set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ); if (err) { err = snd_pcm_hw_params_set_access (stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ); check_error_msg(err, "unable to set access mode neither to non-interleaved or to interleaved"); } snd_pcm_hw_params_get_access(params, &fSampleAccess); // search for 32-bits or 16-bits format err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S32); if (err) { err = snd_pcm_hw_params_set_format (stream, params, SND_PCM_FORMAT_S16); check_error_msg(err, "unable to set format to either 32-bits or 16-bits"); } snd_pcm_hw_params_get_format(params, &fSampleFormat); // set sample frequency snd_pcm_hw_params_set_rate_near (stream, params, &fFrequency, 0); // set period and period size (buffering) err = snd_pcm_hw_params_set_period_size (stream, params, fBuffering, 0); check_error_msg(err, "period size not available"); err = snd_pcm_hw_params_set_periods (stream, params, fPeriods, 0); check_error_msg(err, "number of periods not available"); } ssize_t interleavedBufferSize (snd_pcm_hw_params_t* params) { _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); unsigned int channels; snd_pcm_hw_params_get_channels(params, &channels); ssize_t bsize = snd_pcm_format_size (format, psize * channels); return bsize; } ssize_t noninterleavedBufferSize (snd_pcm_hw_params_t* params) { _snd_pcm_format format; snd_pcm_hw_params_get_format(params, &format); snd_pcm_uframes_t psize; snd_pcm_hw_params_get_period_size(params, &psize, NULL); ssize_t bsize = snd_pcm_format_size (format, psize); return bsize; } void close() {} /** * Read audio samples from the audio card. Convert samples to floats and take * care of interleaved buffers */ void read() { if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { int count = snd_pcm_readi(fInputDevice, fInputCardBuffer, fBuffering); if (count<0) { display_error_msg(count, "reading samples"); int err = snd_pcm_prepare(fInputDevice); check_error_msg(err, "preparing input stream"); } if (fSampleFormat == SND_PCM_FORMAT_S16) { short* buffer16b = (short*) fInputCardBuffer; for (unsigned int s = 0; s < fBuffering; s++) { for (unsigned int c = 0; c < fCardInputs; c++) { fInputSoftChannels[c][s] = float(buffer16b[c + s*fCardInputs])*(1.0/float(SHRT_MAX)); } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { int32* buffer32b = (int32*) fInputCardBuffer; for (unsigned int s = 0; s < fBuffering; s++) { for (unsigned int c = 0; c < fCardInputs; c++) { fInputSoftChannels[c][s] = float(buffer32b[c + s*fCardInputs])*(1.0/float(INT_MAX)); } } } else { printf("unrecognized input sample format : %u\n", fSampleFormat); exit(1); } } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { int count = snd_pcm_readn(fInputDevice, fInputCardChannels, fBuffering); if (count<0) { display_error_msg(count, "reading samples"); int err = snd_pcm_prepare(fInputDevice); check_error_msg(err, "preparing input stream"); } if (fSampleFormat == SND_PCM_FORMAT_S16) { for (unsigned int c = 0; c < fCardInputs; c++) { short* chan16b = (short*) fInputCardChannels[c]; for (unsigned int s = 0; s < fBuffering; s++) { fInputSoftChannels[c][s] = float(chan16b[s])*(1.0/float(SHRT_MAX)); } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { for (unsigned int c = 0; c < fCardInputs; c++) { int32* chan32b = (int32*) fInputCardChannels[c]; for (unsigned int s = 0; s < fBuffering; s++) { fInputSoftChannels[c][s] = float(chan32b[s])*(1.0/float(INT_MAX)); } } } else { printf("unrecognized input sample format : %u\n", fSampleFormat); exit(1); } } else { check_error_msg(-10000, "unknow access mode"); } } /** * write the output soft channels to the audio card. Convert sample * format and interleaves buffers when needed */ void write() { recovery : if (fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED) { if (fSampleFormat == SND_PCM_FORMAT_S16) { short* buffer16b = (short*) fOutputCardBuffer; for (unsigned int f = 0; f < fBuffering; f++) { for (unsigned int c = 0; c < fCardOutputs; c++) { float x = fOutputSoftChannels[c][f]; buffer16b[c + f*fCardOutputs] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ; } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { int32* buffer32b = (int32*) fOutputCardBuffer; for (unsigned int f = 0; f < fBuffering; f++) { for (unsigned int c = 0; c < fCardOutputs; c++) { float x = fOutputSoftChannels[c][f]; buffer32b[c + f*fCardOutputs] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ; } } } else { printf("unrecognized output sample format : %u\n", fSampleFormat); exit(1); } int count = snd_pcm_writei(fOutputDevice, fOutputCardBuffer, fBuffering); if (count<0) { display_error_msg(count, "w3"); int err = snd_pcm_prepare(fOutputDevice); check_error_msg(err, "preparing output stream"); goto recovery; } } else if (fSampleAccess == SND_PCM_ACCESS_RW_NONINTERLEAVED) { if (fSampleFormat == SND_PCM_FORMAT_S16) { for (unsigned int c = 0; c < fCardOutputs; c++) { short* chan16b = (short*) fOutputCardChannels[c]; for (unsigned int f = 0; f < fBuffering; f++) { float x = fOutputSoftChannels[c][f]; chan16b[f] = short( max(min(x,1.0f),-1.0f) * float(SHRT_MAX) ) ; } } } else if (fSampleFormat == SND_PCM_FORMAT_S32) { for (unsigned int c = 0; c < fCardOutputs; c++) { int32* chan32b = (int32*) fOutputCardChannels[c]; for (unsigned int f = 0; f < fBuffering; f++) { float x = fOutputSoftChannels[c][f]; chan32b[f] = int( max(min(x,1.0f),-1.0f) * float(INT_MAX) ) ; } } } else { printf("unrecognized output sample format : %u\n", fSampleFormat); exit(1); } int count = snd_pcm_writen(fOutputDevice, fOutputCardChannels, fBuffering); if (count<0) { display_error_msg(count, "w3"); int err = snd_pcm_prepare(fOutputDevice); check_error_msg(err, "preparing output stream"); goto recovery; } } else { check_error_msg(-10000, "unknow access mode"); } } /** * print short information on the audio device */ void shortinfo() { int err; snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); snd_ctl_card_info_alloca (&card_info); err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); printf("%s|%d|%d|%d|%d|%s\n", snd_ctl_card_info_get_driver(card_info), fCardInputs, fCardOutputs, fFrequency, fBuffering, snd_pcm_format_name((_snd_pcm_format)fSampleFormat)); } /** * print more detailled information on the audio device */ void longinfo() { int err; snd_ctl_card_info_t* card_info; snd_ctl_t* ctl_handle; printf("Audio Interface Description :\n"); printf("Sampling Frequency : %d, Sample Format : %s, buffering : %d\n", fFrequency, snd_pcm_format_name((_snd_pcm_format)fSampleFormat), fBuffering); printf("Software inputs : %2d, Software outputs : %2d\n", fSoftInputs, fSoftOutputs); printf("Hardware inputs : %2d, Hardware outputs : %2d\n", fCardInputs, fCardOutputs); printf("Channel inputs : %2d, Channel outputs : %2d\n", fChanInputs, fChanOutputs); // affichage des infos de la carte err = snd_ctl_open (&ctl_handle, fCardName, 0); check_error(err); snd_ctl_card_info_alloca (&card_info); err = snd_ctl_card_info(ctl_handle, card_info); check_error(err); printCardInfo(card_info); // affichage des infos liees aux streams d'entree-sortie if (fSoftInputs > 0) printHWParams(fInputParams); if (fSoftOutputs > 0) printHWParams(fOutputParams); } void printCardInfo(snd_ctl_card_info_t* ci) { printf("Card info (address : %p)\n", ci); printf("\tID = %s\n", snd_ctl_card_info_get_id(ci)); printf("\tDriver = %s\n", snd_ctl_card_info_get_driver(ci)); printf("\tName = %s\n", snd_ctl_card_info_get_name(ci)); printf("\tLongName = %s\n", snd_ctl_card_info_get_longname(ci)); printf("\tMixerName = %s\n", snd_ctl_card_info_get_mixername(ci)); printf("\tComponents = %s\n", snd_ctl_card_info_get_components(ci)); printf("--------------\n"); } void printHWParams( snd_pcm_hw_params_t* params ) { printf("HW Params info (address : %p)\n", params); #if 0 printf("\tChannels = %d\n", snd_pcm_hw_params_get_channels(params)); printf("\tFormat = %s\n", snd_pcm_format_name((_snd_pcm_format)snd_pcm_hw_params_get_format(params))); printf("\tAccess = %s\n", snd_pcm_access_name((_snd_pcm_access)snd_pcm_hw_params_get_access(params))); printf("\tRate = %d\n", snd_pcm_hw_params_get_rate(params, NULL)); printf("\tPeriods = %d\n", snd_pcm_hw_params_get_periods(params, NULL)); printf("\tPeriod size = %d\n", (int)snd_pcm_hw_params_get_period_size(params, NULL)); printf("\tPeriod time = %d\n", snd_pcm_hw_params_get_period_time(params, NULL)); printf("\tBuffer size = %d\n", (int)snd_pcm_hw_params_get_buffer_size(params)); printf("\tBuffer time = %d\n", snd_pcm_hw_params_get_buffer_time(params, NULL)); #endif printf("--------------\n"); } }; // lopt : Scan Command Line long int Arguments long lopt(int argc, char *argv[], const char* longname, const char* shortname, long def) { for (int i=2; igetNumInputs()) .outputs(DSP->getNumOutputs())); } virtual ~alsaaudio() { stop(); delete fAudio; } virtual bool init(const char */*name*/, dsp* DSP) { AVOIDDENORMALS; fAudio->open(); DSP->init(fAudio->frequency()); return true; } virtual bool start() { fRunning = true; if (pthread_create( &fAudioThread, 0, __run, this)) fRunning = false; return fRunning; } virtual void stop() { if (fRunning) { fRunning = false; pthread_join (fAudioThread, 0); } } virtual void run() { bool rt = setRealtimePriority(); printf(rt ? "RT : ":"NRT: "); fAudio->shortinfo(); fAudio->write(); fAudio->write(); while(fRunning) { fAudio->read(); fDSP->compute(fAudio->buffering(), fAudio->inputSoftChannels(), fAudio->outputSoftChannels()); fAudio->write(); } } }; void* __run (void* ptr) { alsaaudio * alsa = (alsaaudio*)ptr; alsa->run(); return 0; } #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/faudiostream/architecture/faust/audio/audio.h000066400000000000000000000011411210074205700261070ustar00rootroot00000000000000 /****************************************************************************** ******************************************************************************* An abstraction layer over audio layer ******************************************************************************* *******************************************************************************/ #ifndef __audio__ #define __audio__ class dsp; class audio { public: audio() {} virtual ~audio() {} virtual bool init(const char* name, dsp*) = 0; virtual bool start() = 0; virtual void stop() = 0; }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/audio/coreaudio-dsp.h000066400000000000000000001335631210074205700275620ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __coreaudio_dsp__ #define __coreaudio_dsp__ #include #include #include #include #include #include #include #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" using namespace std; /****************************************************************************** ******************************************************************************* COREAUDIO INTERFACE ******************************************************************************* *******************************************************************************/ #define OPEN_ERR -1 #define CLOSE_ERR -1 #define NO_ERR 0 #define WAIT_COUNTER 60 typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) class TCoreAudioRenderer { private: int fDevNumInChans; int fDevNumOutChans; float** fInChannel; float** fOutChannel; dsp* fDSP; AudioBufferList* fInputData; AudioDeviceID fDeviceID; AudioUnit fAUHAL; AudioObjectID fPluginID; // Used for aggregate device bool fState; OSStatus GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id); OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); int SetupSampleRateAux(AudioDeviceID inDevice, int samplerate); static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); void compute(int inNumberFrames) { fDSP->compute(inNumberFrames, fInChannel, fOutChannel); } public: TCoreAudioRenderer() :fInputData(0),fDeviceID(0),fAUHAL(0),fPluginID(0),fState(false),fDevNumInChans(0),fDevNumOutChans(0),fDSP(0) {} virtual ~TCoreAudioRenderer() {} long OpenDefault(dsp* dsp, long inChan, long outChan, long bufferSize, long sampleRate); long Close(); long Start(); long Stop(); }; typedef TCoreAudioRenderer * TCoreAudioRendererPtr; static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) { cout << "- - - - - - - - - - - - - - - - - - - -" << endl; cout << " Sample Rate: " << inDesc->mSampleRate << endl; cout << " Format ID:%.*s\n" << sizeof(inDesc->mFormatID) << (char*)&inDesc->mFormatID << endl; cout << " Format Flags " << inDesc->mFormatFlags << endl; cout << " Bytes per Packet: " << inDesc->mBytesPerPacket << endl; cout << " Frames per Packet: " << inDesc->mFramesPerPacket << endl; cout << " Bytes per Frame: " << inDesc->mBytesPerFrame << endl; cout << " Channels per Frame: "<< inDesc->mChannelsPerFrame << endl; cout << " Bits per Channel: " << inDesc->mBitsPerChannel << endl; cout << "- - - - - - - - - - - - - - - - - - - -" << endl; } static void printError(OSStatus err) { switch (err) { case kAudioHardwareNoError: printf("error code : kAudioHardwareNoError\n"); break; case kAudioConverterErr_FormatNotSupported: printf("error code : kAudioConverterErr_FormatNotSupported\n"); break; case kAudioConverterErr_OperationNotSupported: printf("error code : kAudioConverterErr_OperationNotSupported\n"); break; case kAudioConverterErr_PropertyNotSupported: printf("error code : kAudioConverterErr_PropertyNotSupported\n"); break; case kAudioConverterErr_InvalidInputSize: printf("error code : kAudioConverterErr_InvalidInputSize\n"); break; case kAudioConverterErr_InvalidOutputSize: printf("error code : kAudioConverterErr_InvalidOutputSize\n"); break; case kAudioConverterErr_UnspecifiedError: printf("error code : kAudioConverterErr_UnspecifiedError\n"); break; case kAudioConverterErr_BadPropertySizeError: printf("error code : kAudioConverterErr_BadPropertySizeError\n"); break; case kAudioConverterErr_RequiresPacketDescriptionsError: printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); break; case kAudioConverterErr_InputSampleRateOutOfRange: printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); break; case kAudioConverterErr_OutputSampleRateOutOfRange: printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); break; case kAudioHardwareNotRunningError: printf("error code : kAudioHardwareNotRunningError\n"); break; case kAudioHardwareUnknownPropertyError: printf("error code : kAudioHardwareUnknownPropertyError\n"); break; case kAudioHardwareIllegalOperationError: printf("error code : kAudioHardwareIllegalOperationError\n"); break; case kAudioHardwareBadDeviceError: printf("error code : kAudioHardwareBadDeviceError\n"); break; case kAudioHardwareBadStreamError: printf("error code : kAudioHardwareBadStreamError\n"); break; case kAudioDeviceUnsupportedFormatError: printf("error code : kAudioDeviceUnsupportedFormatError\n"); break; case kAudioDevicePermissionsError: printf("error code : kAudioDevicePermissionsError\n"); break; default: printf("error code : unknown\n"); break; } } OSStatus TCoreAudioRenderer::Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32, UInt32 inNumberFrames, AudioBufferList *ioData) { TCoreAudioRendererPtr renderer = (TCoreAudioRendererPtr)inRefCon; AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fInputData); for (int i = 0; i < renderer->fDevNumInChans; i++) { renderer->fInChannel[i] = (float*)renderer->fInputData->mBuffers[i].mData; } for (int i = 0; i < renderer->fDevNumOutChans; i++) { renderer->fOutChannel[i] = (float*)ioData->mBuffers[i].mData; } renderer->compute((int)inNumberFrames); return 0; } static CFStringRef GetDeviceName(AudioDeviceID id) { UInt32 size = sizeof(CFStringRef); CFStringRef UIname; OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); return (err == noErr) ? UIname : NULL; } OSStatus TCoreAudioRenderer::GetDeviceNameFromID(AudioDeviceID id, char* name) { UInt32 size = 256; return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name); } OSStatus TCoreAudioRenderer::GetDefaultDevice(int inChan, int outChan, int samplerate, AudioDeviceID* id) { UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; AudioDeviceID outDefault; OSStatus res; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) return res; if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) return res; // Duplex mode if (inChan > 0 && outChan > 0) { // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; } else { printf("GetDefaultDevice : input = %uld and output = %uld are not the same, create aggregate device...\n", inDefault, outDefault); if (CreateAggregateDevice(inDefault, outDefault, samplerate, id) != noErr) return kAudioHardwareBadDeviceError; } } else if (inChan > 0) { *id = inDefault; return noErr; } else if (outChan > 0) { *id = outDefault; return noErr; } else { return kAudioHardwareBadDeviceError; } return noErr; } OSStatus TCoreAudioRenderer::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice) { OSStatus err = noErr; AudioObjectID sub_device[32]; UInt32 outSize = sizeof(sub_device); err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector captureDeviceIDArray; if (err != noErr) { printf("Input device does not have subdevices\n"); captureDeviceIDArray.push_back(captureDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); printf("Input device has %d subdevices\n", num_devices); for (int i = 0; i < num_devices; i++) { captureDeviceIDArray.push_back(sub_device[i]); } } err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); vector playbackDeviceIDArray; if (err != noErr) { printf("Output device does not have subdevices\n"); playbackDeviceIDArray.push_back(playbackDeviceID); } else { int num_devices = outSize / sizeof(AudioObjectID); printf("Output device has %d subdevices\n", num_devices); for (int i = 0; i < num_devices; i++) { playbackDeviceIDArray.push_back(sub_device[i]); } } return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); } OSStatus TCoreAudioRenderer::SRNotificationCallback(AudioDeviceID inDevice, UInt32 /*inChannel*/, Boolean /*isInput*/, AudioDevicePropertyID inPropertyID, void* inClientData) { TCoreAudioRenderer* driver = (TCoreAudioRenderer*)inClientData; switch (inPropertyID) { case kAudioDevicePropertyNominalSampleRate: { printf("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate\n"); driver->fState = true; // Check new sample rate Float64 sampleRate; UInt32 outSize = sizeof(Float64); OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); } else { printf("SRNotificationCallback : checked sample rate = %f\n", sampleRate); } break; } } return noErr; } int TCoreAudioRenderer::SetupSampleRateAux(AudioDeviceID inDevice, int samplerate) { OSStatus err = noErr; UInt32 outSize; Float64 sampleRate; // Get sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); return -1; } else { printf("Current sample rate = %f\n", sampleRate); } // If needed, set new sample rate if (samplerate != (int)sampleRate) { sampleRate = (Float64)samplerate; // To get SR change notification err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { printf("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate\n"); printError(err); return -1; } err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { printf("Cannot set sample rate = %d\n", samplerate); printError(err); return -1; } // Waiting for SR change notification int count = 0; while (!fState && count++ < WAIT_COUNTER) { usleep(100000); printf("Wait count = %d\n", count); } // Check new sample rate outSize = sizeof(Float64); err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); } else { printf("Checked sample rate = %f\n", sampleRate); } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; } OSStatus TCoreAudioRenderer::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, int samplerate, AudioDeviceID* outAggregateDevice) { OSStatus osErr = noErr; UInt32 outSize; Boolean outWritable; bool fClockDriftCompensate = true; // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; UInt32 theQualifierDataSize = sizeof(AudioObjectID); AudioClassID inClass = kAudioSubDeviceClassID; void* theQualifierData = &inClass; UInt32 subDevicesNum = 0; //--------------------------------------------------------------------------- // Setup SR of both devices otherwise creating AD may fail... //--------------------------------------------------------------------------- UInt32 keptclockdomain = 0; UInt32 clockdomain = 0; outSize = sizeof(UInt32); bool need_clock_drift_compensation = false; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of input device\n"); } else { // Check clock domain osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; printf("TCoreAudioRenderer::CreateAggregateDevice : input clockdomain = %d\n", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n"); need_clock_drift_compensation = true; } } } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : cannot set SR of output device\n"); } else { // Check clock domain osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); if (osErr != 0) { printf("TCoreAudioRenderer::CreateAggregateDevice : kAudioDevicePropertyClockDomain error\n"); printError(osErr); } else { keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; printf("TCoreAudioRenderer::CreateAggregateDevice : output clockdomain = %d", clockdomain); if (clockdomain != 0 && clockdomain != keptclockdomain) { printf("TCoreAudioRenderer::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed...\n"); need_clock_drift_compensation = true; } } } } // If no valid clock domain was found, then assume we have to compensate... if (keptclockdomain == 0) { need_clock_drift_compensation = true; } //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin //--------------------------------------------------------------------------- char device_name[256]; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { GetDeviceNameFromID(captureDeviceID[i], device_name); printf("Separated input = '%s' \n", device_name); } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { GetDeviceNameFromID(playbackDeviceID[i], device_name); printf("Separated output = '%s' \n", device_name); } osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error\n"); printError(osErr); return osErr; } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); pluginAVT.mOutputData = &fPluginID; pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error\n"); printError(osErr); return osErr; } //------------------------------------------------- // Create a CFDictionary for our aggregate device //------------------------------------------------- CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); // add the name of the device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); // add our choice of UID for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); // add a "private aggregate key" to the dictionary int value = 1; CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); SInt32 system; Gestalt(gestaltSystemVersion, &system); printf("TCoreAudioRenderer::CreateAggregateDevice : system version = %x limit = %x\n", system, 0x00001054); // Starting with 10.5.4 systems, the AD can be internal... (better) if (system < 0x00001054) { printf("TCoreAudioRenderer::CreateAggregateDevice : public aggregate device....\n"); } else { printf("TCoreAudioRenderer::CreateAggregateDevice : private aggregate device....\n"); CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); } // Prepare sub-devices for clock drift compensation CFMutableArrayRef subDevicesArrayClock = NULL; /* if (fClockDriftCompensate) { if (need_clock_drift_compensation) { jack_info("Clock drift compensation activated..."); subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(captureDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef UID = GetDeviceName(playbackDeviceID[i]); if (UID) { CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); //CFRelease(UID); CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); } } // add sub-device clock array for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); } else { jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); } } */ //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); vector captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); if (ref == NULL) return -1; captureDeviceUID.push_back(ref); // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } vector playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); if (ref == NULL) return -1; playbackDeviceUID.push_back(ref); // output sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); } //----------------------------------------------------------------------- // Feed the dictionary to the plugin, to create a blank aggregate device //----------------------------------------------------------------------- AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyDataSize error\n"); printError(osErr); goto error; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectGetPropertyData error\n"); printError(osErr); goto error; } // pause for a bit to make sure that everything completed correctly // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //------------------------- // Set the sub-device list //------------------------- pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error\n"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //----------------------- // Set the master device //----------------------- // set the master device manually (this is the device which will act as the master clock for the aggregate device) // pass in the UID of the device you want to use pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice : AudioObjectSetPropertyData for master device error\n"); printError(osErr); goto error; } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); // Prepare sub-devices for clock drift compensation // Workaround for bug in the HAL : until 10.6.2 if (fClockDriftCompensate) { if (need_clock_drift_compensation) { printf("Clock drift compensation activated...\n"); // Get the property data size osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n"); printError(osErr); } // Calculate the number of object IDs subDevicesNum = outSize / sizeof(AudioObjectID); printf("TCoreAudioRenderer::CreateAggregateDevice clock drift compensation, number of sub-devices = %d\n", subDevicesNum); AudioObjectID subDevices[subDevicesNum]; outSize = sizeof(subDevices); osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error\n"); printError(osErr); } // Set kAudioSubDevicePropertyDriftCompensation property... for (UInt32 index = 0; index < subDevicesNum; ++index) { UInt32 theDriftCompensationValue = 1; osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); if (osErr != noErr) { printf("TCoreAudioRenderer::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error\n"); printError(osErr); } } } else { printf("Clock drift compensation was asked but is not needed (devices use the same clock domain)\n"); } } // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); //---------- // Clean up //---------- // release the private AD key CFRelease(AggregateDeviceNumberRef); // release the CF objects we have created - we don't need them any more CFRelease(aggDeviceDict); CFRelease(subDevicesArray); if (subDevicesArrayClock) CFRelease(subDevicesArrayClock); // release the device UID for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { CFRelease(captureDeviceUID[i]); } for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { CFRelease(playbackDeviceUID[i]); } printf("New aggregate device %d\n", *outAggregateDevice); return noErr; error: DestroyAggregateDevice(); return -1; } OSStatus TCoreAudioRenderer::DestroyAggregateDevice() { OSStatus osErr = noErr; AudioObjectPropertyAddress pluginAOPA; pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; if (fPluginID > 0) { osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); if (osErr != noErr) { printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error\n"); printError(osErr); return osErr; } osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); if (osErr != noErr) { printf("TCoreAudioRenderer::DestroyAggregateDevice : AudioObjectGetPropertyData error\n"); printError(osErr); return osErr; } } return noErr; } long TCoreAudioRenderer::OpenDefault(dsp* dsp, long inChan, long outChan, long bufferSize, long samplerate) { OSStatus err = noErr; ComponentResult err1; UInt32 outSize; UInt32 enableIO; Boolean isWritable; AudioStreamBasicDescription srcFormat, dstFormat, sampleRate; long in_nChannels, out_nChannels; fDSP = dsp; fDevNumInChans = inChan; fDevNumOutChans = outChan; fInChannel = new float*[fDevNumInChans]; fOutChannel = new float*[fDevNumOutChans]; printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld samplerate = %ld\n", inChan, outChan, bufferSize, samplerate); SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (osErr != noErr) { printf("TCoreAudioRenderer::Open kAudioHardwarePropertyRunLoop error\n"); printError(osErr); } } if (GetDefaultDevice(inChan, outChan, samplerate,&fDeviceID) != noErr) { printf("Cannot open default device\n"); return OPEN_ERR; } // Setting buffer size outSize = sizeof(UInt32); err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &bufferSize); if (err != noErr) { printf("Cannot set buffer size %ld\n", bufferSize); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyBufferFrameSize, &outSize, &bufferSize); if (err != noErr) { printf("Cannot get buffer size %ld\n", bufferSize); printError(err); return OPEN_ERR; } else { printf("Use fixed buffer size %ld\n", bufferSize); } } // Setting sample rate outSize = sizeof(AudioStreamBasicDescription); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, &sampleRate); if (err != noErr) { printf("Cannot get current sample rate\n"); printError(err); return OPEN_ERR; } if (samplerate != long(sampleRate.mSampleRate)) { sampleRate.mSampleRate = (Float64)(samplerate); err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate); if (err != noErr) { printf("Cannot set sample rate = %ld\n", samplerate); printError(err); return OPEN_ERR; } } // AUHAL ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0}; Component HALOutput = FindNextComponent(NULL, &cd); err1 = OpenAComponent(HALOutput, &fAUHAL); if (err1 != noErr) { printf("Error calling OpenAComponent\n"); printError(err1); goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { printf("Cannot initialize AUHAL unit\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); printError(err1); goto error; } enableIO = 1; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); printError(err1); goto error; } err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n"); printError(err1); } in_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0; printf("in_nChannels = %ld\n", in_nChannels); err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n"); printError(err1); } out_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0; printf("out_nChannels = %ld\n", out_nChannels); /* Just ignore this case : seems to work without any further change... if (outChan > out_nChannels) { printf("This device hasn't required output channels\n"); goto error; } if (inChan > in_nChannels) { printf("This device hasn't required input channels\n"); goto error; } */ if (outChan < out_nChannels) { SInt32 chanArr[out_nChannels]; for (int i = 0; i < out_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < outChan; i++) { chanArr[i] = i; } err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n"); printError(err1); } } if (inChan < in_nChannels) { SInt32 chanArr[in_nChannels]; for (int i = 0; i < in_nChannels; i++) { chanArr[i] = -1; } for (int i = 0; i < inChan; i++) { chanArr[i] = i; } AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n"); printError(err1); } } if (inChan > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&srcFormat); srcFormat.mSampleRate = samplerate; srcFormat.mFormatID = kAudioFormatLinearPCM; srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; srcFormat.mBytesPerPacket = sizeof(float); srcFormat.mFramesPerPacket = 1; srcFormat.mBytesPerFrame = sizeof(float); srcFormat.mChannelsPerFrame = inChan; srcFormat.mBitsPerChannel = 32; PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (outChan > 0) { outSize = sizeof(AudioStreamBasicDescription); err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); if (err1 != noErr) { printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } PrintStreamDesc(&dstFormat); dstFormat.mSampleRate = samplerate; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; dstFormat.mBytesPerPacket = sizeof(float); dstFormat.mFramesPerPacket = 1; dstFormat.mBytesPerFrame = sizeof(float); dstFormat.mChannelsPerFrame = outChan; dstFormat.mBitsPerChannel = 32; PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); printError(err1); } } if (inChan > 0 && outChan == 0) { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); printError(err1); goto error; } } else { AURenderCallbackStruct output; output.inputProc = Render; output.inputProcRefCon = this; err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); printError(err1); goto error; } } fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer)); if (fInputData == 0) { printf("Cannot allocate memory for input buffers\n"); goto error; } fInputData->mNumberBuffers = inChan; // Prepare buffers for (int i = 0; i < inChan; i++) { fInputData->mBuffers[i].mNumberChannels = 1; fInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float)); fInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float); } return NO_ERR; error: AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); return OPEN_ERR; } long TCoreAudioRenderer::Close() { if (!fAUHAL) { return CLOSE_ERR; } for (int i = 0; i < fDevNumInChans; i++) { free(fInputData->mBuffers[i].mData); } free(fInputData); AudioUnitUninitialize(fAUHAL); CloseComponent(fAUHAL); DestroyAggregateDevice(); delete[] fInChannel; delete[] fOutChannel; return NO_ERR; } long TCoreAudioRenderer::Start() { if (!fAUHAL) { return OPEN_ERR; } OSStatus err = AudioOutputUnitStart(fAUHAL); if (err != noErr) { printf("Error while opening device : device open error \n"); return OPEN_ERR; } else { return NO_ERR; } } long TCoreAudioRenderer::Stop() { if (!fAUHAL) { return OPEN_ERR; } OSStatus err = AudioOutputUnitStop(fAUHAL); if (err != noErr) { printf("Error while closing device : device close error \n"); return OPEN_ERR; } else { return NO_ERR; } } /****************************************************************************** ******************************************************************************* CORE AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class coreaudio : public audio { TCoreAudioRenderer audio_device; long fSampleRate, fFramesPerBuf; public: coreaudio(long srate, long fpb) : fSampleRate(srate), fFramesPerBuf(fpb) {} virtual ~coreaudio() {} virtual bool init(const char* /*name*/, dsp* DSP) { DSP->init(fSampleRate); if (audio_device.OpenDefault(DSP, DSP->getNumInputs(), DSP->getNumOutputs(), fFramesPerBuf, fSampleRate) < 0) { printf("Cannot open CoreAudio device\n"); return false; } return true; } virtual bool start() { if (audio_device.Start() < 0) { printf("Cannot start CoreAudio device\n"); return false; } return true; } virtual void stop() { audio_device.Stop(); audio_device.Close(); } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/faudiostream/architecture/faust/audio/dsp.h000066400000000000000000000025501210074205700256010ustar00rootroot00000000000000 /****************************************************************************** ******************************************************************************* FAUST DSP ******************************************************************************* *******************************************************************************/ #ifndef __dsp__ #define __dsp__ #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif class UI; //---------------------------------------------------------------- // signal processor definition //---------------------------------------------------------------- class dsp { protected: int fSamplingFreq; public: dsp() {} virtual ~dsp() {} virtual int getNumInputs() = 0; virtual int getNumOutputs() = 0; virtual void buildUserInterface(UI* interface) = 0; virtual void init(int samplingRate) = 0; virtual void instanceInit(int samplingFreq) = 0; virtual void compute(int len, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0; }; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) // flags to avoid costly denormals #ifdef __SSE__ #include #ifdef __SSE2__ #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) #else #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) #endif #else #define AVOIDDENORMALS #endif #endif radium_compressor-0.5.1/faudiostream/architecture/faust/audio/jack-dsp.h000066400000000000000000000106571210074205700265160ustar00rootroot00000000000000 #ifndef __jack_dsp__ #define __jack_dsp__ #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" static int _srate(jack_nframes_t nframes, void *); static void _jack_shutdown(void *); static int _process (jack_nframes_t nframes, void *client); #ifdef _OPENMP static void* _jackthread(void* arg); #endif /****************************************************************************** ******************************************************************************* JACK AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class jackaudio : public audio { dsp* fDsp; jack_client_t* fClient; int fNumInChans; // number of input channels int fNumOutChans; // number of output channels jack_port_t * fInput_ports[256]; // Jack input ports jack_port_t * fOutput_ports[256]; // Jack output ports float* fInChannel[256]; // tables of noninterleaved input channels for FAUST float* fOutChannel[256]; // tables of noninterleaved output channels for FAUST public: jackaudio() : fClient(0), fNumInChans(0), fNumOutChans(0) {} virtual ~jackaudio() { stop(); } virtual bool init(const char*name, dsp* DSP) { fDsp = DSP; if ((fClient = jack_client_open(name, JackNullOption, NULL)) == 0) { fprintf(stderr, "jack server not running?\n"); return false; } #ifdef _OPENMP jack_set_process_thread(fClient, _jackthread, this); #else jack_set_process_callback(fClient, _process, this); #endif jack_set_sample_rate_callback(fClient, _srate, 0); jack_on_shutdown(fClient, _jack_shutdown, 0); fNumInChans = fDsp->getNumInputs(); fNumOutChans = fDsp->getNumOutputs(); for (int i = 0; i < fNumInChans; i++) { char buf[256]; snprintf(buf, 256, "in_%d", i); fInput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); } for (int i = 0; i < fNumOutChans; i++) { char buf[256]; snprintf(buf, 256, "out_%d", i); fOutput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } fDsp->init(jack_get_sample_rate(fClient)); return true; } virtual bool start() { if (jack_activate(fClient)) { fprintf(stderr, "cannot activate client"); return false; } char** physicalInPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsInput); char** physicalOutPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (physicalOutPorts != NULL) { for (int i = 0; i < fNumInChans && physicalOutPorts[i]; i++) jack_connect(fClient, physicalOutPorts[i], jack_port_name(fInput_ports[i])); } if (physicalInPorts != NULL) { for (int i = 0; i < fNumOutChans && physicalInPorts[i]; i++) jack_connect(fClient, jack_port_name(fOutput_ports[i]), physicalInPorts[i]); } return true; } virtual void stop() { if (fClient) { jack_deactivate(fClient); for (int i = 0; i < fNumInChans; i++) jack_port_unregister(fClient, fInput_ports[i]); for (int i = 0; i < fNumOutChans; i++) jack_port_unregister(fClient, fOutput_ports[i]); jack_client_close(fClient); fClient = 0; } } // jack callbacks int process (jack_nframes_t nframes) { AVOIDDENORMALS; for (int i = 0; i < fNumInChans; i++) fInChannel[i] = (float *)jack_port_get_buffer(fInput_ports[i], nframes); for (int i = 0; i < fNumOutChans; i++) fOutChannel[i] = (float *)jack_port_get_buffer(fOutput_ports[i], nframes); fDsp->compute(nframes, fInChannel, fOutChannel); return 0; } #ifdef _OPENMP void process_thread () { jack_nframes_t nframes; while (1) { nframes = jack_cycle_wait(fClient); process (nframes); jack_cycle_signal(fClient, 0); } } #endif }; //---------------------------------------------------------------------------- // Jack Callbacks //---------------------------------------------------------------------------- static int _srate(jack_nframes_t nframes, void *) { printf("the sample rate is now %u/sec\n", nframes); return 0; } static void _jack_shutdown(void *) { exit(1); } static int _process(jack_nframes_t nframes, void *client) { jackaudio* jackclient = (jackaudio*)client; return jackclient->process (nframes); } #ifdef _OPENMP static void* _jackthread(void* arg) { jackaudio* jackclient = (jackaudio*)arg; jackclient->process_thread(); return 0; } #endif #endif radium_compressor-0.5.1/faudiostream/architecture/faust/audio/netjack-dsp.h000066400000000000000000000103741210074205700272210ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __netjack_dsp__ #define __netjack_dsp__ #include "faust/audio/audio.h" #include "faust/audio/dsp.h" #include #include class netjackaudio : public audio { dsp* fDsp; jack_net_slave_t* fNet; int fCelt; std::string fMasterIP; int fMasterPort; static void net_shutdown(void *) { printf("Network failure, restart...\n"); } static int net_process(jack_nframes_t buffer_size, int, float** audio_input_buffer, int, void**, int, float** audio_output_buffer, int, void**, void* arg) { AVOIDDENORMALS; netjackaudio* obj = (netjackaudio*)arg; obj->fDsp->compute(buffer_size, audio_input_buffer, audio_output_buffer); return 0; } public: netjackaudio(int celt, const std::string master_ip, int master_port) :fCelt(celt), fMasterIP(master_ip), fMasterPort(master_port) {} bool init(const char* name, dsp* DSP) { fDsp = DSP; jack_slave_t request = { DSP->getNumInputs(), DSP->getNumOutputs(), 0, 0, DEFAULT_MTU, -1, (fCelt > 0) ? JackCeltEncoder: JackFloatEncoder, (fCelt > 0) ? fCelt : 0, 2 }; jack_master_t result; if ((fNet = jack_net_slave_open(fMasterIP.c_str(), fMasterPort, name, &request, &result)) == 0) { printf("jack remote server not running ?\n"); return false; } jack_set_net_slave_process_callback(fNet, net_process, this); jack_set_net_slave_shutdown_callback(fNet, net_shutdown, 0); fDsp->init(result.sample_rate); return true; } bool start() { if (jack_net_slave_activate(fNet)) { printf("cannot activate net"); return false; } return true; } void stop() { jack_net_slave_deactivate(fNet); jack_net_slave_close(fNet); } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/faudiostream/architecture/faust/audio/oscdsp.h000066400000000000000000000035451210074205700263130ustar00rootroot00000000000000 #ifndef __osc_dsp__ #define __osc_dsp__ #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" #include "OSCIO.h" /****************************************************************************** ******************************************************************************* OSC AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ #define kMaxBuffer 4096 class oscdsp : public audio, public oscfaust::OSCIO { dsp* fDsp; float ** fInBuffers, **fOutBuffers; public: oscdsp(const char * dst, int argc, char *argv[]) : OSCIO(dst), fDsp(0), fInBuffers(0), fOutBuffers(0) { for (int i = 1; i < argc-1; i++) if (!strcmp(argv[i], "-iodst")) setDest (argv[i+1]); } virtual ~oscdsp() { stop(); } virtual bool init(const char*name, dsp* DSP) { fDsp = DSP; fDsp->init(44100); fInBuffers = new float*[numInputs()]; fOutBuffers = new float*[numOutputs()]; for (int i= 0; i < numInputs(); i++) fInBuffers[i] = new float[kMaxBuffer]; for (int i= 0; i < numOutputs(); i++) fOutBuffers [i] = new float[kMaxBuffer]; return true; } virtual bool start() { return true; } virtual void stop() {} void compute( int nframes ) { fDsp->compute(nframes, fInBuffers, fOutBuffers); for (int i= 0; i < numOutputs(); i++) send( nframes, fOutBuffers [i], i); } void receive( int nvalues, float * val ) { int inChans = numInputs(); if (!inChans) { compute(nvalues); return; } for (int i=0; i < nvalues; i++) { int c = i % inChans; int frame = i / inChans; fInBuffers[c][frame] = val[i]; } compute (nvalues / inChans); } int numOutputs() const { return fDsp ? fDsp->getNumOutputs() : 0; } int numInputs() const { return fDsp ? fDsp->getNumInputs() : 0; } }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/audio/portaudio-dsp.h000066400000000000000000000177131210074205700276140ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __portaudio_dsp__ #define __portaudio_dsp__ #include #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void * drv); static bool pa_error(int err) { if (err != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return true; } else { return false; } } /****************************************************************************** ******************************************************************************* PORT AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class portaudio : public audio { private: dsp* fDsp; PaStream* fAudioStream; long fSampleRate; long fBufferSize; //---------------------------------------------------------------------------- // number of physical input and output channels of the PA device //---------------------------------------------------------------------------- int fDevNumInChans; int fDevNumOutChans; //---------------------------------------------------------------------------- // tables of noninterleaved input and output channels for FAUST //---------------------------------------------------------------------------- float** fInChannel; float** fOutChannel; //---------------------------------------------------------------------------- // allocated the noninterleaved input and output channels for FAUST //---------------------------------------------------------------------------- void allocChannels(int size, int numInChan, int numOutChan) { fInChannel = new float*[numInChan]; fOutChannel = new float*[numOutChan]; for (int i = 0; i < numInChan; i++) { fInChannel[i] = (float*) calloc (size, sizeof(float)); for (int j = 0; j < size; j++) fInChannel[i][j] = 0.0; } for (int i = 0; i < numOutChan; i++) { fOutChannel[i] = (float*) calloc (size, sizeof(float)); for (int j = 0; j < size; j++) fOutChannel[i][j] = 0.0; } } public: portaudio(long srate, long bsize) : fDsp(0), fAudioStream(0), fSampleRate(srate), fBufferSize(bsize), fDevNumInChans(0), fDevNumOutChans(0) {} virtual ~portaudio() { stop(); delete [] fInChannel; delete [] fOutChannel; } virtual bool init(const char* name, dsp* DSP) { fDsp = DSP; if (pa_error(Pa_Initialize())) { return false; } const PaDeviceInfo* idev = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice()); const PaDeviceInfo* odev = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice()); fDevNumInChans = (fDsp->getNumInputs() > 0) ? idev->maxInputChannels : 0; fDevNumOutChans = (fDsp->getNumOutputs() > 0) ? odev->maxOutputChannels : 0; PaStreamParameters inputParameters; PaStreamParameters outputParameters; inputParameters.device = Pa_GetDefaultInputDevice(); inputParameters.sampleFormat = paFloat32; inputParameters.channelCount = fDevNumInChans; inputParameters.hostApiSpecificStreamInfo = 0; outputParameters.device = Pa_GetDefaultOutputDevice(); outputParameters.sampleFormat = paFloat32; outputParameters.channelCount = fDevNumOutChans; outputParameters.hostApiSpecificStreamInfo = 0; PaError err; if ((err = Pa_IsFormatSupported( ((fDevNumInChans > 0) ? &inputParameters : 0), ((fDevNumOutChans > 0) ? &outputParameters : 0), fSampleRate)) != 0) { printf("stream format is not supported err = %d\n", err); return false; } allocChannels(fBufferSize, max(fDevNumInChans, fDsp->getNumInputs()), max(fDevNumOutChans, fDsp->getNumOutputs())); fDsp->init(fSampleRate); return true; } virtual bool start() { if (pa_error(Pa_OpenDefaultStream(&fAudioStream, fDevNumInChans, fDevNumOutChans, paFloat32, fSampleRate, fBufferSize, audioCallback, this))) { return false; } if (pa_error(Pa_StartStream(fAudioStream)) { return false; } return true; } virtual void stop() { if (fAudioStream) { Pa_StopStream (fAudioStream); Pa_CloseStream(fAudioStream); fAudioStream = 0; } } int processAudio(const float* ibuf, float* obuf, unsigned long frames) { const float* fInputBuffer = ibuf; float* fOutputBuffer = obuf; // split input samples for (unsigned long s = 0; s < frames; s++) { for (int c = 0; c < fDevNumInChans; c++) { fInChannel[c][s] = fInputBuffer[c + s*fDevNumInChans]; } } // process samples fDsp->compute(frames, fInChannel, fOutChannel); // merge output samples for (unsigned long s = 0; s < frames; s++) { for (int c = 0; c < fDevNumOutChans; c++) { fOutputBuffer[c + s*fDevNumOutChans] = fOutChannel[c][s]; } } return 0; } }; //---------------------------------------------------------------------------- // Port Audio Callback //---------------------------------------------------------------------------- static int audioCallback(const void* ibuf, void* obuf, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* drv) { portaudio* pa = (portaudio*) drv; return pa->processAudio((const float*)ibuf, (float*)obuf, frames); } #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/000077500000000000000000000000001210074205700243235ustar00rootroot00000000000000radium_compressor-0.5.1/faudiostream/architecture/faust/gui/FUI.h000066400000000000000000000075011210074205700251220ustar00rootroot00000000000000#ifndef FAUST_FUI_H #define FAUST_FUI_H #include "faust/gui/UI.h" #include #include #include #include #include #include #include using namespace std; #if 1 /******************************************************************************* * FUI : used to save and recall the state of the user interface * This class provides essentially two new methods saveState() and recallState() * used to save on file and recall from file the state of the user interface. * The file is human readble and editable ******************************************************************************/ class FUI : public UI { stack fGroupStack; vector fNameList; map fName2Zone; protected: // labels are normalized by replacing white spaces by underscores and by // removing parenthesis string normalizeLabel(const char* label) { string s; char c; while ((c=*label++)) { if (isspace(c)) { s += '_'; } //else if ((c == '(') | (c == ')') ) { } else { s += c; } } return s; } // add an element by relating its full name and memory zone virtual void addElement(const char* label, FAUSTFLOAT* zone) { string fullname (fGroupStack.top() + '/' + normalizeLabel(label)); fNameList.push_back(fullname); fName2Zone[fullname] = zone; } // keep track of full group names in a stack virtual void pushGroupLabel(const char* label) { if (fGroupStack.empty()) { fGroupStack.push(normalizeLabel(label)); } else { fGroupStack.push(fGroupStack.top() + '/' + normalizeLabel(label)); } } virtual void popGroupLabel() { fGroupStack.pop(); }; public: FUI() {} virtual ~FUI() {} // -- Save and recall methods // save the zones values and full names virtual void saveState(const char* filename) { ofstream f(filename); for (unsigned int i=0; i> v >> n; if (fName2Zone.count(n)>0) { *(fName2Zone[n]) = v; } else { cerr << "recallState : parameter not found : " << n.c_str() << " with value : " << v << endl; } } f.close(); } // -- widget's layouts (just keep track of group labels) virtual void openTabBox(const char* label) { pushGroupLabel(label); } virtual void openHorizontalBox(const char* label) { pushGroupLabel(label); } virtual void openVerticalBox(const char* label) { pushGroupLabel(label); } virtual void closeBox() { popGroupLabel(); }; // -- active widgets (just add an element) virtual void addButton(const char* label, FAUSTFLOAT* zone) { addElement(label, zone); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { addElement(label, zone); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT , FAUSTFLOAT) { addElement(label, zone); } // -- passive widgets (are ignored) virtual void addHorizontalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {}; virtual void addVerticalBargraph(const char*, FAUSTFLOAT*, FAUSTFLOAT, FAUSTFLOAT) {}; // -- metadata are not used virtual void declare(FAUSTFLOAT*, const char*, const char*) {} }; #endif #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/GUI.h000066400000000000000000000062261210074205700251260ustar00rootroot00000000000000#ifndef FAUST_GUI_H #define FAUST_GUI_H #include "faust/gui/UI.h" #include #include using namespace std; /******************************************************************************* * GUI : Abstract Graphic User Interface * Provides additional macchanismes to synchronize widgets and zones. Widgets * should both reflect the value of a zone and allow to change this value. ******************************************************************************/ struct uiItem; typedef void (*uiCallback)(FAUSTFLOAT val, void* data); class GUI : public UI { typedef list clist; typedef map zmap; private: static list fGuiList; zmap fZoneMap; bool fStopped; public: GUI() : fStopped(false) { fGuiList.push_back(this); } virtual ~GUI() { // suppression de this dans fGuiList } // -- registerZone(z,c) : zone management void registerZone(FAUSTFLOAT* z, uiItem* c) { if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist(); fZoneMap[z]->push_back(c); } void updateAllZones(); void updateZone(FAUSTFLOAT* z); static void updateAllGuis() { list::iterator g; for (g = fGuiList.begin(); g != fGuiList.end(); g++) { (*g)->updateAllZones(); } } void addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data); virtual void show() {}; virtual void run() {}; void stop() { fStopped = true; } bool stopped() { return fStopped; } virtual void declare(FAUSTFLOAT* , const char* , const char* ) {} }; /** * User Interface Item: abstract definition */ class uiItem { protected : GUI* fGUI; FAUSTFLOAT* fZone; FAUSTFLOAT fCache; uiItem (GUI* ui, FAUSTFLOAT* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321) { ui->registerZone(zone, this); } public : virtual ~uiItem() {} void modifyZone(FAUSTFLOAT v) { fCache = v; if (*fZone != v) { *fZone = v; fGUI->updateZone(fZone); } } FAUSTFLOAT cache() { return fCache; } virtual void reflectZone() = 0; }; /** * Callback Item */ struct uiCallbackItem : public uiItem { uiCallback fCallback; void* fData; uiCallbackItem(GUI* ui, FAUSTFLOAT* zone, uiCallback foo, void* data) : uiItem(ui, zone), fCallback(foo), fData(data) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fCallback(v, fData); } }; // en cours d'installation de call back. a finir!!!!! /** * Update all user items reflecting zone z */ inline void GUI::updateZone(FAUSTFLOAT* z) { FAUSTFLOAT v = *z; clist* l = fZoneMap[z]; for (clist::iterator c = l->begin(); c != l->end(); c++) { if ((*c)->cache() != v) (*c)->reflectZone(); } } /** * Update all user items not up to date */ inline void GUI::updateAllZones() { for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) { FAUSTFLOAT* z = m->first; clist* l = m->second; FAUSTFLOAT v = *z; for (clist::iterator c = l->begin(); c != l->end(); c++) { if ((*c)->cache() != v) (*c)->reflectZone(); } } } inline void GUI::addCallback(FAUSTFLOAT* zone, uiCallback foo, void* data) { new uiCallbackItem(this, zone, foo, data); }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/OSCUI.h000066400000000000000000000104511210074205700253570ustar00rootroot00000000000000/* Copyright (C) 2011 Grame - Lyon All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted. */ #include "faust/gui/OSCControler.h" #include "faust/gui/GUI.h" #include /****************************************************************************** ******************************************************************************* OSC (Open Sound Control) USER INTERFACE ******************************************************************************* *******************************************************************************/ /* Note about the OSC addresses and the Faust UI names: ---------------------------------------------------- There are potential conflicts between the Faust UI objects naming scheme and the OSC address space. An OSC symbolic names is an ASCII string consisting of printable characters other than the following: space # number sign * asterisk , comma / forward ? question mark [ open bracket ] close bracket { open curly brace } close curly brace a simple solution to address the problem consists in replacing space or tabulation with '_' (underscore) all the other osc excluded characters with '-' (hyphen) This solution is implemented in the proposed OSC UI; */ using namespace std; //class oscfaust::OSCIO; class OSCUI : public GUI { oscfaust::OSCControler* fCtrl; vector fAlias; const char* tr(const char* label) const; // add all accumulated alias void addalias(FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max) { for (unsigned int i=0; iaddfullpathnode(fAlias[i], zone, (FAUSTFLOAT)0, (FAUSTFLOAT)1, init, min, max); } fAlias.clear(); } public: OSCUI(char* /*applicationname*/, int argc, char *argv[], oscfaust::OSCIO* io=0) : GUI() { fCtrl = new oscfaust::OSCControler(argc, argv, io); // fCtrl->opengroup(applicationname); } virtual ~OSCUI() { delete fCtrl; } // -- widget's layouts virtual void openTabBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void openHorizontalBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void openVerticalBox(const char* label) { fCtrl->opengroup( tr(label)); } virtual void closeBox() { fCtrl->closegroup(); } // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) { addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { addalias(zone, 0, 0, 1); fCtrl->addnode( tr(label), zone, (FAUSTFLOAT)0, (FAUSTFLOAT)0, (FAUSTFLOAT)1); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT /*step*/) { addalias(zone, init, min, max); fCtrl->addnode( tr(label), zone, init, min, max); } // -- passive widgets virtual void addHorizontalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {} virtual void addVerticalBargraph(const char* /*label*/, FAUSTFLOAT* /*zone*/, FAUSTFLOAT /*min*/, FAUSTFLOAT /*max*/) {} // -- metadata declarations virtual void declare(FAUSTFLOAT* , const char* key , const char* alias) { if (strcasecmp(key,"OSC")==0) fAlias.push_back(alias); } virtual void show() {} void run() { fCtrl->run(); } const char* getRootName() { return fCtrl->getRootName(); } }; const char* OSCUI::tr(const char* label) const { static char buffer[1024]; char * ptr = buffer; int n=1; while (*label && (n++ < 1024)) { switch (*label) { case ' ': case ' ': *ptr++ = '_'; break; case '#': case '*': case ',': case '/': case '?': case '[': case ']': case '{': case '}': *ptr++ = '_'; break; default: *ptr++ = *label; } label++; } *ptr = 0; return buffer; } radium_compressor-0.5.1/faudiostream/architecture/faust/gui/UI.h000066400000000000000000000031441210074205700250130ustar00rootroot00000000000000#ifndef FAUST_UI_H #define FAUST_UI_H #ifndef FAUSTFLOAT #define FAUSTFLOAT float #endif /******************************************************************************* * UI : Faust User Interface * This abstract class contains only the method that the faust compiler can * generate to describe a DSP interface. ******************************************************************************/ class UI { public: UI() {} virtual ~UI() {} // -- widget's layouts virtual void openTabBox(const char* label) = 0; virtual void openHorizontalBox(const char* label) = 0; virtual void openVerticalBox(const char* label) = 0; virtual void closeBox() = 0; // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0; virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0; virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0; // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0; virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) = 0; // -- metadata declarations virtual void declare(FAUSTFLOAT*, const char*, const char*) {} }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/console.h000066400000000000000000000130241210074205700261360ustar00rootroot00000000000000/************************************************************************ IMPORTANT NOTE : this file contains two clearly delimited sections : the ARCHITECTURE section (in two parts) and the USER section. Each section is governed by its own copyright and license. Please check individually each section for license and copyright information. *************************************************************************/ /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ /************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . EXCEPTION : As a special exception, you may create a larger work that contains this FAUST architecture section and distribute that work under terms of your choice, so long as this FAUST architecture section is not modified. ************************************************************************ ************************************************************************/ #ifndef __faustconsole__ #define __faustconsole__ #include #include #include #include #include #include #include #include "faust/gui/GUI.h" using namespace std; /****************************************************************************** ******************************************************************************* USER INTERFACE ******************************************************************************* *******************************************************************************/ struct param { FAUSTFLOAT* fZone; FAUSTFLOAT fMin; FAUSTFLOAT fMax; param(FAUSTFLOAT* z, FAUSTFLOAT a, FAUSTFLOAT b) : fZone(z), fMin(a), fMax(b) {} }; class CMDUI : public GUI { int fArgc; char** fArgv; stack fPrefix; map fKeyParam; void addOption(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { string fullname = fPrefix.top() + label; fKeyParam.insert(make_pair(fullname, param(zone, min, max))); } void openAnyBox(const char* label) { string prefix; if (label && label[0]) { prefix = fPrefix.top() + "-" + label; } else { prefix = fPrefix.top(); } fPrefix.push(prefix); } public: CMDUI(int argc, char *argv[]) : GUI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } virtual ~CMDUI() {} virtual void openTabBox(const char* label) { openAnyBox(label); } virtual void openHorizontalBox(const char* label) { openAnyBox(label); } virtual void openVerticalBox(const char* label) { openAnyBox(label); } virtual void closeBox() { fPrefix.pop(); } virtual void addButton(const char* label, FAUSTFLOAT* zone) {}; virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) {}; virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { addOption(label,zone,min,max); } // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {} virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {} virtual void show() {} virtual void run() { char c; printf("Type 'q' to quit\n"); while ((c = getchar()) != 'q') { sleep(1); } } void print() { map::iterator i; cout << fArgc << "\n"; cout << fArgv[0] << " option list : "; for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; } cout << endl; } void process_command() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; print(); exit(1); } char* end; *(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end)); i++; } } } void process_init() { map::iterator p; for (int i = 1; i < fArgc; i++) { if (fArgv[i][0] == '-') { p = fKeyParam.find(fArgv[i]); if (p == fKeyParam.end()) { cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; exit(1); } char* end; *(p->second.fZone) = FAUSTFLOAT(strtod(fArgv[i+1], &end)); i++; } } } }; #endif /********************END ARCHITECTURE SECTION (part 2/2)****************/ radium_compressor-0.5.1/faudiostream/architecture/faust/gui/faustgtk.h000066400000000000000000001320711210074205700263300ustar00rootroot00000000000000#ifndef FAUST_GTKUI_H #define FAUST_GTKUI_H #include "faust/gui/GUI.h" /****************************************************************************** ******************************************************************************* GRAPHIC USER INTERFACE gtk interface ******************************************************************************* *******************************************************************************/ #include #include #include #include #include #include #include #include using namespace std; #define stackSize 256 // Insertion modes #define kSingleMode 0 #define kBoxMode 1 #define kTabMode 2 //------------ calculate needed precision static int precision(double n) { if (n < 0.009999) return 3; else if (n < 0.099999) return 2; else if (n < 0.999999) return 1; else return 0; } namespace gtk_knob { class GtkKnob { private: double start_x, start_y, max_value; public: GtkRange parent; int last_quadrant; GtkKnob(); ~GtkKnob(); GtkWidget *gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment); }; #define GTK_TYPE_KNOB (gtk_knob_get_type()) #define GTK_KNOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob)) #define GTK_IS_KNOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB)) #define GTK_KNOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_KNOB, GtkKnobClass)) #define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_KNOB)) GtkKnob::GtkKnob() // GtkKnob constructor {} GtkKnob::~GtkKnob() { // Nothing specific to do... } struct GtkKnobClass { GtkRangeClass parent_class; int knob_x; int knob_y; int knob_step; int button_is; }; //------forward declaration GType gtk_knob_get_type (); /**************************************************************** ** calculate the knop pointer with dead zone */ const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs static void knob_expose(GtkWidget *widget, int knob_x, int knob_y, GdkEventExpose *event, int arc_offset) { /** check resize **/ int grow; if(widget->allocation.width > widget->allocation.height) { grow = widget->allocation.height; } else { grow = widget->allocation.width; } knob_x = grow-4; knob_y = grow-4; /** get values for the knob **/ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int knobx = (widget->allocation.x+2 + (widget->allocation.width-4 - knob_x) * 0.5); int knoby = (widget->allocation.y+2 + (widget->allocation.height-4 - knob_y) * 0.5); int knobx1 = (widget->allocation.x+2 + (widget->allocation.width-4)* 0.5); int knoby1 = (widget->allocation.y+2 + (widget->allocation.height-4) * 0.5); double knobstate = (adj->value - adj->lower) / (adj->upper - adj->lower); double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero); double knobstate1 = (0. - adj->lower) / (adj->upper - adj->lower); double pointer_off = knob_x/6; double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2; double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle); double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle); double radius1 = min(knob_x, knob_y) / 2 ; /** get widget forground color convert to cairo **/ GtkStyle *style = gtk_widget_get_style (widget); double r = min(0.6,style->fg[gtk_widget_get_state(widget)].red/65535.0), g = min(0.6,style->fg[gtk_widget_get_state(widget)].green/65535.0), b = min(0.6,style->fg[gtk_widget_get_state(widget)].blue/65535.0); /** paint focus **/ if (GTK_WIDGET_HAS_FOCUS(widget)== TRUE) { gtk_paint_focus(widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, NULL, knobx-2, knoby-2, knob_x+4, knob_y+4); } /** create clowing knobs with cairo **/ cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); GdkRegion *region; region = gdk_region_rectangle (&widget->allocation); gdk_region_intersect (region, event->region); gdk_cairo_region (cr, region); cairo_clip (cr); cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI ); cairo_pattern_t*pat = cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 ); if(adj->lower<0 && adj->value>0.) { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } else if(adj->lower<0 && adj->value<=0.) { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } else { cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 +knobstate, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + knobstate*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b); } cairo_set_source (cr, pat); cairo_fill_preserve (cr); gdk_cairo_set_source_color(cr, gtk_widget_get_style (widget)->fg); cairo_set_line_width(cr, 2.0); cairo_stroke(cr); /** create a rotating pointer on the kob**/ cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); cairo_set_line_width(cr,max(3, min(7, knob_x/15))); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); cairo_move_to(cr, knobx+radius1, knoby+radius1); cairo_line_to(cr,lengh_x,lengh_y); cairo_stroke(cr); cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); cairo_set_line_width(cr,min(5, max(1,knob_x/30))); cairo_move_to(cr, knobx+radius1, knoby+radius1); cairo_line_to(cr,lengh_x,lengh_y); cairo_stroke(cr); cairo_pattern_destroy (pat); gdk_region_destroy (region); cairo_destroy(cr); } /**************************************************************** ** general expose events for all "knob" controllers */ //----------- draw the Knob when moved static gboolean gtk_knob_expose (GtkWidget *widget, GdkEventExpose *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); knob_expose(widget, klass->knob_x, klass->knob_y, event, 0); return TRUE; } /**************************************************************** ** set initial size for GdkDrawable per type */ static void gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); requisition->width = klass->knob_x; requisition->height = klass->knob_y; } /**************************************************************** ** set value from key bindings */ static void gtk_knob_set_value (GtkWidget *widget, int dir_down) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment); int step; int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment); if (dir_down) step = oldstep - 1; else step = oldstep + 1; FAUSTFLOAT value = adj->lower + step * double(adj->upper - adj->lower) / nsteps; gtk_widget_grab_focus(widget); gtk_range_set_value(GTK_RANGE(widget), value); } /**************************************************************** ** keyboard bindings */ static gboolean gtk_knob_key_press (GtkWidget *widget, GdkEventKey *event) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); switch (event->keyval) { case GDK_Home: gtk_range_set_value(GTK_RANGE(widget), adj->lower); return TRUE; case GDK_End: gtk_range_set_value(GTK_RANGE(widget), adj->upper); return TRUE; case GDK_Up: gtk_knob_set_value(widget, 0); return TRUE; case GDK_Right: gtk_knob_set_value(widget, 0); return TRUE; case GDK_Down: gtk_knob_set_value(widget, 1); return TRUE; case GDK_Left: gtk_knob_set_value(widget, 1); return TRUE; } return FALSE; } /**************************************************************** ** alternative (radial) knob motion mode (ctrl + mouse pressed) */ static void knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, int knob_x, int knob_y, bool drag, int state) { static double last_y = 2e20; GtkKnob *knob = GTK_KNOB(widget); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); double radius = min(knob_x, knob_y) / 2; int knobx = (widget->allocation.width - knob_x) / 2; int knoby = (widget->allocation.height - knob_y) / 2; double posx = (knobx + radius) - x; // x axis right -> left double posy = (knoby + radius) - y; // y axis top -> bottom double value; if (!drag) { if (state & GDK_CONTROL_MASK) { last_y = 2e20; return; } else { last_y = posy; } } if (last_y < 1e20) { // in drag started with Control Key const double scaling = 0.005; double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling); value = (last_y - posy) * scal; last_y = posy; gtk_range_set_value(GTK_RANGE(widget), adj->value - value * (adj->upper - adj->lower)); return; } double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI if (drag) { // block "forbidden zone" and direct moves between quadrant 1 and 4 int quadrant = 1 + int(angle/M_PI_2); if (knob->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) { angle = scale_zero; } else if (knob->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) { angle = 2*M_PI - scale_zero; } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } knob->last_quadrant = quadrant; } } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } knob->last_quadrant = 0; } angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1 gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower)); } /**************************************************************** ** mouse button pressed set value */ static gboolean gtk_knob_button_press (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); switch (event->button) { case 1: // left button gtk_widget_grab_focus(widget); gtk_widget_grab_default (widget); gtk_grab_add(widget); klass->button_is = 1; knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y, false, event->state); break; case 2: //wheel klass->button_is = 2; break; case 3: // right button klass->button_is = 3; break; default: // do nothing break; } return TRUE; } /**************************************************************** ** mouse button release */ static gboolean gtk_knob_button_release (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->button_is = 0; if (GTK_WIDGET_HAS_GRAB(widget)) gtk_grab_remove(widget); return FALSE; } /**************************************************************** ** set the value from mouse movement */ static gboolean gtk_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); gdk_event_request_motions (event); if (GTK_WIDGET_HAS_GRAB(widget)) { knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y, true, event->state); } return FALSE; } /**************************************************************** ** set value from mouseweel */ static gboolean gtk_knob_scroll (GtkWidget *widget, GdkEventScroll *event) { usleep(5000); gtk_knob_set_value(widget, event->direction); return FALSE; } /**************************************************************** ** init the GtkKnobClass */ static void gtk_knob_class_init (GtkKnobClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); /** set here the sizes and steps for the used knob **/ //--------- small knob size and steps klass->knob_x = 30; klass->knob_y = 30; klass->knob_step = 86; //--------- event button klass->button_is = 0; //--------- connect the events with funktions widget_class->expose_event = gtk_knob_expose; widget_class->size_request = gtk_knob_size_request; widget_class->button_press_event = gtk_knob_button_press; widget_class->button_release_event = gtk_knob_button_release; widget_class->motion_notify_event = gtk_knob_pointer_motion; widget_class->key_press_event = gtk_knob_key_press; widget_class->scroll_event = gtk_knob_scroll; } /**************************************************************** ** init the Knob type/size */ static void gtk_knob_init (GtkKnob *knob) { GtkWidget *widget = GTK_WIDGET(knob); GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget)); GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_DEFAULT); widget->requisition.width = klass->knob_x; widget->requisition.height = klass->knob_y; } /**************************************************************** ** redraw when value changed */ static gboolean gtk_knob_value_changed(gpointer obj) { GtkWidget *widget = (GtkWidget *)obj; gtk_widget_queue_draw(widget); return FALSE; } /**************************************************************** ** create small knob */ GtkWidget *GtkKnob::gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment) { GtkWidget *widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL )); GtkKnob *knob = GTK_KNOB(widget); knob->last_quadrant = 0; if (widget) { gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment); g_signal_connect(GTK_OBJECT(widget), "value-changed", G_CALLBACK(gtk_knob_value_changed), widget); } return widget; } /**************************************************************** ** get the Knob type */ GType gtk_knob_get_type (void) { static GType kn_type = 0; if (!kn_type) { static const GTypeInfo kn_info = { sizeof(GtkKnobClass), NULL, NULL, (GClassInitFunc)gtk_knob_class_init, NULL, NULL, sizeof(GtkKnob), 0, (GInstanceInitFunc)gtk_knob_init, NULL }; kn_type = g_type_register_static(GTK_TYPE_RANGE, "GtkKnob", &kn_info, (GTypeFlags)0); } return kn_type; } }/* end of gtk_knob namespace */ gtk_knob::GtkKnob myGtkKnob; /** * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string * (but not those in the middle of the string) */ static string rmWhiteSpaces(const string& s) { size_t i = s.find_first_not_of(" \t"); size_t j = s.find_last_not_of(" \t"); if (i != string::npos & j != string::npos) { return s.substr(i, 1+j-i); } else { return ""; } } /** * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata */ static void extractMetadata(const string& fulllabel, string& label, map& metadata) { enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue}; int state = kLabel; int deep = 0; string key, value; for (unsigned int i=0; i < fulllabel.size(); i++) { char c = fulllabel[i]; switch (state) { case kLabel : assert (deep == 0); switch (c) { case '\\' : state = kEscape1; break; case '[' : state = kKey; deep++; break; default : label += c; } break; case kEscape1 : label += c; state = kLabel; break; case kEscape2 : key += c; state = kKey; break; case kEscape3 : value += c; state = kValue; break; case kKey : assert (deep > 0); switch (c) { case '\\' : state = kEscape2; break; case '[' : deep++; key += c; break; case ':' : if (deep == 1) { state = kValue; } else { key += c; } break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)] = ""; state = kLabel; key=""; value=""; } else { key += c; } break; default : key += c; } break; case kValue : assert (deep > 0); switch (c) { case '\\' : state = kEscape3; break; case '[' : deep++; value += c; break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value); state = kLabel; key=""; value=""; } else { value += c; } break; default : value += c; } break; default : cerr << "ERROR unrecognized state " << state << endl; } } label = rmWhiteSpaces(label); } class GTKUI : public GUI { private : static bool fInitialized; static map fGuiSize; // map widget zone with widget size coef static map fTooltip; // map widget zone with tooltip strings static set fKnobSet; // set of widget zone to be knobs string gGroupTooltip; bool isKnob(FAUSTFLOAT* zone) {return fKnobSet.count(zone) > 0;} protected : GtkWidget* fWindow; int fTop; GtkWidget* fBox[stackSize]; int fMode[stackSize]; bool fStopped; GtkWidget* addWidget(const char* label, GtkWidget* w); virtual void pushBox(int mode, GtkWidget* w); public : static const gboolean expand = TRUE; static const gboolean fill = TRUE; static const gboolean homogene = FALSE; GTKUI(char * name, int* pargc, char*** pargv); // -- Labels and metadata virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value); virtual int checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel); virtual void checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget); // -- layout groups virtual void openTabBox(const char* label = ""); virtual void openHorizontalBox(const char* label = ""); virtual void openVerticalBox(const char* label = ""); virtual void closeBox(); // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone); virtual void addCheckButton(const char* label, FAUSTFLOAT* zone); virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); // -- passive display widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max); virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max); // -- layout groups - internal virtual void openFrameBox(const char* label); // -- extra widget's layouts virtual void openDialogBox(const char* label, FAUSTFLOAT* zone); virtual void openEventBox(const char* label = ""); virtual void openHandleBox(const char* label = ""); virtual void openExpanderBox(const char* label, FAUSTFLOAT* zone); virtual void adjustStack(int n); // -- active widgets - internal virtual void addToggleButton(const char* label, FAUSTFLOAT* zone); virtual void addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step); // -- passive display widgets - internal virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision); virtual void addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT min, FAUSTFLOAT max); virtual void show(); virtual void run(); }; /****************************************************************************** ******************************************************************************* GRAPHIC USER INTERFACE (v2) gtk implementation ******************************************************************************* *******************************************************************************/ // global static fields bool GTKUI::fInitialized = false; map GTKUI::fGuiSize; map GTKUI::fTooltip; set GTKUI::fKnobSet; // set of widget zone to be knobs /** * Format tooltip string by replacing some white spaces by * return characters so that line width doesn't exceed n. * Limitation : long words exceeding n are not cut */ static string formatTooltip(unsigned int n, const string& tt) { string ss = tt; // ss string we are going to format unsigned int lws = 0; // last white space encountered unsigned int lri = 0; // last return inserted for (unsigned int i = 0; i < tt.size(); i++) { if (tt[i] == ' ') lws = i; if (((i-lri) >= n) && (lws > lri)) { // insert return here ss[lws] = '\n'; lri = lws; } } cout << ss; return ss; } static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { return FALSE; } static void destroy_event( GtkWidget *widget, gpointer data ) { gtk_main_quit (); } GTKUI::GTKUI(char * name, int* pargc, char*** pargv) { if (!fInitialized) { gtk_init(pargc, pargv); fInitialized = true; } fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10); gtk_window_set_title (GTK_WINDOW (fWindow), name); gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL); fTop = 0; fBox[fTop] = gtk_vbox_new (homogene, 4); fMode[fTop] = kBoxMode; gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]); fStopped = false; } // empilement des boites void GTKUI::pushBox(int mode, GtkWidget* w) { ++fTop; assert(fTop < stackSize); fMode[fTop] = mode; fBox[fTop] = w; } /** * Remove n levels from the stack S before the top level * adjustStack(n): S -> S' with S' = S(0),S(n+1),S(n+2),... */ void GTKUI::adjustStack(int n) { if (n > 0) { assert(fTop >= n); fTop -= n; fMode[fTop] = fMode[fTop+n]; fBox[fTop] = fBox[fTop+n]; } } void GTKUI::closeBox() { --fTop; assert(fTop >= 0); } /** * Analyses the widget zone metadata declarations and takes * appropriate actions */ void GTKUI::declare(FAUSTFLOAT* zone, const char* key, const char* value) { if (zone == 0) { // special zone 0 means group metadata if (strcmp(key,"tooltip") == 0) { // only group tooltip are currently implemented gGroupTooltip = formatTooltip(30, value); } } else { if (strcmp(key,"size")==0) { fGuiSize[zone] = atof(value); } else if (strcmp(key,"tooltip") == 0) { fTooltip[zone] = formatTooltip(30,value) ; } else if (strcmp(key,"style") == 0) { if (strcmp(value,"knob") == 0) { fKnobSet.insert(zone); } } } } /** * Analyses a full label and activates the relevant options. returns a simplified * label (without options) and an amount of stack adjustement (in case additional * containers were pushed on the stack). */ int GTKUI::checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel) { map metadata; extractMetadata(fullLabel, simplifiedLabel, metadata); if (metadata.count("tooltip")) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, metadata["tooltip"].c_str(), NULL); } if (metadata["option"] == "detachable") { openHandleBox(simplifiedLabel.c_str()); return 1; } //--------------------- if (gGroupTooltip != string()) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, gGroupTooltip.c_str(), NULL); gGroupTooltip = string(); } //---------------------- // no adjustement of the stack needed return 0; } /** * Check if a tooltip is associated to a zone and add it to the corresponding widget */ void GTKUI::checkForTooltip(FAUSTFLOAT* zone, GtkWidget* widget) { if (fTooltip.count(zone)) { gtk_tooltips_set_tip (gtk_tooltips_new (), widget, fTooltip[zone].c_str(), NULL); } } // les differentes boites void GTKUI::openFrameBox(const char* label) { GtkWidget * box = gtk_frame_new (label); //gtk_container_set_border_width (GTK_CONTAINER (box), 10); pushBox(kSingleMode, addWidget(label, box)); } void GTKUI::openTabBox(const char* fullLabel) { string label; GtkWidget* widget = gtk_notebook_new(); int adjust = checkLabelOptions(widget, fullLabel, label); pushBox(kTabMode, addWidget(label.c_str(), widget)); // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openHorizontalBox(const char* fullLabel) { string label; GtkWidget* box = gtk_hbox_new (homogene, 4); int adjust = checkLabelOptions(box, fullLabel, label); gtk_container_set_border_width (GTK_CONTAINER (box), 10); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str())); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label.c_str(), box)); } // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openVerticalBox(const char* fullLabel) { string label; GtkWidget * box = gtk_vbox_new (homogene, 4); int adjust = checkLabelOptions(box, fullLabel, label); gtk_container_set_border_width (GTK_CONTAINER (box), 10); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str())); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label.c_str(), box)); } // adjust stack because otherwise Handlebox will remain open adjustStack(adjust); } void GTKUI::openHandleBox(const char* label) { GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_handle_box_new ()); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } void GTKUI::openEventBox(const char* label) { GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_event_box_new ()); gtk_container_add (GTK_CONTAINER(frame), box); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } struct uiExpanderBox : public uiItem { GtkExpander* fButton; uiExpanderBox(GUI* ui, FAUSTFLOAT* zone, GtkExpander* b) : uiItem(ui, zone), fButton(b) {} static void expanded (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = gtk_expander_get_expanded (GTK_EXPANDER(widget)); if (v == 1.000000) { v = 0; } else { v = 1; } ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_expander_set_expanded(GTK_EXPANDER(fButton), v); } }; void GTKUI::openExpanderBox(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget * box = gtk_hbox_new (homogene, 4); gtk_container_set_border_width (GTK_CONTAINER (box), 2); if (fMode[fTop] != kTabMode && label[0] != 0) { GtkWidget * frame = addWidget(label, gtk_expander_new (label)); gtk_container_add (GTK_CONTAINER(frame), box); uiExpanderBox* c = new uiExpanderBox(this, zone, GTK_EXPANDER(frame)); gtk_signal_connect (GTK_OBJECT (frame), "activate", GTK_SIGNAL_FUNC (uiExpanderBox::expanded), (gpointer)c); gtk_widget_show(box); pushBox(kBoxMode, box); } else { pushBox(kBoxMode, addWidget(label, box)); } } GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w) { switch (fMode[fTop]) { case kSingleMode : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w); break; case kBoxMode : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0); break; case kTabMode : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break; } gtk_widget_show (w); return w; } // --------------------------- Press button --------------------------- struct uiButton : public uiItem { GtkButton* fButton; uiButton(GUI* ui, FAUSTFLOAT* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {} static void pressed(GtkWidget *widget, gpointer data) { uiItem* c = (uiItem*) data; c->modifyZone(1.0); } static void released(GtkWidget *widget, gpointer data) { uiItem* c = (uiItem*) data; c->modifyZone(0.0); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton); } }; void GTKUI::addButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_button_new_with_label (label); addWidget(label, button); uiButton* c = new uiButton(this, zone, GTK_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c); gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c); checkForTooltip(zone, button); } // --------------------------- Toggle Buttons --------------------------- struct uiToggleButton : public uiItem { GtkToggleButton* fButton; uiToggleButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {} static void toggled (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_toggle_button_set_active(fButton, v > 0.0); } }; void GTKUI::addToggleButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_toggle_button_new_with_label (label); addWidget(label, button); uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c); checkForTooltip(zone, button); } void show_dialog(GtkWidget *widget, gpointer data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == TRUE) { gtk_widget_show(GTK_WIDGET(data)); gint root_x, root_y; gtk_window_get_position (GTK_WINDOW(data), &root_x, &root_y); root_y -= 120; gtk_window_move(GTK_WINDOW(data), root_x, root_y); } else gtk_widget_hide(GTK_WIDGET(data)); } static gboolean deleteevent( GtkWidget *widget, gpointer data ) { return TRUE; } void GTKUI::openDialogBox(const char* label, FAUSTFLOAT* zone) { // create toplevel window and set properties GtkWidget * dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_decorated(GTK_WINDOW(dialog), TRUE); gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE); gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_SOUTH); gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(fWindow)); gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); gtk_window_set_keep_below (GTK_WINDOW(dialog), FALSE); gtk_window_set_title (GTK_WINDOW (dialog), label); g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (deleteevent), NULL); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); GtkWidget * box = gtk_hbox_new (homogene, 4); *zone = 0.0; GtkWidget* button = gtk_toggle_button_new (); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (show_dialog), (gpointer) dialog); gtk_container_add (GTK_CONTAINER(fBox[fTop]), button); gtk_container_add (GTK_CONTAINER(dialog), box); gtk_widget_show (button); gtk_widget_show(box); pushBox(kBoxMode, box); } // --------------------------- Check Button --------------------------- struct uiCheckButton : public uiItem { GtkToggleButton* fButton; uiCheckButton(GUI* ui, FAUSTFLOAT* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {} static void toggled (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_toggle_button_set_active(fButton, v > 0.0); } }; void GTKUI::addCheckButton(const char* label, FAUSTFLOAT* zone) { *zone = 0.0; GtkWidget* button = gtk_check_button_new_with_label (label); addWidget(label, button); uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button)); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c); checkForTooltip(zone, button); } // --------------------------- Adjustmenty based widgets --------------------------- struct uiAdjustment : public uiItem { GtkAdjustment* fAdj; uiAdjustment(GUI* ui, FAUSTFLOAT* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {} static void changed (GtkWidget *widget, gpointer data) { FAUSTFLOAT v = GTK_ADJUSTMENT (widget)->value; ((uiItem*)data)->modifyZone(v); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_adjustment_set_value(fAdj, v); } }; // --------------------------- format knob value display --------------------------- struct uiValueDisplay : public uiItem { GtkLabel* fLabel; int fPrecision ; uiValueDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision) : uiItem(ui, zone), fLabel(label), fPrecision(precision) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; char s[64]; if (fPrecision <= 0) snprintf(s, 63, "%d", int(v)); else if (fPrecision > 3) snprintf(s, 63, "%f", v); else if (fPrecision == 1) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[1-1], v); } else if (fPrecision == 2) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[2-1], v); } else { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[3-1], v); } gtk_label_set_text(fLabel, s); } }; // ------------------------------- Knob ----------------------------------------- void GTKUI::addKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_vbox_new (FALSE, 0); GtkWidget* fil = gtk_vbox_new (FALSE, 0); GtkWidget* rei = gtk_vbox_new (FALSE, 0); GtkWidget* re =myGtkKnob.gtk_knob_new_with_adjustment(GTK_ADJUSTMENT(adj)); GtkWidget* lw = gtk_label_new(""); new uiValueDisplay(this, zone, GTK_LABEL(lw),precision(step)); gtk_container_add (GTK_CONTAINER(rei), re); if(fGuiSize[zone]) { FAUSTFLOAT size = 30 * fGuiSize[zone]; gtk_widget_set_size_request(rei, size, size ); gtk_box_pack_start (GTK_BOX(slider), fil, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(slider), rei, FALSE, FALSE, 0); } else { gtk_container_add (GTK_CONTAINER(slider), fil); gtk_container_add (GTK_CONTAINER(slider), rei); } gtk_container_add (GTK_CONTAINER(slider), lw); gtk_widget_show_all(slider); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // -------------------------- Vertical Slider ----------------------------------- void GTKUI::addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj)); gtk_scale_set_digits(GTK_SCALE(slider), precision(step)); FAUSTFLOAT size = 160; if(fGuiSize[zone]) { size = 160 * fGuiSize[zone]; } gtk_widget_set_size_request(slider, -1, size); gtk_range_set_inverted (GTK_RANGE(slider), TRUE); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // -------------------------- Horizontal Slider ----------------------------------- void GTKUI::addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj)); gtk_scale_set_digits(GTK_SCALE(slider), precision(step)); FAUSTFLOAT size = 160; if(fGuiSize[zone]) { size = 160 * fGuiSize[zone]; } gtk_widget_set_size_request(slider, size, -1); if (label && label[0]!=0) { openFrameBox(label); addWidget(label, slider); closeBox(); } else { addWidget(label, slider); } checkForTooltip(zone, slider); } // ------------------------------ Num Entry ----------------------------------- void GTKUI::addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addKnob(label, zone, init, min, max, step); return; } *zone = init; GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step); uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj)); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c); GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step)); openFrameBox(label); addWidget(label, spinner); closeBox(); checkForTooltip(zone, spinner); } // ========================== passive widgets =============================== // ------------------------------ Progress Bar ----------------------------------- struct uiBargraph : public uiItem { GtkProgressBar* fProgressBar; FAUSTFLOAT fMin; FAUSTFLOAT fMax; uiBargraph(GUI* ui, FAUSTFLOAT* zone, GtkProgressBar* pbar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {} FAUSTFLOAT scale(FAUSTFLOAT v) { return (v-fMin)/(fMax-fMin); } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; gtk_progress_bar_set_fraction(fProgressBar, scale(v)); } }; void GTKUI::addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* pb = gtk_progress_bar_new(); gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP); gtk_widget_set_size_request(pb, 8, -1); new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi); openFrameBox(label); addWidget(label, pb); closeBox(); checkForTooltip(zone, pb); } void GTKUI::addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* pb = gtk_progress_bar_new(); gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT); gtk_widget_set_size_request(pb, -1, 8); new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi); openFrameBox(label); addWidget(label, pb); closeBox(); checkForTooltip(zone, pb); } // ------------------------------ Num Display ----------------------------------- struct uiNumDisplay : public uiItem { GtkLabel* fLabel; int fPrecision; uiNumDisplay(GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, int precision) : uiItem(ui, zone), fLabel(label), fPrecision(precision) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; char s[64]; if (fPrecision <= 0) { snprintf(s, 63, "%d", int(v)); } else if (fPrecision>3) { snprintf(s, 63, "%f", v); } else { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[fPrecision-1], v); } gtk_label_set_text(fLabel, s); } }; void GTKUI::addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision) { GtkWidget* lw = gtk_label_new(""); new uiNumDisplay(this, zone, GTK_LABEL(lw), precision); openFrameBox(label); addWidget(label, lw); closeBox(); checkForTooltip(zone, lw); } // ------------------------------ Text Display ----------------------------------- struct uiTextDisplay : public uiItem { GtkLabel* fLabel; const char** fNames; FAUSTFLOAT fMin; FAUSTFLOAT fMax; int fNum; uiTextDisplay (GUI* ui, FAUSTFLOAT* zone, GtkLabel* label, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi) { fNum = 0; while (fNames[fNum] != 0) fNum++; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; int idx = int(fNum*(v-fMin)/(fMax-fMin)); if (idx < 0) idx = 0; else if (idx >= fNum) idx = fNum-1; gtk_label_set_text(fLabel, fNames[idx]); } }; void GTKUI::addTextDisplay(const char* label, FAUSTFLOAT* zone, const char* names[], FAUSTFLOAT lo, FAUSTFLOAT hi) { GtkWidget* lw = gtk_label_new(""); new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi); openFrameBox(label); addWidget(label, lw); closeBox(); checkForTooltip(zone, lw); } void GTKUI::show() { assert(fTop == 0); gtk_widget_show (fBox[0]); gtk_widget_show (fWindow); } /** * Update all user items reflecting zone z */ static gboolean callUpdateAllGuis(gpointer) { GUI::updateAllGuis(); return TRUE; } void GTKUI::run() { assert(fTop == 0); gtk_widget_show (fBox[0]); gtk_widget_show (fWindow); gtk_timeout_add(40, callUpdateAllGuis, 0); gtk_main (); stop(); } #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/faustqt.h000066400000000000000000001543511210074205700261740ustar00rootroot00000000000000/************************************************************************ ************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . ************************************************************************ ************************************************************************/ #ifndef __faustqt__ #define __faustqt__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include "faust/gui/GUI.h" //---------------------------------- // for compatibility #define minValue minimum #define maxValue maximum using namespace std; //==============================BEGIN QSYNTHKNOB===================================== // // qsynthknob and qsynthDialVokiStyle borrowed from qsynth-0.3.3 by Rui Nuno Capela // This widget is based on a design by Thorsten Wilms, // implemented by Chris Cannam in Rosegarden, // adapted for QSynth by Pedro Lopez-Cabanillas, // improved for Qt4 by David Garcia Garzon. // #define DIAL_MIN (0.25 * M_PI) #define DIAL_MAX (1.75 * M_PI) #define DIAL_RANGE (DIAL_MAX - DIAL_MIN) class qsynthDialVokiStyle : public QCommonStyle { public: qsynthDialVokiStyle() {}; virtual ~qsynthDialVokiStyle() {}; virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget = 0) const { if (cc != QStyle::CC_Dial) { QCommonStyle::drawComplexControl(cc, opt, p, widget); return; } const QStyleOptionSlider *dial = qstyleoption_cast(opt); if (dial == NULL) return; double angle = DIAL_MIN // offset + (DIAL_RANGE * (double(dial->sliderValue - dial->minimum) / (double(dial->maximum - dial->minimum)))); int degrees = int(angle * 180.0 / M_PI); int side = dial->rect.width() < dial->rect.height() ? dial->rect.width() : dial->rect.height(); int xcenter = dial->rect.width() / 2; int ycenter = dial->rect.height() / 2; int notchWidth = 1 + side / 400; int pointerWidth = 2 + side / 30; int scaleShadowWidth = 1 + side / 100; int knobBorderWidth = 0; int ns = dial->tickInterval; int numTicks = 1 + (dial->maximum + ns - dial->minimum) / ns; int indent = int(0.15 * side) + 2; int knobWidth = side - 2 * indent; int shineFocus = knobWidth / 4; int shineCenter = knobWidth / 5; int shineExtension = shineCenter * 4; int shadowShift = shineCenter * 2; int meterWidth = side - 2 * scaleShadowWidth; QPalette pal = opt->palette; QColor knobColor = pal.mid().color(); QColor borderColor = knobColor.light(); QColor meterColor = (dial->state & State_Enabled) ? QColor("orange") : pal.mid().color(); // pal.highlight().color() : pal.mid().color(); QColor background = pal.window().color(); p->save(); p->setRenderHint(QPainter::Antialiasing, true); // The bright metering bit... QConicalGradient meterShadow(xcenter, ycenter, -90); meterShadow.setColorAt(0, meterColor.dark()); meterShadow.setColorAt(0.5, meterColor); meterShadow.setColorAt(1.0, meterColor.light().light()); p->setBrush(meterShadow); p->setPen(Qt::transparent); p->drawPie(xcenter - meterWidth / 2, ycenter - meterWidth / 2, meterWidth, meterWidth, (180 + 45) * 16, -(degrees - 45) * 16); // Knob projected shadow QRadialGradient projectionGradient( xcenter + shineCenter, ycenter + shineCenter, shineExtension, xcenter + shadowShift, ycenter + shadowShift); projectionGradient.setColorAt(0, QColor( 0, 0, 0, 100)); projectionGradient.setColorAt(1, QColor(200, 0, 0, 10)); QBrush shadowBrush(projectionGradient); p->setBrush(shadowBrush); p->drawEllipse(xcenter - shadowShift, ycenter - shadowShift, knobWidth, knobWidth); // Knob body and face... QPen pen; pen.setColor(knobColor); pen.setWidth(knobBorderWidth); p->setPen(pen); QRadialGradient gradient( xcenter - shineCenter, ycenter - shineCenter, shineExtension, xcenter - shineFocus, ycenter - shineFocus); gradient.setColorAt(0.2, knobColor.light().light()); gradient.setColorAt(0.5, knobColor); gradient.setColorAt(1.0, knobColor.dark(150)); QBrush knobBrush(gradient); p->setBrush(knobBrush); p->drawEllipse(xcenter - knobWidth / 2, ycenter - knobWidth / 2, knobWidth, knobWidth); // Tick notches... p->setBrush(Qt::NoBrush); if (dial->subControls & QStyle::SC_DialTickmarks) { pen.setColor(pal.dark().color()); pen.setWidth(notchWidth); p->setPen(pen); double hyp = double(side - scaleShadowWidth) / 2.0; double len = hyp / 4; for (int i = 0; i < numTicks; ++i) { int div = numTicks; if (div > 1) --div; bool internal = (i != 0 && i != numTicks - 1); double angle = DIAL_MIN + (DIAL_MAX - DIAL_MIN) * i / div; double dir = (internal ? -1 : len); double sinAngle = sin(angle); double cosAngle = cos(angle); double x0 = xcenter - (hyp - len) * sinAngle; double y0 = ycenter + (hyp - len) * cosAngle; double x1 = xcenter - (hyp + dir) * sinAngle; double y1 = ycenter + (hyp + dir) * cosAngle; p->drawLine(QLineF(x0, y0, x1, y1)); } } // Shadowing... // Knob shadow... if (knobBorderWidth > 0) { QLinearGradient inShadow(xcenter - side / 4, ycenter - side / 4, xcenter + side / 4, ycenter + side / 4); inShadow.setColorAt(0.0, borderColor.light()); inShadow.setColorAt(1.0, borderColor.dark()); p->setPen(QPen(QBrush(inShadow), knobBorderWidth * 7 / 8)); p->drawEllipse(xcenter - side / 2 + indent, ycenter - side / 2 + indent, side - 2 * indent, side - 2 * indent); } // Scale shadow... QLinearGradient outShadow(xcenter - side / 3, ycenter - side / 3, xcenter + side / 3, ycenter + side / 3); outShadow.setColorAt(0.0, background.dark().dark()); outShadow.setColorAt(1.0, background.light().light()); p->setPen(QPen(QBrush(outShadow), scaleShadowWidth)); p->drawArc(xcenter - side / 2 + scaleShadowWidth / 2, ycenter - side / 2 + scaleShadowWidth / 2, side - scaleShadowWidth, side - scaleShadowWidth, -45 * 16, 270 * 16); // Pointer notch... double hyp = double(side) / 2.0; double len = hyp - indent - 1; double x = xcenter - len * sin(angle); double y = ycenter + len * cos(angle); QColor pointerColor = pal.dark().color(); pen.setColor((dial->state & State_Enabled) ? pointerColor.dark(140) : pointerColor); pen.setWidth(pointerWidth + 2); p->setPen(pen); p->drawLine(QLineF(xcenter, ycenter, x, y)); pen.setColor((dial->state & State_Enabled) ? pointerColor.light() : pointerColor.light(140)); pen.setWidth(pointerWidth); p->setPen(pen); p->drawLine(QLineF(xcenter - 1, ycenter - 1, x - 1, y - 1)); // done p->restore(); } }; // //===============================END QSYNTHKNOB====================================== //==============================BEGIN DISPLAYS=================================== // // This section constains displays, passive QT widgets that displays values in // different ways, in particular bargraphs // /** * An abstract widget that display a value in a range */ class AbstractDisplay : public QWidget { protected : FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fValue; public: AbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : fMin(lo), fMax(hi), fValue(lo) {} /** * set the range of displayed values */ virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi) { fMin = lo; fMax = hi; } /** * set the value to be displayed */ virtual void setValue(FAUSTFLOAT v) { if (v < fMin) v = fMin; else if (v > fMax) v = fMax; if (v != fValue) { fValue = v; update(); } } }; /** * Displays dB values using a scale of colors */ class dbAbstractDisplay : public AbstractDisplay { protected : FAUSTFLOAT fScaleMin; FAUSTFLOAT fScaleMax; vector fLevel; vector fBrush; /** * Convert a dB value into a scale between 0 and 1 (following IEC standard ?) */ FAUSTFLOAT dB2Scale(FAUSTFLOAT dB) const { FAUSTFLOAT fScale = 1.0; /*if (dB < -70.0f) fScale = 0.0f; else*/ if (dB < -60.0) fScale = (dB + 70.0) * 0.0025; else if (dB < -50.0) fScale = (dB + 60.0) * 0.005 + 0.025; else if (dB < -40.0) fScale = (dB + 50.0) * 0.0075 + 0.075; else if (dB < -30.0) fScale = (dB + 40.0) * 0.015 + 0.15; else if (dB < -20.0) fScale = (dB + 30.0) * 0.02 + 0.3; else if (dB < -0.001 || dB > 0.001) /* if (dB < 0.0) */ fScale = (dB + 20.0f) * 0.025 + 0.5; return fScale; } /** * Create the scale of colors used to paint the bargraph in relation to the levels * The parameter x indicates the direction of the gradient. x=1 means an horizontal * gradient typically used by a vertical bargraph, and x=0 a vertical gradient. */ void initLevelsColors(int x) { int alpha = 200; { // level until -10 dB QColor c(40, 160, 40, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-10); fBrush.push_back(QBrush(g)); } { // level until -6 dB QColor c(160, 220, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-6); fBrush.push_back(QBrush(g)); } { // level until -3 dB QColor c(220, 220, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(-3); fBrush.push_back(QBrush(g)); } { // level until -0 dB QColor c(240, 160, 20, alpha); QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(0); fBrush.push_back(QBrush(g)); } { // until 10 dB (and over because last one) QColor c(240, 0, 20, alpha); // ColorOver QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fLevel.push_back(+10); fBrush.push_back(QBrush(g)); } } public: dbAbstractDisplay(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo, hi) {} /** * set the range of displayed values */ virtual void setRange(FAUSTFLOAT lo, FAUSTFLOAT hi) { AbstractDisplay::setRange(lo, hi); fScaleMin = dB2Scale(fMin); fScaleMax = dB2Scale(fMax); } }; /** * Small rectangular LED display which color changes with the level in dB */ class dbLED : public dbAbstractDisplay { protected: /** * Draw the LED using a color depending of its value in dB */ virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); painter.drawRect(rect()); if (fValue <= fLevel[0]) { // interpolate the first color on the alpha channel QColor c(40, 160, 40) ; FAUSTFLOAT a = (fValue-fMin)/(fLevel[0]-fMin); c.setAlphaF(a); painter.fillRect(rect(), c); } else { // find the minimal level > value int l = fLevel.size()-1; while (fValue < fLevel[l] && l > 0) l--; painter.fillRect(rect(), fBrush[l]); } } public: dbLED(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); initLevelsColors(1); } virtual QSize sizeHint () const { return QSize(16, 8); } }; /** * Small rectangular LED display which intensity (alpha channel) changes according to the value */ class LED : public AbstractDisplay { QColor fColor; protected: /** * Draw the LED using a transparency depending of its value */ virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); painter.drawRect(rect()); // interpolate the first color on the alpha channel QColor c = fColor ; FAUSTFLOAT a = (fValue-fMin)/(fMax-fMin); c.setAlphaF(a); painter.fillRect(rect(), c); } public: LED(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi), fColor("yellow") { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } virtual QSize sizeHint () const { return QSize(16, 8); } }; /** * A simple bargraph that detect automatically its direction */ class linBargraph : public AbstractDisplay { protected : QBrush fBrush; /** * No scale implemented yet */ void paintScale(QPainter* painter) const { painter->drawRect(0,0,width(),height()); } /** * The length of the rectangle is proportional to the value */ void paintContent (QPainter* painter) const { int w = width(); int h = height(); FAUSTFLOAT v = (fValue-fMin)/(fMax-fMin); if (h>w) { // draw vertical rectangle painter->fillRect(0,(1-v)*h,w, v*h, fBrush); } else { // draw horizontal rectangle painter->fillRect(0, 0, h, v*w, fBrush); } } virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); paintContent(&painter); paintScale(&painter); } public: linBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : AbstractDisplay(lo,hi) { // compute the brush that will be used to // paint the value QColor c(0xffa500); // orange int x = int(height() < width()); // gradient direction QLinearGradient g(0,0,x,1-x); g.setCoordinateMode(QGradient::ObjectBoundingMode); g.setColorAt(0.0, c.lighter()); g.setColorAt(0.2, c); g.setColorAt(0.8, c); g.setColorAt(0.9, c.darker(120)); fBrush = QBrush(g); } }; /** * A simple vertical bargraph */ class linVerticalBargraph : public linBargraph { public: linVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); } virtual QSize sizeHint () const { return QSize(16, 128); } }; /** * A simple horizontal bargraph */ class linHorizontalBargraph : public linBargraph { public: linHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : linBargraph(lo,hi) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } virtual QSize sizeHint () const { return QSize(128, 16); } }; /** * A dB Bargraph with a scale of colors */ class dbBargraph : public dbAbstractDisplay { QBrush fBackColor; protected : // These two abstract methods are implemented // according to the vertical or horizontal direction // in dbVerticalBargraph and dbHorizontalBargraph virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const = 0; virtual int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const = 0; /** * Draw the logarithmic scale */ void paintScale(QPainter* painter) const { painter->fillRect(0,0,width(),height(), fBackColor); painter->save(); painter->setPen(QColor(0x6699aa)); //0xffa500)); for (FAUSTFLOAT v = -10; v > fMin; v -= 10) paintMark(painter, v); for (FAUSTFLOAT v = -6; v < fMax; v += 3) paintMark(painter, v); painter->restore(); } /** * Draw the content using colored segments */ void paintContent (QPainter* painter) const { int l = fLevel.size(); FAUSTFLOAT p = -1; // fake value indicates to start from border int n = 0; // paint all the full segments < fValue for (n=0; (n < l) && (fValue > fLevel[n]); n++) { p = paintSegment(painter, p, fLevel[n], fBrush[n]); } // paint the last segment if (n == l) n = n-1; p=paintSegment(painter, p, fValue, fBrush[n]); painter->drawRect(0,0,width(),height()); } virtual void paintEvent ( QPaintEvent *) { QPainter painter(this); paintScale(&painter); paintContent(&painter); } public: dbBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbAbstractDisplay(lo,hi) { QFont f = this->font(); f.setPointSize(6); this->setFont(f); fBackColor = QBrush(QColor(20,20,20)); } }; /** * Vertical dB Bargraph */ class dbVerticalBargraph : public dbBargraph { protected: /** * Convert a dB value into a vertical position */ FAUSTFLOAT dB2y(FAUSTFLOAT dB) const { FAUSTFLOAT s0 = fScaleMin; FAUSTFLOAT s1 = fScaleMax; FAUSTFLOAT sx = dB2Scale(dB); int h = height(); return h - h*(s0-sx)/(s0-s1); } /** * Paint a vertical graduation mark */ virtual void paintMark(QPainter* painter, FAUSTFLOAT v) const { int n = 10; int y = dB2y(v); QRect r(0,y-n,width()-1,2*n); if (v > 0.0) { painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v).prepend('+')); } else { painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v)); } } /** * Paint a color segment */ virtual int paintSegment(QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const { if (pos == -1) pos = height(); FAUSTFLOAT y = dB2y(v); painter->fillRect(0, y, width(), pos-y+1, b); return y; } public: dbVerticalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); initLevelsColors(1); } virtual QSize sizeHint () const { return QSize(18, 256); } }; /** * Horizontal dB Bargraph */ class dbHorizontalBargraph : public dbBargraph { protected: /** * Convert a dB value into an horizontal position */ FAUSTFLOAT dB2x(FAUSTFLOAT dB) const { FAUSTFLOAT s0 = fScaleMin; FAUSTFLOAT s1 = fScaleMax; FAUSTFLOAT sx = dB2Scale(dB); int w = width(); return w - w*(s1-sx)/(s1-s0); } /** * Paint an horizontal graduation mark */ void paintMark(QPainter* painter, FAUSTFLOAT v) const { int n = 10; int x = dB2x(v); QRect r(x-n,0,2*n, height()); painter->drawText(r, Qt::AlignHCenter|Qt::AlignVCenter, QString::number(v)); } /** * Paint a horizontal color segment */ int paintSegment (QPainter* painter, int pos, FAUSTFLOAT v, const QBrush& b) const { if (pos == -1) pos = 0; FAUSTFLOAT x = dB2x(v); painter->fillRect(pos, 0, x-pos, height(), b); return x; } public: dbHorizontalBargraph(FAUSTFLOAT lo, FAUSTFLOAT hi) : dbBargraph(lo,hi) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); initLevelsColors(0); } virtual QSize sizeHint () const { return QSize(256, 18); } }; // //===============================END DISPLAYS==================================== //============================= BEGIN GROUP LABEL METADATA=========================== // Unlike widget's label, metadata inside group's label are not extracted directly by // the Faust compiler. Therefore they must be extracted within the architecture file //----------------------------------------------------------------------------------- // /** * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string * (but not those in the middle of the string) */ static string rmWhiteSpaces(const string& s) { size_t i = s.find_first_not_of(" \t"); size_t j = s.find_last_not_of(" \t"); if ( (i != string::npos) && (j != string::npos) ) { return s.substr(i, 1+j-i); } else { return ""; } } /** * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata(unit=dB) */ static void extractMetadata(const string& fulllabel, string& label, map& metadata) { enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue}; int state = kLabel; int deep = 0; string key, value; for (unsigned int i=0; i < fulllabel.size(); i++) { char c = fulllabel[i]; switch (state) { case kLabel : assert (deep == 0); switch (c) { case '\\' : state = kEscape1; break; case '[' : state = kKey; deep++; break; default : label += c; } break; case kEscape1 : label += c; state = kLabel; break; case kEscape2 : key += c; state = kKey; break; case kEscape3 : value += c; state = kValue; break; case kKey : assert (deep > 0); switch (c) { case '\\' : state = kEscape2; break; case '[' : deep++; key += c; break; case ':' : if (deep == 1) { state = kValue; } else { key += c; } break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)] = ""; state = kLabel; key=""; value=""; } else { key += c; } break; default : key += c; } break; case kValue : assert (deep > 0); switch (c) { case '\\' : state = kEscape3; break; case '[' : deep++; value += c; break; case ']' : deep--; if (deep < 1) { metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value); state = kLabel; key=""; value=""; } else { value += c; } break; default : value += c; } break; default : cerr << "ERROR unrecognized state " << state << endl; } } label = rmWhiteSpaces(label); } // //============================= END GROUP LABEL METADATA=========================== /****************************************************************************** ******************************************************************************* IMPLEMENTATION OF GUI ITEMS (QT 4.3 for FAUST) ******************************************************************************* *******************************************************************************/ class uiButton : public QObject, public uiItem { Q_OBJECT public : QAbstractButton* fButton; uiButton (GUI* ui, FAUSTFLOAT* zone, QAbstractButton* b) : uiItem(ui, zone), fButton(b) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fButton->setDown( v > 0.0 ); } public slots : void pressed() { modifyZone(1.0); } void released() { modifyZone(0.0); } }; class uiCheckButton : public QObject, public uiItem { Q_OBJECT public : QCheckBox* fCheckBox; uiCheckButton (GUI* ui, FAUSTFLOAT* zone, QCheckBox* b) : uiItem(ui, zone), fCheckBox(b) {} virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fCheckBox->setCheckState( (v < 0.5) ? Qt::Unchecked : Qt::Checked ); } public slots : void setState(int v) { modifyZone(FAUSTFLOAT(v>0)); } }; class uiSlider : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/fStep); } FAUSTFLOAT qt2faust (int v) { return fMin + v*fStep; } int optimalTick() { FAUSTFLOAT x = fStep; while ((fMax-fMin)/x > 50) x*=10; while ((fMax-fMin)/x < 10) x/=2; return faust2qt(fMin+x); } public : QSlider* fSlider; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; uiSlider (GUI* ui, FAUSTFLOAT* zone, QSlider* slider, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fSlider->setMinimum(0); fSlider->setMaximum(faust2qt(fMax)); fSlider->setValue(faust2qt(fCur)); fSlider->setTickInterval(optimalTick()); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fSlider->setValue(faust2qt(v)); } public slots : void setValue(int v) { modifyZone(qt2faust(v)); } }; class uiKnob : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/fStep); } FAUSTFLOAT qt2faust (int v) { return fMin + v*fStep; } int optimalTick() { FAUSTFLOAT x = fStep; while ((fMax-fMin)/x > 50) x*=10; while ((fMax-fMin)/x < 10) x/=2; return faust2qt(fMin+x); } public : QAbstractSlider* fSlider; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; uiKnob (GUI* ui, FAUSTFLOAT* zone, QAbstractSlider* slider, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fSlider->setMinimum(0); fSlider->setMaximum(faust2qt(fMax)); fSlider->setValue(faust2qt(fCur)); //fSlider->setTickInterval(optimalTick()); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fSlider->setValue(faust2qt(v)); } public slots : void setValue(int v) { modifyZone(qt2faust(v)); } }; class uiBargraph : public QObject, public uiItem { Q_OBJECT int faust2qt(FAUSTFLOAT x) { return int(0.5 + (x-fMin)/(fMax-fMin)*fStep); } public : QProgressBar* fBar; FAUSTFLOAT fMin; FAUSTFLOAT fMax; int fStep; uiBargraph (GUI* ui, FAUSTFLOAT* zone, QProgressBar* bar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fBar(bar), fMin(lo), fMax(hi), fStep(1024) { fBar->setRange(0, fStep); fBar->setValue(0); *fZone = 0; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; int x = faust2qt(v); //std::cout << "update *" << fBar << " = " << x << std::endl; fBar->setValue(x); } }; class uiBargraph2 : public QObject, public uiItem { Q_OBJECT public : AbstractDisplay* fBar; uiBargraph2 (GUI* ui, FAUSTFLOAT* zone, AbstractDisplay* bar, FAUSTFLOAT lo, FAUSTFLOAT hi) : uiItem(ui, zone), fBar(bar) { fBar->setRange(lo, hi); fBar->setValue(lo); *fZone = lo; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fBar->setValue(v); } }; class uiNumEntry : public QObject, public uiItem { Q_OBJECT public : QDoubleSpinBox* fNumEntry; FAUSTFLOAT fCur; FAUSTFLOAT fMin; FAUSTFLOAT fMax; FAUSTFLOAT fStep; int fDecimals; uiNumEntry (GUI* ui, FAUSTFLOAT* zone, QDoubleSpinBox* numEntry, FAUSTFLOAT cur, FAUSTFLOAT lo, FAUSTFLOAT hi, FAUSTFLOAT step) : uiItem(ui, zone), fNumEntry(numEntry), fCur(cur), fMin(lo), fMax(hi), fStep(step) { fDecimals = (fStep >= 1.0) ? 0 : int(0.5+log10(1.0/fStep)); fNumEntry->setMinimum(fMin); fNumEntry->setMaximum(fMax); fNumEntry->setSingleStep(fStep); fNumEntry->setDecimals(fDecimals); fNumEntry->setValue(fCur); *fZone = fCur; } virtual void reflectZone() { FAUSTFLOAT v = *fZone; fCache = v; fNumEntry->setValue(v); } public slots : void setValue(double v) { modifyZone(FAUSTFLOAT(v)); } }; /****************************************************************************** ******************************************************************************* IMPLEMENTATION OF THE USER INTERFACE (QT 4.3 for FAUST) ******************************************************************************* *******************************************************************************/ class QTGUI : public QObject, public GUI { Q_OBJECT QApplication fAppl; QTimer* fTimer; QStyle* fStyle; string gGroupTooltip; stack fGroupStack; map fGuiSize; // map widget zone with widget size coef map fTooltip; // map widget zone with tooltip strings map fUnit; // map widget zone to unit string (i.e. "dB") set fKnobSet; // set of widget zone to be knobs set fLedSet; // set of widget zone to be LEDs /** * Format tooltip string by replacing some white spaces by * return characters so that line width doesn't exceed n. * Limitation : long words exceeding n are not cut */ virtual string formatTooltip(int n, const string& tt) { string ss = tt; // ss string we are going to format int lws = 0; // last white space encountered int lri = 0; // last return inserted for (int i=0; i< (int)tt.size(); i++) { if (tt[i] == ' ') lws = i; if (((i-lri) >= n) && (lws > lri)) { // insert return here ss[lws] = '\n'; lri = lws; } } return ss; } /** * Analyses the widget zone metadata declarations and takes * appropriate actions */ virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value) { if (zone == 0) { // special zone 0 means group metadata if (strcmp(key,"tooltip")==0) { // only group tooltip are currently implemented gGroupTooltip = formatTooltip(30, value); } } else { if (strcmp(key,"size")==0) { fGuiSize[zone]=atof(value); } else if (strcmp(key,"tooltip")==0) { fTooltip[zone] = formatTooltip(30, value) ; } else if (strcmp(key,"unit")==0) { fUnit[zone] = value ; } else if (strcmp(key,"style")==0) { // else if ((strcmp(key,"style")==0) || (strcmp(key,"type")==0)) { if (strcmp(value,"knob") == 0) { fKnobSet.insert(zone); } else if (strcmp(value,"led") == 0) { fLedSet.insert(zone); } } } } bool isTabContext() { //return fGroupStack.empty() || ((!fGroupStack.empty()) && (dynamic_cast(fGroupStack.top()) != 0)); return ((!fGroupStack.empty()) && (dynamic_cast(fGroupStack.top()) != 0)); } void insert(const char* label, QWidget* widget) { if (fStyle) widget->setStyle(fStyle); if (!fGroupStack.empty()) { QWidget* mother = fGroupStack.top(); QTabWidget* tab = dynamic_cast(mother); if (tab) { tab->addTab(widget,label); } else { widget->setParent(mother); mother->layout()->addWidget(widget); } } } /** * Analyses a full label and activates the relevant options. returns a simplified * label (without options) and an amount of stack adjustement (in case additional * containers were pushed on the stack). */ int checkLabelOptions(QWidget* widget, const string& fullLabel, string& simplifiedLabel) { map metadata; extractMetadata(fullLabel, simplifiedLabel, metadata); if (metadata.count("tooltip")) { widget->setToolTip(metadata["tooltip"].c_str()); } if (metadata["option"] == "detachable") { //openHandleBox(simplifiedLabel.c_str()); return 1; } // no adjustement of the stack needed return 0; } /** * Check if a tooltip is associated to a zone and add it to the corresponding widget */ void checkForTooltip(FAUSTFLOAT* zone, QWidget* widget) { if (fTooltip.count(zone)) { widget->setToolTip(fTooltip[zone].c_str()); } } /** * Check if a knob is required */ bool isKnob(FAUSTFLOAT* zone) { return fKnobSet.count(zone) > 0; } void openBox(const char* fulllabel, QLayout* layout) { map metadata; string label; extractMetadata(fulllabel, label, metadata); layout->setMargin(5); QWidget* box; if (isTabContext()) { box = new QWidget(); // set background color QPalette pal = box->palette(); pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150) ); box->setPalette(pal); } else if (label.size()>0) { QGroupBox* group = new QGroupBox(); group->setTitle(label.c_str()); box = group; } else { // no label here we use simple widget layout->setMargin(0); box = new QWidget(); } box->setLayout(layout); /* if (metadata.count("tooltip")) { box->setToolTip(metadata["tooltip"].c_str()); }*/ if (gGroupTooltip != string()) { box->setToolTip(gGroupTooltip.c_str()); gGroupTooltip = string(); } insert(label.c_str(), box); fGroupStack.push(box); } void openTab(const char* label) { QTabWidget* group = new QTabWidget(); if (fStyle) group->setStyle(fStyle); insert(label, group); fGroupStack.push(group); } public slots : void update() { //std::cout << '.' << std::endl; updateAllZones(); } public: QTGUI(int &argc, char* argv[], QStyle* style = 0) : fAppl(argc, argv), fTimer(0), fStyle(style){ //fGroupStack.push(new QMainWindow()); } virtual ~QTGUI() {} virtual void run() { if (fTimer == 0) { fTimer = new QTimer(this); QObject::connect(fTimer, SIGNAL(timeout()), this, SLOT(update())); fTimer->start(100); } #if 0 fAppl.setStyleSheet( // BUTTONS "QPushButton {" "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," "stop: 0 #B0B0B0, stop: 1 #404040);" "border: 2px solid grey;" "border-radius: 6px;" "margin-top: 1ex;" "}" "QPushButton:hover {" "border: 2px solid orange;" "}" "QPushButton:pressed {" //"border: 1px solid orange;" "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #404040, stop: 1 #B0B0B0);" "}" // GROUPS "QGroupBox {" "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," "stop: 0 #A0A0A0, stop: 1 #202020);" "border: 2px solid gray;" "border-radius: 5px;" "margin-top: 3ex;" "font-size:10pt;" "font-weight:bold;" //"color: dark grey;" "color: white;" "}" "QGroupBox::title {" "subcontrol-origin: margin;" "subcontrol-position: top center;" /* position at the top center */ "padding: 0 5px;" "}" // SLIDERS // horizontal sliders "QSlider::groove:vertical {" "background: red;" "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ "left: 13px; right: 13px;" "}" "QSlider::handle:vertical {" "height: 40px;" "width: 30px;" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" "margin: 0 -5px; /* expand outside the groove */" "border-radius: 5px;" "}" "QSlider::add-page:vertical {" "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 yellow, stop : 0.5 orange);" "}" "QSlider::sub-page:vertical {" "background: grey;" "}" // horizontal sliders "QSlider::groove:horizontal {" "background: red;" "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ "top: 14px; bottom: 14px;" "}" "QSlider::handle:horizontal {" "width: 40px;" "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" "margin: -5px 0; /* expand outside the groove */" "border-radius: 5px;" "}" "QSlider::sub-page:horizontal {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 yellow, stop : 0.5 orange);" "}" "QSlider::add-page:horizontal {" "background: grey;" "}" // TABS //TabWidget and TabBar "QTabWidget::pane {" /* The tab widget frame */ //"border-top: 2px solid #C2C7CB;" "border-top: 2px solid orange;" "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #A0A0A0, stop: 1 #202020);" "}" "QTabWidget::tab-bar {" "left: 5px;" /* move to the right by 5px */ "}" /* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */ "QTabBar::tab {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #909090, stop: 0.4 #888888," "stop: 0.5 #808080, stop: 1.0 #909090);" "border: 2px solid #808080;" //"border-bottom-color: #C2C7CB;" /* same as the pane color */ "border-bottom-color: orange;" /* same as the pane color */ "border-top-left-radius: 4px;" "border-top-right-radius: 4px;" "min-width: 8ex;" "padding: 2px;" "}" "QTabBar::tab:selected, QTabBar::tab:hover {" "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "stop: 0 #D0D0D0, stop: 0.4 #A0A0A0," "stop: 0.5 #808080, stop: 1.0 #A0A0A0);" //"stop: 0.5 #A0A0A0, stop: 1.0 #C0C0C0);" //"stop: 0 #fafafa, stop: 0.4 #f4f4f4," //"stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);" //"border-bottom-color: orange;" /* same as the pane color */ "}" "QTabBar::tab:selected {" "border-color: orange;" "border-bottom-color: #A0A0A0;" /* same as pane color */ "}" "QTabBar::tab:!selected {" " margin-top: 2px;" /* make non-selected tabs look smaller */ "}" ); #endif fAppl.exec(); stop(); } // ------------------------- Groups ----------------------------------- virtual void openHorizontalBox(const char* label) { openBox(label, new QHBoxLayout()); } virtual void openVerticalBox(const char* label) { openBox(label, new QVBoxLayout()); } virtual void openFrameBox(const char* ) { } virtual void openTabBox(const char* label) { openTab(label); } virtual void closeBox() { QWidget* group = fGroupStack.top(); fGroupStack.pop(); if (fGroupStack.empty()) { group->show(); group->adjustSize();} } // ------------------------- active widgets ----------------------------------- virtual void addButton(const char* label, FAUSTFLOAT* zone) { QAbstractButton* w = new QPushButton(label); uiButton* c = new uiButton(this, zone, w); insert(label, w); QObject::connect(w, SIGNAL(pressed()), c, SLOT(pressed())); QObject::connect(w, SIGNAL(released()), c, SLOT(released())); checkForTooltip(zone, w); } virtual void addToggleButton(const char*, FAUSTFLOAT*) {} virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { QCheckBox* w = new QCheckBox(label); uiCheckButton* c = new uiCheckButton(this, zone, w); insert(label, w); QObject::connect(w, SIGNAL(stateChanged(int)), c, SLOT(setState(int))); checkForTooltip(zone, w); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addVerticalKnob(label, zone, init, min, max, step); return; } //insert(label, new QDoubleSpinBox()); if (label && label[0]) openVerticalBox(label); QDoubleSpinBox* w = new QDoubleSpinBox(); uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); insert(label, w); w->setSuffix(fUnit[zone].c_str()); QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); if (label && label[0]) closeBox(); checkForTooltip(zone, w); } // special num entry without buttons virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { //insert(label, new QDoubleSpinBox()); if (label && label[0]) openVerticalBox(label); QDoubleSpinBox* w = new QDoubleSpinBox(); w->setAlignment(Qt::AlignHCenter); #if 1 w->setStyleSheet( "QDoubleSpinBox {" "border: 2px solid orange;" "border-radius: 5px;" "font-size: 8pt;" "}" ); #endif uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); insert(label, w); w->setButtonSymbols(QAbstractSpinBox::NoButtons); w->setSuffix(fUnit[zone].c_str()); QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); if (label && label[0]) closeBox(); checkForTooltip(zone, w); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // KNOBS // ////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void addVerticalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { openHorizontalBox(label); QAbstractSlider* w = new QDial(); //qsynthKnob(); uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); insert(label, w); w->setStyle(new qsynthDialVokiStyle()); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); // compute the size of the knob+display int width = int(64*pow(2,fGuiSize[zone])); int height = int(100*pow(2,fGuiSize[zone])); fGroupStack.top()->setMinimumSize(width,height); fGroupStack.top()->setMaximumSize(width,height); closeBox(); checkForTooltip(zone, w); } virtual void addHorizontalKnob(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { openHorizontalBox(label); QAbstractSlider* w = new QDial(); //new qsynthKnob(); uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); insert(label, w); w->setStyle(new qsynthDialVokiStyle()); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SLIDERS // ////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addVerticalKnob(label, zone, init, min, max, step); return; } openVerticalBox(label); QSlider* w = new QSlider(Qt::Vertical); w->setMinimumHeight(160); w->setMinimumWidth(34); //w->setTickPosition(QSlider::TicksBothSides); uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); insert(label, w); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { if (isKnob(zone)) { addHorizontalKnob(label, zone, init, min, max, step); return; } openHorizontalBox(label); QSlider* w = new QSlider(Qt::Horizontal); w->setMinimumHeight(34); w->setMinimumWidth(160); //w->setTickPosition(QSlider::TicksBothSides); uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); insert(label, w); QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); addNumDisplay(0, zone, init, min, max, step); closeBox(); checkForTooltip(zone, w); } // ------------------------- passive widgets ----------------------------------- virtual void addNumDisplay(const char*, FAUSTFLOAT*, int) {} virtual void addTextDisplay(const char*, FAUSTFLOAT*, const char* [], FAUSTFLOAT, FAUSTFLOAT) {} virtual void addHorizontalBargraph(const char* label , FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { AbstractDisplay* bargraph; openVerticalBox(label); bool db = (fUnit[zone] == "dB"); if (fLedSet.count(zone)) { if (db) { bargraph = new dbLED(min, max); } else { bargraph = new LED(min,max); } } else { if (db) { bargraph = new dbHorizontalBargraph(min, max); } else { bargraph = new linHorizontalBargraph(min, max); } } new uiBargraph2(this, zone, bargraph, min, max); insert(label, bargraph); closeBox(); checkForTooltip(zone, bargraph); } virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { AbstractDisplay* bargraph; openVerticalBox(label); bool db = (fUnit[zone] == "dB"); if (fLedSet.count(zone)) { if (db) { bargraph = new dbLED(min, max); } else { bargraph = new LED(min,max); } } else { if (db) { bargraph = new dbVerticalBargraph(min, max); } else { bargraph = new linVerticalBargraph(min, max); } } new uiBargraph2(this, zone, bargraph, min, max); insert(label, bargraph); closeBox(); checkForTooltip(zone, bargraph); } }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/httpdUI.h000066400000000000000000000075371210074205700260710ustar00rootroot00000000000000/* Copyright (C) 2012 Grame - Lyon All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted. */ #ifndef __httpdUI__ #define __httpdUI__ #include "faust/gui/HTTPDControler.h" #include "faust/gui/GUI.h" /****************************************************************************** ******************************************************************************* HTTPD USER INTERFACE ******************************************************************************* *******************************************************************************/ /* Note about URLs and the Faust UI names: ---------------------------------------------------- Characters in a url could be: 1. Reserved: ; / ? : @ & = + $ , These characters delimit URL parts. 2. Unreserved: alphanum - _ . ! ~ * ' ( ) These characters have no special meaning and can be used as is. 3. Excluded: control characters, space, < > # % ", { } | \ ^ [ ] ` To solve potential conflicts between the Faust UI objects naming scheme and the URL allowed characters, the reserved and excluded characters are replaced with '-' (hyphen). Space or tabulation are replaced with '_' (underscore) */ using namespace std; class httpdUI : public UI { httpdfaust::HTTPDControler* fCtrl; const char* tr(const char* label) const; public: httpdUI(const char* applicationname, int argc, char *argv[]) { fCtrl = new httpdfaust::HTTPDControler(argc, argv, applicationname); } virtual ~httpdUI() { delete fCtrl; } // -- widget's layouts virtual void openTabBox(const char* label) { fCtrl->opengroup( "tgroup", tr(label)); } virtual void openHorizontalBox(const char* label) { fCtrl->opengroup( "hgroup", tr(label)); } virtual void openVerticalBox(const char* label) { fCtrl->opengroup( "vgroup", tr(label)); } virtual void closeBox() { fCtrl->closegroup(); } // -- active widgets virtual void addButton(const char* label, FAUSTFLOAT* zone) { fCtrl->addnode( "button", tr(label), zone); } virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { fCtrl->addnode( "checkbox", tr(label), zone); } virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "vslider", tr(label), zone, init, min, max, step); } virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "hslider", tr(label), zone, init, min, max, step); } virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { fCtrl->addnode( "nentry", tr(label), zone, init, min, max, step); } // -- passive widgets virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fCtrl->addnode( "hbargraph", tr(label), zone, min, max); } virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) { fCtrl->addnode( "vbargraph", tr(label), zone, min, max); } virtual void declare (FAUSTFLOAT* , const char* key, const char* val ) { fCtrl->declare(key, val); } void run() { fCtrl->run(); } }; const char* httpdUI::tr(const char* label) const { static char buffer[1024]; char * ptr = buffer; int n=1; while (*label && (n++ < 1024)) { switch (*label) { case ' ': case ' ': *ptr++ = '_'; break; case ';': case '/': case '?': case ':': case '@': case '&': case '=': case '+': case '$': case ',': case '<': case '>': case '#': case '%': case '"': case '{': case '}': case '|': case '\\': case '^': case '[': case ']': case '`': *ptr++ = '_'; break; default: *ptr++ = *label; } label++; } *ptr = 0; return buffer; } #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/meta.h000066400000000000000000000023451210074205700254260ustar00rootroot00000000000000/************************************************************************ ************************************************************************ FAUST Architecture File Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale --------------------------------------------------------------------- This Architecture section 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 3 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, see . ************************************************************************ ************************************************************************/ #ifndef __meta__ #define __meta__ struct Meta { virtual void declare(const char* key, const char* value) = 0; }; #endif radium_compressor-0.5.1/faudiostream/architecture/faust/gui/mocfaustqt.cpp000066400000000000000000000324171210074205700272240ustar00rootroot00000000000000/**************************************************************************** ** Meta object code from reading C++ file 'faustqt.h' ** ** Created: Fri Feb 25 08:07:38 2011 ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include "faustqt.h" #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'faustqt.h' doesn't include ." #elif Q_MOC_OUTPUT_REVISION != 62 #error "This file was generated using the moc from 4.7.0. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE static const uint qt_meta_data_uiButton[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 2, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 10, 9, 9, 9, 0x0a, 20, 9, 9, 9, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiButton[] = { "uiButton\0\0pressed()\0released()\0" }; const QMetaObject uiButton::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiButton, qt_meta_data_uiButton, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiButton::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiButton::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiButton::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiButton)) return static_cast(const_cast< uiButton*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiButton*>(this)); return QObject::qt_metacast(_clname); } int uiButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: pressed(); break; case 1: released(); break; default: ; } _id -= 2; } return _id; } static const uint qt_meta_data_uiCheckButton[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 17, 15, 14, 14, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiCheckButton[] = { "uiCheckButton\0\0v\0setState(int)\0" }; const QMetaObject uiCheckButton::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiCheckButton, qt_meta_data_uiCheckButton, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiCheckButton::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiCheckButton::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiCheckButton::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiCheckButton)) return static_cast(const_cast< uiCheckButton*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiCheckButton*>(this)); return QObject::qt_metacast(_clname); } int uiCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setState((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiSlider[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 12, 10, 9, 9, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiSlider[] = { "uiSlider\0\0v\0setValue(int)\0" }; const QMetaObject uiSlider::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiSlider, qt_meta_data_uiSlider, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiSlider::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiSlider::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiSlider::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiSlider)) return static_cast(const_cast< uiSlider*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiSlider*>(this)); return QObject::qt_metacast(_clname); } int uiSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiKnob[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 10, 8, 7, 7, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiKnob[] = { "uiKnob\0\0v\0setValue(int)\0" }; const QMetaObject uiKnob::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiKnob, qt_meta_data_uiKnob, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiKnob::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiKnob::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiKnob::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiKnob)) return static_cast(const_cast< uiKnob*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiKnob*>(this)); return QObject::qt_metacast(_clname); } int uiKnob::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< int(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_uiBargraph[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; static const char qt_meta_stringdata_uiBargraph[] = { "uiBargraph\0" }; const QMetaObject uiBargraph::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph, qt_meta_data_uiBargraph, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiBargraph::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiBargraph::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiBargraph::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiBargraph)) return static_cast(const_cast< uiBargraph*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiBargraph*>(this)); return QObject::qt_metacast(_clname); } int uiBargraph::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; return _id; } static const uint qt_meta_data_uiBargraph2[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; static const char qt_meta_stringdata_uiBargraph2[] = { "uiBargraph2\0" }; const QMetaObject uiBargraph2::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiBargraph2, qt_meta_data_uiBargraph2, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiBargraph2::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiBargraph2::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiBargraph2::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiBargraph2)) return static_cast(const_cast< uiBargraph2*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiBargraph2*>(this)); return QObject::qt_metacast(_clname); } int uiBargraph2::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; return _id; } static const uint qt_meta_data_uiNumEntry[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 14, 12, 11, 11, 0x0a, 0 // eod }; static const char qt_meta_stringdata_uiNumEntry[] = { "uiNumEntry\0\0v\0setValue(double)\0" }; const QMetaObject uiNumEntry::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_uiNumEntry, qt_meta_data_uiNumEntry, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &uiNumEntry::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *uiNumEntry::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *uiNumEntry::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_uiNumEntry)) return static_cast(const_cast< uiNumEntry*>(this)); if (!strcmp(_clname, "uiItem")) return static_cast< uiItem*>(const_cast< uiNumEntry*>(this)); return QObject::qt_metacast(_clname); } int uiNumEntry::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: setValue((*reinterpret_cast< double(*)>(_a[1]))); break; default: ; } _id -= 1; } return _id; } static const uint qt_meta_data_QTGUI[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 7, 6, 6, 6, 0x0a, 0 // eod }; static const char qt_meta_stringdata_QTGUI[] = { "QTGUI\0\0update()\0" }; const QMetaObject QTGUI::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_QTGUI, qt_meta_data_QTGUI, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &QTGUI::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *QTGUI::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *QTGUI::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_QTGUI)) return static_cast(const_cast< QTGUI*>(this)); if (!strcmp(_clname, "UI")) return static_cast< UI*>(const_cast< QTGUI*>(this)); return QObject::qt_metacast(_clname); } int QTGUI::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: update(); break; default: ; } _id -= 1; } return _id; } QT_END_MOC_NAMESPACE radium_compressor-0.5.1/find_moc_and_uic_paths.sh000077500000000000000000000013451210074205700222510ustar00rootroot00000000000000#!/bin/bash if which $1 >/dev/null 2>/dev/null ; then if $1 -v 2>&1 | grep Qt\ 4 >/dev/null ; then echo $1 exit 0 elif $1 -v 2>&1 | grep version\ 4 >/dev/null ; then echo $1 exit 0 fi fi if [ -f /etc/fedora-release ] ; then if uname -a |grep x86_64 >/dev/null ; then echo /usr/bin/$1-qt4 else echo /usr/bin/$1-qt4 fi elif grep -i ubuntu /etc/lsb-release >/dev/null 2>/dev/null ; then echo $1-qt4 elif grep -i debian /etc/lsb-release >/dev/null 2>/dev/null ; then echo $1-qt4 elif grep -i mint /etc/lsb-release >/dev/null 2>/dev/null ; then echo $1-qt4 elif grep -i arch /etc/lsb-release >/dev/null 2>/dev/null ; then echo $1 else echo $1 fi radium_compressor-0.5.1/main.cpp000066400000000000000000000225711210074205700167070ustar00rootroot00000000000000/* Copyright 2013 Kjetil S. Matheussen 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. */ #include #include #include "audio/faudiostream/architecture/faust/audio/dsp.h" #include "audio/faudiostream/architecture/faust/gui/UI.h" #include "myjack-dsp.h" #include #define OPTARGS_CHECK_GET(wrong,right) lokke==argc-1?(fprintf(stderr,"Must supply argument for '%s'\n",argv[lokke]),exit(-4),wrong):right #define OPTARGS_BEGIN(das_usage) {int lokke;const char *usage=das_usage;for(lokke=1;lokkeb) ? a : b; } inline int max (int a, int b) { return (a>b) ? a : b; } inline long max (long a, long b) { return (a>b) ? a : b; } inline long max (int a, long b) { return (a>b) ? a : b; } inline long max (long a, int b) { return (a>b) ? a : b; } inline float max (float a, float b) { return (a>b) ? a : b; } inline float max (int a, float b) { return (a>b) ? a : b; } inline float max (float a, int b) { return (a>b) ? a : b; } inline float max (long a, float b) { return (a>b) ? a : b; } inline float max (float a, long b) { return (a>b) ? a : b; } inline double max (double a, double b) { return (a>b) ? a : b; } inline double max (int a, double b) { return (a>b) ? a : b; } inline double max (double a, int b) { return (a>b) ? a : b; } inline double max (long a, double b) { return (a>b) ? a : b; } inline double max (double a, long b) { return (a>b) ? a : b; } inline double max (float a, double b) { return (a>b) ? a : b; } inline double max (double a, float b) { return (a>b) ? a : b; } inline int min (int a, int b) { return (a _controllers; std::vector _graphs; void remove_last_item(){ printf("Popping last effect\n"); _controllers.pop_back(); } void addEffect(const char *name, float* control_port, float min_value, float default_value, float max_value){ printf("Adding effect %s %p\n",name,control_port); _controllers.push_back(control_port); } void addButton(const char* label, float* zone) { addEffect(label, zone, 0, 0, 1); } void addToggleButton(const char* label, float* zone) { addEffect(label, zone, 0, 0, 1); } void addCheckButton(const char* label, float* zone) { addEffect(label, zone, 0, 0, 1); } void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) { addEffect(label, zone, min, init, max); } void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) { addEffect(label, zone, min, init, max); } void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) { addEffect(label, zone, min, init, max); // The INT effect format might not work. Need to go through the code first. } // -- passive widgets void addNumDisplay(const char* label, float* zone, int precision) {remove_last_item();} void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) {remove_last_item();} void addHorizontalBargraph(const char* label, float* zone, float min, float max) { _graphs.push_back(zone); //remove_last_item(); // remove metadata //next_peak = zone; } void addVerticalBargraph(const char* label, float* zone, float min, float max) { _graphs.push_back(zone); //remove_last_item(); // remove metadata //next_peak = zone; } }; mydsp *d; MyUI *ui; static void set_compressor_parameter(int num,float value){ float *controller = ui->_controllers.at(num); *controller = value; //printf("Setting controller %d (%p) to %f (%f)\n",num,controller,value,*controller); } static float get_compressor_parameter(int num){ float *controller = ui->_controllers.at(num); return *controller; } static float get_graph_value(int num){ float *controller = ui->_graphs.at(num); return *controller; } #include "mQt_compressor_widget_callbacks.h" static void set_colors(void){ das_colors[0] = QColor("#828070"); das_colors[1] = QColor("#00001d"); das_colors[2] = QColor("#f1ece6"); das_colors[3] = QColor("#98006d"); das_colors[4] = QColor("#6437a7"); das_colors[5] = QColor("#354353"); das_colors[6] = QColor("#8b6735"); das_colors[7] = QColor("#23405d"); das_colors[8] = QColor("#310062"); das_colors[9] = QColor("#8a8877"); das_colors[10] = QColor("#7a7a7a"); das_colors[11] = QColor("#696c5f"); das_colors[12] = QColor("#a1b09b"); das_colors[13] = QColor("#13511f"); das_colors[14] = QColor("#8a0000"); das_colors[15] = QColor("#7a7967"); } int main(int argc, char **argv){ const char *settings_filename = NULL; bool autoconnect = false; const char *jack_client_name = "radium_compressor"; OPTARGS_BEGIN("radium_compressor [--autoconnect] [--client-name s] [--settings-filename s] [settings-filename]\n" " [ -ac ] [ -cn s] [ -sn s] [settings filename]\n" "\n" "\"autoconnect\" connects radium_compressor to physical in and out ports.\n" "\"client-name\" sets the name of the jack client.\n" "\"settings-filename\" is the name of a settings file to load at startup.\n" ) { OPTARG("--settings-filename","-sn") settings_filename=OPTARG_GETSTRING(); OPTARG("--autoconnect","-ac") autoconnect=true; OPTARG("--client-name","-cn") jack_client_name=OPTARG_GETSTRING(); OPTARG_LAST() settings_filename=OPTARG_GETSTRING(); }OPTARGS_END; QApplication app(argc, argv); set_colors(); d = new mydsp; //d->init(44100); // d->init is called in audio.init. jackaudio audio; audio.init(jack_client_name, d); //finterface->recallState(rcfilename); audio.start(autoconnect); ui = new MyUI; d->buildUserInterface(ui); Compressor_widget compressor; if(settings_filename!=NULL) compressor.load(settings_filename); compressor.show(); QPalette pal = compressor.palette(); //pal.setColor(compressor.backgroundRole(), das_colors[11].light(200)); pal.setColor(compressor.backgroundRole(), das_colors[11].light(100)); compressor.setPalette(pal); app.exec(); audio.stop(); return 0; } radium_compressor-0.5.1/myjack-dsp.h000066400000000000000000000113401210074205700174620ustar00rootroot00000000000000 #ifndef __jack_dsp__ #define __jack_dsp__ #include #include #include "faust/audio/audio.h" #include "faust/audio/dsp.h" static int _srate(jack_nframes_t nframes, void *); static void _jack_shutdown(void *); static int _process (jack_nframes_t nframes, void *client); #ifdef _OPENMP static void* _jackthread(void* arg); #endif /****************************************************************************** ******************************************************************************* JACK AUDIO INTERFACE ******************************************************************************* *******************************************************************************/ class jackaudio : public audio { dsp* fDsp; jack_client_t* fClient; int fNumInChans; // number of input channels int fNumOutChans; // number of output channels jack_port_t * fInput_ports[256]; // Jack input ports jack_port_t * fOutput_ports[256]; // Jack output ports float* fInChannel[256]; // tables of noninterleaved input channels for FAUST float* fOutChannel[256]; // tables of noninterleaved output channels for FAUST public: jackaudio() : fClient(0), fNumInChans(0), fNumOutChans(0) {} virtual ~jackaudio() { stop(); } virtual bool init(const char*name, dsp* DSP) { fDsp = DSP; if ((fClient = jack_client_open(name, JackNullOption, NULL)) == 0) { fprintf(stderr, "jack server not running?\n"); return false; } #ifdef _OPENMP jack_set_process_thread(fClient, _jackthread, this); #else jack_set_process_callback(fClient, _process, this); #endif jack_set_sample_rate_callback(fClient, _srate, 0); jack_on_shutdown(fClient, _jack_shutdown, 0); fNumInChans = fDsp->getNumInputs(); fNumOutChans = fDsp->getNumOutputs(); for (int i = 0; i < fNumInChans; i++) { char buf[256]; snprintf(buf, 256, "in_%d", i); fInput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); } for (int i = 0; i < fNumOutChans; i++) { char buf[256]; snprintf(buf, 256, "out_%d", i); fOutput_ports[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } fDsp->init(jack_get_sample_rate(fClient)); return true; } virtual bool start(bool autoconnect) { if (jack_activate(fClient)) { fprintf(stderr, "cannot activate client"); return false; } if(autoconnect){ char** physicalInPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsInput); char** physicalOutPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (physicalOutPorts != NULL) { for (int i = 0; i < fNumInChans && physicalOutPorts[i]; i++) jack_connect(fClient, physicalOutPorts[i], jack_port_name(fInput_ports[i])); } if (physicalInPorts != NULL) { for (int i = 0; i < fNumOutChans && physicalInPorts[i]; i++) jack_connect(fClient, jack_port_name(fOutput_ports[i]), physicalInPorts[i]); } } return true; } virtual bool start(){ return start(true); } virtual void stop() { if (fClient) { jack_deactivate(fClient); for (int i = 0; i < fNumInChans; i++) jack_port_unregister(fClient, fInput_ports[i]); for (int i = 0; i < fNumOutChans; i++) jack_port_unregister(fClient, fOutput_ports[i]); jack_client_close(fClient); fClient = 0; } } // jack callbacks int process (jack_nframes_t nframes) { AVOIDDENORMALS; for (int i = 0; i < fNumInChans; i++) fInChannel[i] = (float *)jack_port_get_buffer(fInput_ports[i], nframes); for (int i = 0; i < fNumOutChans; i++) fOutChannel[i] = (float *)jack_port_get_buffer(fOutput_ports[i], nframes); fDsp->compute(nframes, fInChannel, fOutChannel); return 0; } #ifdef _OPENMP void process_thread () { jack_nframes_t nframes; while (1) { nframes = jack_cycle_wait(fClient); process (nframes); jack_cycle_signal(fClient, 0); } } #endif }; //---------------------------------------------------------------------------- // Jack Callbacks //---------------------------------------------------------------------------- static int _srate(jack_nframes_t nframes, void *) { printf("the sample rate is now %u/sec\n", nframes); return 0; } static void _jack_shutdown(void *) { exit(1); } static int _process(jack_nframes_t nframes, void *client) { jackaudio* jackclient = (jackaudio*)client; return jackclient->process (nframes); } #ifdef _OPENMP static void* _jackthread(void* arg) { jackaudio* jackclient = (jackaudio*)arg; jackclient->process_thread(); return 0; } #endif #endif