diff options
author | N.N. <matju@users.sourceforge.net> | 2010-01-05 22:49:36 +0000 |
---|---|---|
committer | N.N. <matju@users.sourceforge.net> | 2010-01-05 22:49:36 +0000 |
commit | 8dbec761cf858ea65900c8a094599857208d8c3a (patch) | |
tree | 3228c023f87f23a354da3b57fdc2afe5b7052032 /desiredata/src | |
parent | 529e59635598e2d90a7a49f6b4c676f8366109ba (diff) |
svn path=/trunk/; revision=12907
Diffstat (limited to 'desiredata/src')
120 files changed, 0 insertions, 64205 deletions
diff --git a/desiredata/src/ChangeLog b/desiredata/src/ChangeLog deleted file mode 100644 index aa5120d7..00000000 --- a/desiredata/src/ChangeLog +++ /dev/null @@ -1,249 +0,0 @@ -$Id: ChangeLog,v 1.1.4.11.2.44 2007/09/06 16:12:01 chunlee Exp $ - -DesireData 2009.06... : - * fixed some win32 (mingw) bugs (thanks to Patrice Colet) - * modal dialogues now appear on top of current window, not always main window - * added -stdout - * fixed osx scrolling - * -listdev not supported anymore - * made the patch appearance more like pd - * fixed some UI bugs - -DesireData 2008.02.19 : - - * added more Bokml (Norwegian) translations from Gisle Frysland - * added Nihongo (Japanese) translations from Kentaro Fukuchi - * added Dansk (Danish) translations from Steffen Leve Poulsen - * added Trke (Turkish) translations from Koray Tahiroglu - * added Nederlands (Dutch) translations from Tim Vets - * added Brasiliano (Brasilian Portuguese) translations from chgp - * added Russkij (Russian) translations from Ilya Dmitrichenko - * added History class to unify command history for Listener/Runcommand/TextBox - * KeyboardDialog clean up, added font selector for console and virtual keyboard - * Appearance settings can be applied at run time - * new object/wire indexing system (diff-friendly) - * Added keyboard/mouse macro recording, playback, and copy (to clipboard) - * [select] has as many inlets as it has arguments - * Added [macro] so that a macro can be played back in a patch using messagebox - * Added [clipboard] to pull the content of system clipboard - * Fixed variable width font support and TextBox code clean up - * Added object id display toggle - * Added [display] object - * Added patch editing commands - * Added expand_port - * Added profiler (object speed measurements) (not compiled in by default) - * Can now use spaces and \{} in IEM labels and some other places. - * Added Locale diff tool: localeutils.tcl - * Added [>~] [<~] [<=~] [>=~] [==~] [!=~] - * moved from CVS to SVN. - * officially requiring Tcl version >= 8.5 - -DesireData 2007.08.04 : - - * Unicode locales - * fixed type mismatch bug recently introduced in [unpack]... - * fixed lost console posts at startup - * turned most fprintf() into post() or error() - * added Chinese locale from Chun Lee - * added Polish locale from Michal Seta - * added object creation history - * added arrow keys and mouse clicks to KeyboardDialog - * added click drag and copy - * added background grid - * added snap to grid - * added new font selector (in client prefs) - -DesireData 2007.07.30 : - - * added classes [unpost], [tracecall], [parse], [unparse] - * non-constructed objects finally have a dashed box like they used to - * most of the rest of the C code switched to C++,PD_PLUSPLUS_FACE - * beginning to use C++ standard library components - * added event history view (help menu) - * added keyboard view - * fixed several bugs in copy/paste, undo/redo, subpatches, gop. - * added atom_ostream (similar to atom_string) - * lifted many string length restrictions - * fixed the hexmunge generator (for classnames with special chars) - * pd_error() is deprecated - * added verror(), added open_via_path2(), canvas_open2(), outlet_atom(), ... - * [route] and [select] support mixed floats and symbols - * [unpack] supports type "e" meaning any atom ("e" stands for "element") - * added variable mouse cursor sensitivity - * various fixes on keyboard navigation - -DesireData 2007.06.27 (which should have been 2007.01.12) : - - * merged new loader from Miller's pd 0.40-2 - * merged (but not tested) the rest of the [declare] code from pd 0.40-2 - * added gensym2 (support for NUL in symbols) - * most of the code now uses C++,PD_PLUSPLUS_FACE,class_new2,etc - * auto show/hide scrollbars - * menu bar can be disabled - * new Find widget (FireFox style) - * added "subpatcherize" (turn a selection into a subpatch) - * IEMGUI can now by controled with keyboard - * more general keyboard control - * merged t_alist and t_binbuf together and aliased them to t_list - * delay uploading until #X restore or #X pop - * don't upload all abstractions instances to client (much faster) - * introduced zombie objects to deal with dead objects - * Command evaluator per canvas window - * Added locale for Euskara (Basque) by Ibon Rodriguez Garcia - * PureUnity is now part of the DesireData project (but is designed to - run also on Miller's 0.40). - * added -port option in desire.tk so that server and client may - be started separately. - * PureUnity has type suffixes for some class families; for each $1 in - f,~,# (float,signal,grid) there is [inlet.$1] [outlet.$1] [taa.$1] - [op2.$1] [rand.$1] [norm.$1] [swap.$1] [packunpack3.$1] - * Other new PureUnity classes: [^] [commutator] [associator] - [invertor] [distributor] [tree] [protocols-tree] - -DesireData 0.40.pre5 (2006.12.19) (-r desiredata; ./configure && make) : - - * merged changes from Miller's pd 0.40-2 (80% of it) - * new canvas method "reply_with" of canvases replaces the implicit - reply-matching of pre4. (even less bug-prone) - * server-side wires and scalars appear to client just like other objects. - * floatatom,symbolatom,[nbx] use normal Tk text edition just like - ObjectBox,MessageBox,Comment have done for a while - * obsolete t_object fields removed: te_type te_width - * global object table (crash protection for bindless .x targets) - * variable width font usable in ObjectBoxes and MessageBoxes and Comments. - * [hsl] [vsl] support jump-on-click again - * lots of bugfixes - * -console and -lang moved to Client Preferences dialog - * added some more translations by Patrice Colet - * removed Find menu in main window - * added Find, Find Next, Find Last Error (canvas windows only) - * choose between horizontal and vertical in Properties of slider or radio. - -DesireData 0.39.A.pre4 (2006.12.07) (-r desiredata; ./configure && make) : - - * major speedup of the GUI (sometimes 3-4 times faster) - * lots of bugfixes - * logging of the socket into the terminal is now disabled by default - * introducing PD_PLUSPLUS_FACE, a new way to use <m_pd.h> and <desire.h> - * new branch "desiredata" instead of "devel_0_39". - * got rid of #ifdef DESIRE - * reply-matching in client-server protocol (less bug-prone) - * reversing the connection to what it was supposed to be: - the client connects to the server, not the other way around. - * the server uses [netreceive] to receive the connection from the GUI - * removed support for .pdsettings, .plist, microsoft registry. - * cross-platform libpd - * new titlebar icon - * removed t_guiconnect - * removed [scope] - -DesireData 0.39.A.pre3 (2006.11.27) (-r devel_0_39; ./configure && make) : - * franais updated by Patrice Colet - * italiano updated by Federico Ferri - * tons of bugfixes - * better pdrc editor (renamed to server prefs) - * removed media menu (split to: help menu, file menu, server prefs) - * removed Gdb box, added crash report dialog - * renamed objective.tcl to poe.tcl (because the name was already taken) - * replaced scons by autoconf and make (starting from Miller's 0.39's files) - * removed detection of Tcl (we don't need to use libtcl) - * removed the setuid option because no-one needs it; also fixed the - setuid security vulnerability in case someone does chmod u+s anyway - * Portaudio 18 is no longer supported. - * simplified configure.in (detector and makefile generator) - * APIs not compiled in show up in "pd -help", with a special mention - "(support not compiled in)"; those options don't give you a "unknown - option" when trying them, it says "option -foo not compiled in this pd". - * switched desire.c to C++, as another way to reduce redundancy in code. - * can be compiled without audio support. - * can be compiled without MIDI support. - * can --disable-portaudio on OSX - * added multiple wire connection support - * fixed copy/paste on canvas - * keyboard navigation pointer makeover - * added automatic object insertion support - -DesireData 0.39.A.pre2 (2006.11.12) (-r devel_0_39; scons desire=1) : - * espaol updated by Mario Mora - * subpatches - * GOPs - * abstraction instances - * multi-line objectboxes, messageboxes and comments - * keyboard-based navigation - * made desire.c C++ compatible (for future use) - * lots of things not written here - -DesireData 0.39.A.pre1 (-r devel_0_39; scons desire=1) : - * merged into the devel branch; enable with scons desire=1, which - disables lots of g_*.c files (and s_print.c) and enables desire.c; - use the std devel gui using desire=0. - * added an object-oriented programming system in desire.tk (do not - confuse with a dataflow system). added proc unknown, which allows - subject-verb-complement method-calling in tcl (aka objective.tcl) - * run the client to start the server and not the other way around: do wish desire.tk - * the client can make the server start via GDB - * added Pd box (like Ctrl+M but with history) - * added Gdb box - * menu translations in 8 languages - * classbrowser now show short descriptions in 3 languages - * objectbox tooltip now replaced by mini-classbrowser - * client conf editor - * other stuff I forget to write about - * looks for .ddrc - * pdrc and ddrc config becomes server and client configuration editor - * graphics rendering completely removed from the server - * toolbar and status bar can be enabled/disabled - * added Patcher->View->Reload: client reloads the patch from the server - * localization support (currently 8 languages: english, franais, deutsch, - catal, espaol, portugus, bokml, italiano.) - * lots of things not written here - -ImpureData 0.37.B : - * moving rendering to the TCL side - * moving event-handling to the TCL side too - * new file u_object.tk - * added pd_scanargs(), pd_upload(), sys_mgui(). - * added color schemes (modifiable in u_main.tk) - * switched to a jmaxish look - * merged g_vdial.c into g_hdial.c - * merged g_vslider.c into g_hslider.c - * added Patcher->View->Redraw - * added proc populate_menu, proc property_dialog - * added ~/.pd.tk loading - * inlet tooltips have new look - * rewrote all of the property dialogs - * added object class name completion (the <Tab> key) - * mouse scrollwheel works in patchers - * plus/minus button on tcl listener - * changed default font and borderwidth - * if conf not found in ~ ($HOME), - looks in Pd's install directory (eg. /usr/local/lib/pd) - * looks for .impdrc before .pdrc - * pdrc editor - * -help lists unavailable options with note "not compiled in" - * sys_vgui() message size limit removed - * new peak meters (thanks Carmen) - * dropper object outputs symbols of filenames (requires tkdnd) - * joe sarlo's VST-plugin i/o scheduler available on windows - * error() merged into pd_error() - and using strerror() to get meaningful error messages for failed I/O - * completely breaking compatibility with Pd's GUI externals - (for a good reason) - -ImpureData 0.37.A.2 (-r impd_0_37_A_2) : - * merged GG's reverting of "quote hack" - -ImpureData 0.37.A (-r impd_0_37_A) : - * forked from devel_0_37, 2004.02.21 - * added console for post() - * .pdrc: -console <number_of_lines> - * added button bar (that does like Ctrl+E & Put menu) - * .pdrc: -look <directory_of_icons> - (remember you can't use ~ nor $HOME in .pdrc) - * includes a selectable windowid (for those who know how to use it) - * class list dialog - * scans for loaded classes, abstractions/externs dirs - * help button fetches help file without needing to instantiate first - * filter box helps finding classes quickly - * displays some info on the class, like a list of defined methods and such. - * statusbar shows cursor position (enable with -statusbar) diff --git a/desiredata/src/TODO b/desiredata/src/TODO deleted file mode 100644 index f7b845f7..00000000 --- a/desiredata/src/TODO +++ /dev/null @@ -1,515 +0,0 @@ -DesireData's TODO list, $Id: TODO,v 1.1.2.28.2.63 2007/09/09 17:45:45 matju Exp $ - -LEGEND: - [c] client - [s] server - [b] both - ---- do those soon even though they're not in any milestone: -[ ] update translation credits -[s] encapsulate wires list -[s] observable boxes list -[s] observable wires list -[s] gop filter -[c] make List objects, to manage children, visible_children, wires, selection, selection_wires. - ---- those should be only things that will not be in milestones 1,2,3, until the progress bar. -[ ] Don't expand $0, $1, etc. in the struct name. (Jonathan Wilkes, 2009.09.14) -[ ] t_canvasenvironment->path can break in externals that access it directly (because of the type of ->dollarzero). -[ ] glerm says: backspace key problem in virtual keyboard -[s] rewrite [any] -[ ] right-click on an [s] or [r] would have an option "Find Matching Sends & Receives" -[c] split View into several classes (why?) -[s] [error] -[b] look into race conditions and locking -[s] take advantage of the support for zero-size arrays in gcc. (how?) -[s] make t_hash thread-safe (use external iterator) -[c] figure out what to do about the existence of [$self look] vs ordinary attributes (pointer_sense= and such) -[b] localise error messages -[s] new parser for nested lists and extended symbols -[s] remove more duplication of adc vs dac (see s_audio_*.c) -[s] [route] should be reconfigurable and accept pointer -[s] [select] should accept pointer -[s] [moses] should be multi-arg (and be aliased to [range] ?) -[s] get rid of stderr in server -[ ] pd-extended's [tcl_version] -[c] -path and -helppath listbox entries should be draggable (so that up/down buttons can be removed) -[s] finish merging 0.40 (wasn't it finished?) -[s] merge 0.41 (no?) -[s] merge 0.42 -[s] refcounted symbols -[c] redesign auto-apply so that it works without conflict with Ok/Cancel buttons -[c] simplify def Dialogue add -[b] rewrite [image], [display], [knob], [grid], [popup], ... -[s] merge martin peach's tcp externs into the core -[ ] sync pd.gif with pd_32.gif -[s] inheritance: [super] "instantiates" other abstraction with same $0; [self] allows sending messages to self; [declare super ...] makes the tree. -[ ] cleaner parsing of [expr]... remove int type because it causes e.g. [expr 8.0 / 10.0] = 0 but [expr 8.0/10.0] = 0.8 -[ ] how does [declare -stdpath] work? this is a mystery. can't get it to work in pd 0.40. -[ ] tidy_up/snap to grid -[c] change the order of the fields in Properties if it makes things more logical than the order of fields of savefn -[b] too much duplication of inlets vs outlets in source (where?) -[b] [t a] could be a very small GUI object (called "null object") -[b] all the [t] could be GUI objects -[b] GUI objects for [inlet] and [outlet] and [pd] ([page]) -[-] make a dd-extended -[s] SymbolBox could support dnd -[b] http://lists.puredata.info/pipermail/pd-dev/2007-10/009581.html -[s] what to do with post() in case of -nogui ? (it fills an ever-expanding buffer, does it?) -------------------8<------------------------------------progress-bar----------------------------------------------8<------------------ -[c] "can't read $@inchannels0" error in server prefs when there is no sound card. -[c] clicking on an object does not do Open. -[c] <Return> in Completion shouldn't finish the object. -[c] is pd_mess_split correct? e.g. does it handle \\; properly? -[c] make [display] look distinctive (not confusable with ObjectBox) -[c] correct the dozen problems you can see by using visual_diff on all_guis_and_gop.pd -[ ] help files for: [parse], [unparse], [clipboard], [display], etc. -[s] recreate abstr instances after abstr save -[s] [bng] messages get duplicated upon entering a subpatch??? -[s] counter-test.pd shows [nbx] jamming the update queue if too many updates at once...? -[s] queue priorities cause double call to changed() to change the expected order of updates (dangling pointer in client) -[c] Ctrl+e doesn't change Edit menu entry; likewise for visual_diff -[c] implement dirty flag (Save Changes? Save Changes? Save Changes? Save Changes? Save Changes? Save Changes? Save Changes?) -[s] canvas_resortinlets confuses wire upload -[s] should do canvas_resortinlets after moving objects -[s] writesf_free has deadlock. -[s] [netsend] is unreliable: buffer too full drops chunks of messages, not at message boundaries -[b] colorised console with hyperlinked error messages -[c] numbox: is_log -[c] [hradio] : chg -> is_log -[c] [vu] props : scale should appear instead of is_log -[s] update s_audio.c to support any number of devices (not just max 4) -[c] new way to do View get_canvas -[c] def Menuable raise {} {wm withdraw $w; wm deiconify $w -[b] GOP problems are back due to recent changes in canvas_map and canvas_vis. - now that abstractions don't get loaded into the client anymore, GOP can't always be drawn anymore too. - i mean, because the content of GOP is not uploaded to the client, so the client can't draw anything about it.. - unless def View outside_of_the_box are moved to the server side and the server only uploads what needs to be drawn - for gop - - another side effect of not uploading the content of [pd]/abs that i just found out is that, when deleting such object, - 1. the client won't be able to perform things like $wire deconstruct in def Canvas del, - as the object don't exists in the client side - 2. even if client don't call things like that, the server would still send -> delete message to the client, - which causes the same error because the object don't exists... - -[s] it might make sense to always upload subpatches but upload instances only when needed -[s] serial got sent too early when creating [pd] with push & #N canvas (http://pastebin.ca/318318) -[s] prevent hidden subpatches/abstraction-instances from being loaded in the client all of the time. -[b] fix gop - [c] reimplement View get_canvas so that it does not rely on [focus] - [s] gop contains can be drawn if not uploaded to client -[ ] fix deleteing/closing Canvas - [ ] server sends -> x806a3b8 delete twice - [ ] fix deletion order -[ ] graphical array rendering optimisation -[ ] fix double delete of [pd]; this is because [pd] is both an object in a patch and a patch itself, and "subscribe" doesn't distinguish. -[s] added "version 2" syntax parser (optional), which has nested lists, - extended quoting, extended float syntax - (some ex-symbols now parsed as floats: +1 +1.0 +1e8 0x10 and so on.) -[ ] atomically with multiple level - -[ ] PureUnity - [ ] benchmark - [ ] signals - [ ] grids - [ ] transitive, antisymmetric, predicate - [ ] contracts : *-rule.pd - [ ] tests for the frameworks' own components? - * not finished: - [glue-test] - [comparators-test] [arith-test] - [operator1-rule] [operator1-test] - [operator2-rule] [operator2-test] - -[s] those are the externs that have to be recompiled if I want to trap calls to return values of getfn. - ./externals/olafmatt/clone/clone.c:544: mess1(&cv->gl_pd, gensym("dsp"), sp); - ./externals/grill/dynext/src/main.cpp:952: mess1((t_pd *)canvas,const_cast<t_symbol *>(sym_dsp),NULL); - -[c] proc netsend doesn't escape newline... what else doesn't? which other chars need an escape fix? - -[s] allow helpfiles to load without having to "make install". -[s] MIDI loopback pseudo-device (inside pd) -[s] audio loopback pseudo-device (inside pd) -[s] use vector doubling in binbuf_add,binbuf_addv...? -[c] opening an already-open subpatch should just raise that subpatch -[c] hide inlets/outlets of IEMGUI when they have receive-symbols/send-symbols -[c] rightclick help doesn't work on [cnv]: tries to find help for "cnv.pd" ??? -[s] creating a graph causes crash. -[b] fix NumBox's height (box size follows font size) or just remove that setting -[b] fix NumBox's width (missing some fudge) -[b] fix std::map's apparent trouble getting exit() done properly - -Implement (or fix) Find: - with ability to search across canvases: - [ ] all canvases - [ ] all subcanvases (including invisible) - [ ] with regexps - [ ] with replace -[ ] in hsl-help.pd, [hsl] shouldn't appear as a Radio. -[ ] canvas dialogue: - [ ] add option for old-style GOP - [ ] make hidetext work - [ ] add units/pixel -[c] array button doesn't work (menuarray) -[c] implement timeout in def Manager call -[s] proper symbol quoting -[c] patching-in-tongues follow-up -[c] skip unneeded motion events inside client (do we need this?) -[b] rename pd to pd-server, desire.tk to pd-client, add new program "pd" which would launch both (will we really do this?) -[b] #V test with bg color -[c] kill global tooltip variable ? -[c] iemprops: min,max labels broken -[b] fix the [key] and [keyup] and [mouse] (?) classes -[s] fix all issues with backslashes and braces. -[c] implement def Canvas tidy -[c] set tk::mac::useCGDrawing 1 -[c] differential download (property dialogues autoapply) -[c] differential redraw -[b] improved dirty_lists including proper array support -[b] bang counter (instead of sending every bang message to client) -[b] implement garray -[c] implement a mark-and-sweep in order to find leaks... (?) -[ ] this seems fishy but might have good ideas -> http://www.rebelscience.org/Cosas/Reliability.htm -[c] make a statistical profiler for Tcl, if possible -[c] try to use profiler.tcl (tcllib) in a sensible way -[s] try C-oriented tools: - [ ] oprofile (with GUI) - [ ] memprof - [ ] sysprof - [ ] kprof - [ ] gprof - [ ] prospect - -[s] iirc, bang~ registers a timer callback. the problem is that the timer callbacks are only executed every dac block, - which is 64 samples. so running bang~ in subpatch with less than 64 samples, bang~ sets the same timer several times, - but it's only executed once. - -[b] think about this if you are reconsidering properties panels, I strongly encourage all y'all to make them Pd patches. - This is how Max/MSP does it and I think it would work very well for Pd as well. Sounds like this is a good opportunity - to make the switch. -- hcs - -<chun> 1. a keyboard operated cursor, a bit like Active, but one can use it like the mouse pointer -<chun> 2. snap to grid feature, or similiar -<chun> 3. prefix keybindings, like M-x in emacs - -Iohannes said about redirecting stdout/stderr: - pd -verbose -stderr 2>&1 | while read line; do echo "${line};" | pdsend 6666 localhost udp; done - -[b] [struct], scalar, DS-array, [plot], [drawpolygon], [drawnumber], ... -[c] desire.tk can be *really* loaded without Tk -[c] make commandline options reloadable at runtime -[x] canvas scrollbars auto-disappear when not needed. -[s] use gensym2() in builtin classes and stuff. -[s] fix 64-bit arrays so that carmen gets a use for DD. -[s] carmen also needs strings (no symbol leakage) -[c] right-click on labels for translations. -[b] http://www.w3.org/DesignIssues/Diff -[c] solve printing problems with GDB. use a pty (pseudo-teletype) ---> http://wiki.tcl.tk/3916 -[c] try TkZinc -[c] try Tcl/Gtk (Gnocl) with emulation layer -[?] http://www.comparisonics.com/gallery.html -[c] obiwannabe writes: - it would be good to have the choice as a comandline arg of the first one launched with a way - to accept patches to open in the same instance from, say a web browser. Like also when you are - in a file manager and browsing some .pd files you really want them to open in the same running instance. -[s] must work with ALL gridflow samples -[b] objectbox argument completion -[b] messagebox completion -[c] tooltips on arguments/inlets/outlets -[c] option to make non-gui objects appear on a GOP (?) -[b] multilingual labels in objects -[b] multilingual comments -[b] what would be needed to be able to use gdb --pid=... ? -[ ] set tk::mac::CGAntialiasLimit 2 -[ ] try Doxygen's callgraphs -[ ] try splint (http://www.splint.org/) -[ ] try uno -[ ] try CCCC -[ ] try OSX Shark -[ ] try http://www.drugphish.ch/~jonny/cca.html -[-] do we move the trac to artengine or not? -[c] remember that it's possible to use break in a bind-handler, to completely override system's behaviour. -[c] try: itcl itk iwidgets (itk implements megawidgets) -[c] try tkgate, a hardware sim program -[ ] try libentity -[c] try vtk-tcl -[s] make sure $0 actually works (see canvas_realizedollar) -[c] test rcv_able, snd_able -[?] iem: snd/rcv problem(s) ? (what was that?) -[c] [vu] have fcol in props ! -[c] [vu] has snd in props ! -[b] Duplicate wires? -[c] Can connect object to an object that is inside a GOP (!!!!) -[c] weird offset stuff when there are negative canvas coords sometimes. -[s] Bug: bad quoting in sys_mgui() -[b] Bug: spaces in name of vslider cause corruption of properties (devel_0_37) -[b] classlist: add method signatures -[c] bang flash delays should be reimplemented -[c] pdrc_options radio don't load/save -[c] patch window may open off-screen (all branches) -[c] patch window may open too big (all branches, osx) -[b] properties on objectboxes (generic dialogues tapping into method signatures) (?) - [s] hooks for outsourcing the preceding stuff to a plugin (eg: GridFlow, PyExt) -[b] [graph] is too slow (gui) for real big arrays -[b] VT100 colours in console ? -[b] freeform comments (no atom parsing) -[b] preserve whitespace in textboxes? -[b] inlet inspector to show what are the message types expected by an inlet - that could read like "int: set left operand; bang: do it" -[c] custom buttonbars (including premade objects with args like a [t b f] and such) - [c] with configurable hotkeys -[b] coloured wires -[b] insert_object makes error with multiple selection. -[c] popup_properties on multiple selection. -[b] segmented patchcords: - [c] a hotkey to click on the cord, and add a new segment - [c] a hotkey to drag the "points" (where two lines meet) - [c] a modifier key to delete a segment (actually the others should be that way too) - [c] you should be able to right click on a regular wire, and press "segment" or do a hotkey with it - and it automatically turns it into an straight-elbow multisegmented wire -[s] symbol vs strings: Ruby is right: the Symbol vs String distinction is annoying and possibly obsolete. - according to me, symbols exist mostly because LISP had them before they had strings, and because most - Strings implementations aren't powerful enough to be as fast (or almost as fast) as Symbols. - (well, for compatibility reasons, just like in Ruby, we can't remove symbol support completely, but - at least we can reduce the difference between strings and symbols to a minimum.) -[b] server-side IEMGUI could be turned into Tcl-based externs OR EVEN become abstractions. - it's possible to make a DesireData GUI for any Pd class, including abstractions. - to turn IEMGUI into an abstraction, what's missing is the savefn/saveargs/scanargs business. -[s] I would like to know how much it is feasible to compress the t_atom structure so that even with 64-bit pointers the t_atom - still stays 8 bytes instead of 16. I think it's possible, but not necessarily in a - backwards-compatible way, and not necessarily in a portable way. also maybe it's not that useful. -[c] splashscreen: we could make it different than other programs by inserting the splashscreen - inside the main window or we could make it a separate window but no timer, just an [OK] button, - so actually, this would be exactly the same as the "About" dialogue. -[s] turn [makefilename] into something that doesn't suck. (alias it to [sprintf] or [format]) - -[b] data inspector: when this tool is enabled, it prints on the console any data coming through whatever cable you - currently have selected. if you select multiple wires, it reports whats going through multiple wires. -[b] you need a way to see cpu usage on individual objects or on patchers or on groups of selected objects -[c] objectbox history: see whether ddrc should have a history count entry; - think about saving history; matju thought that it could be turned into a dynamic button bar that you can drag from. -[?] send to front, send to back -[c] make windows not get auto-resized to the width of the toolbar, so that people can have tiny windows. -[c] <Dossy> fconfigure -encoding binary ... -[s] implement the stuff that is in iostreams.txt - -[c] hcs implemented "recent files..." in devel. - -[c] Luke Iannini suggests some OSX bindings: - Command-` to switch between different windows within the application. - Command-, to bring up preferences (though this one is more difficult since there are multiple preference windows...) - Command-m to minimize the window (this currently brings up the "send message" dialogue box) - -[s] Claude: - Sending a message to vline~ creates a t_vseg, which are stored in a - sorted linear linked list, which means the time taken to add each new - line segment would be O(n), where n is the number of existing line segments. - -[-] look at some object sync protocols that we can think of: NFS for folders, palm sync for calendars, rsync for file contents - -[s] look at auto-vectorisation and figure out which versions of GCC really can do it (and not crash!) - -Marius Schebella: -I have a small keyboard shortcut wish: change between "entering mode" and "selected mode" with boxes. -when I create a new object/message... then it would be nice to have a -shortcut that switches from the mode, where the cursor is in the box to the -mode, where the object is selected. I think the tab-key could be used for -that. As it is now, I type something in, then I have to grab the mouse, then -klick, then select, then I can adjust it (which I also do with the keyboard, -because it is more precise). -I know the toggeling will not be possible when more objects are selected, -but maybe someone has an idea for that. - -[c] command for unpatcherizing a subpatch or abstraction (useful for making variants) - or for turning an abstraction into a subpatch. - -[s] I fixed it now, but I don't know if this is not a bug in pd 0.40: - -"The problem is, that canvas-local search path really tread each path as local to the canvas-path ( see line 1561 in g_canvas.c). -So if you add e.g. /usr/local/lib/pd/extra/iemmatrix, it will search for this path, but local to the canvas path - so if I started -Pd from /home/me it will search in /home/me//usr/local/lib/pd/extra/iemmatrix ! Is this a feature or a bug of Pd ?" -- Holzi - -[s] "I don't quite understand how this explains why wrap~ of -1 returns 1." -- steffen -[s] there's a [wrap~] but no [wrap]. there's a [>] but no [>~] (without externals). -- matju - -dmotd about converting patches to postscript: -"the internal pd postscript printer grabs the viewable canvas size, -this would need to change to encompass the virtual limits of the patch. -tcl/tk's 'canvas postscript' command takes the -width -height flags, -so making it the virtual bounds is trivial. this works for snapshotting -canvas bounds: sys_vgui("set cnv_bbox [.x%x.c bbox all] \n .x%x.c -postscript -file /tmp/canvas.ps -width [lindex $cnv_bbox 2] -height -[lindex $cnv_bbox 3] \n ", canvas, canvas); - -------------------8<--------cut-here--------8<------------------ - -Patching-in-tongues Project - -[ ] make entries counter and matcher. - - entries -en: english [ ] -es: espaol [ ] Mario Mora & Ramiro Cosentino -de: deutsch [ ] M Neupert, G Holzmann, T Grill -nb: bokml [ ] Gisle Frysland -it: italiano [ ] Davide Morelli + Federico Ferri -pt: portugus [ ] Nuno Godinho -fr: franais [ ] Patrice Colet -ca: catal [ ] Nria Verges -pl: polski [ ] Michal Seta -eu: euskara [ ] Ibon Rodriguez Garcia (Enrike Hurtado) -cn: chinese [ ] Chun Lee -jp: nihongo [ ] Kentaro Fukuchi -tu: trke [ ] ... Koray Tahiroglu -sv: svenska [ ] ... Daniel Skoglund (NOT FOUND) -br: brasiliano [ ] ... Gabriel Menotti -dk: dansk [ ] ... Steffen Leve Poulsen - -------------------8<--------cut-here--------8<------------------ -Dec 18 2006 - -1. there's no way to limit the size of the output buffer. If the other -side of the connection doesn't respond, the sending buffer just -inflates quickly. I've seen it happen that a bug in the sender causes -it to try to send so fast that it ate memory like an infinite recursion -or a forkbomb. - -2. That operation is not realtime-safe (but still it's much closer to -being so than just blocking...) - -3. It's only usable by the GUI socket and never by [netsend]. - -4. While that buffer together with t_guiqueue allow GUI updates to be -delayed for as long as necessary, it doesn't solve the problem that it can -send information that is already outdated and redundant. This can be -important in preventing problem #1 for a very heavy GUI. DesireData has -had this problem essentially dealt with since a long time, but it lacks -some fine tuning to get more robust. - -------------------8<--------cut-here--------8<------------------ - -<arjen> matju, you may be interested in "Jim" - that does have closures and on the Wiki you can find several attempts and - experiments regarding closures: http://wiki.tcl.tk/closures - -<matju> is there something like listbox but which works as a popup menu ? -<tclguy> tk_optionMenu is an old-school version -<tclguy> or get a combobox from BWidget or tile - -1. wish8.5 desire.tk city.pd &> err -2. ctrl+e, ctrl+a, shift+right*3 (or just once if profiling) -3. times (tclx) - -<matju> is there a wrapper for libagg for tcl? AGG of antigrain.com -<ijchain> <kbk> don't know of one, but SWIG, Critcl, or ffidl might plug the gap - -[initbang] & [closebang]: https://sourceforge.net/tracker/?func=detail&atid=478072&aid=1544041&group_id=55736 - -[s] Ed Kelly <morph_2016@yahoo.co.uk> reports that ALSA 24-bit output does not work? - -to dave griffiths: I think that this is three feature requests: -1. performing replacement of wire-object-wire by a single wire, as a -single operation in the GUI -2. make that operation atomic in terms of DSP recompilation. -3. break down DSP recompilation in pieces so that it is more "incremental" -for large patches. -In the case of object insertion, (2) and (3) are not implemented either, -but step (1) already has most of the desired effect; for the message -system, step (1) is all that is needed. DSP is more work and I know less -about DSP. It'll take me a while to get there; but (2) doesn't seem so -hard. - -http://www.tomsawyer.com/gallery/index.php - -[b] matju to atwood: - If I had automatic positioning in DesireData, it would be as an option: e.g. objects could default to "floating around" - (that is, automatic positioning), but be pinned down into specific positions. In that case, an exception has to be done - for [inlet] and [outlet] objects mostly. (the DS subsystem should be skipped over as well...) I could also have a use - for some semi-automatic repositionings: for example, there could be a keyboard shortcut to reposition a non-"floating" - object wherever it would go if it were floating, and if the user doesn't want it s/he can Ctrl+z it. - -http://www.graphdrawing.org/ - -<mamalala> you select a bunch of objects and group them together .... then you can select all the objects in that group -later, if needed, by its name like, you start to build some mixer patch .. and then you add a chain for an external fx, -so you can put all associated objects in the "ext.fx" group ... whenever it gets so messed up that you forgot what is -what, you can just select the groupt you want, and see/move/whatever the involved objects the group name could also act -as a template for the name of a subpatch, if one decides to finally put them into one .... - -#--------#--------#--------#--------#--------#--------#--------#--------#-------- -interface wishlist from timvets (2008 Feb 17) - -Hello, -here's my current Pd GUI wishlist, things that could streamline my work -flow, things that don't seem logical to me...etc: - -I wish: -[ ] going in and out of edit mode was reflected by the cursor turning into a hand or arrow immediately, - not requiring the user to move it first, who, if newbie, can get confused if he/she hasn't moved the mouse. - (this is the case on some versions I use in class, specifically pd-extended OSX I think) -[ ] shift-click-and-drag on a number box would also work after you already clicked. - Another idea: ctrl-click-drag to increment in steps of 10 or 100. -[ ] home, end, shift+left/right, ctrl+left/right, ctrl+shift+left/right would work within object boxes just like in a text editor. -[ ] click+drag a single object or messagebox wouldn't automatically activate text entry mode but the object itself stays the selection, - so that you can move it again or use arrow keys for repositioning without having to deselect+reselect first. -[ ] for a multiple connections facility, to connect all outlets of object a to all inlets of object b, and variations on that. - (I think max has had this for a while, and maybe desiredata ?). -[ ] 'subpatcherize' -[ ] that when deleting all text in a comment and clicking outside it, the comment would be deleted, so that if you save the patch, - close it, and reopen it, there doesn't appear the word 'comment' everywhere you left a 'blank' comment this way. Alternatively - it could become 'comment' upon finalizing an empty comment, so that you can still see, select and delete it. -[ ] the file browser (openpanel/savepanel) would support keystrokes to navigate: alt+up one dir up, tab to toggle focus between text - entry and graphical area (where folders and files are displayed)...etc -[ ] opening the filebrowser wouldn't cause the Pd main window to pop in front of all the patcher windows after it is closed. -[ ] one object could be finalized by clicking the outlet of another object, so that you can immediately connect it. The extra click - outside the object to finalize it first is unnecessary. When I click the outlet of another object, it is obvious that I am done - typing the name of the current one. - -#--------#--------#--------#--------#--------#--------#--------#--------#-------- -marius schebella 2008 Feb 17 - -Hi, -this list is great! I would like to add the one again that I posted -yesterday (sorry for double posting, but this thread subject is better) - -[ ] when only one object is selected and you start typing (any other than -arrows) it should be possible to write into the object without an -additional click into the object. I often use ctrl+d to duplicate an -object and then arrow keys to place it on the canvas, and then I would -like to just start typing into the object. -[ ] when there is more than one object selected and I click into one -object, but do not drag, then that object could switch to type-entry -mode. right now I have to unselect all objects by clicking into the -canvas and then click into the box to start text entry. -[ ] exiting entry mode with enter would actually be nice, too. (for -messages cr could be shift+enter (the cr is overwritten anyway). -[ ] more actions could be triggered by keyboard shortcuts? -[ ] the alt click and drag function. you click on an object and as soon -as you start dragging that object is duplicated, but at the same time -you already have the new object at the cursor position and can place it -fast at a new spot. - -I want to point out that in many cases this would mean different -behaviour between clicking, and clicking+dragging. - -plus new: keyboardshortcuts to bring the pd window to the front (to -watch console output. -[ ] and also change the cursor to arrow when you hit the command key to -imply that clicking on messages or numbers has different behaviour (play -mode) when you hit apple (or ctrl on win/lin?). - -marius. - -#--------#--------#--------#--------#--------#--------#--------#--------#-------- -http://autobuild.puredata.info/auto-build/2009-05-30/logs/2009-05-30_08.33.25_linux_ubuntu-intrepid-i386_pd-desiredata_run-automated-builder.txt -s_audio_oss.o s_audio_alsa.o s_audio_alsamm.o s_midi_alsa.o s_audio_jack.o s_midi_oss.o - -http://autobuild.puredata.info/auto-build/2009-05-30/logs/2009-05-30_08.11.32_linux_ubuntu-hardy-i386_pd-desiredata_run-automated-builder.txt -s_audio_oss.o s_audio_alsa.o s_audio_alsamm.o s_midi_alsa.o s_audio_jack.o s_midi_oss.o - -http://autobuild.puredata.info/auto-build/2009-05-30/logs/2009-05-30_06.48.53_linux_debian-lenny-powerpc_pd-desiredata_run-automated-builder.txt -s_audio_oss.o s_audio_alsa.o s_audio_alsamm.o s_midi_alsa.o s_audio_jack.o s_midi_oss.o - -http://autobuild.puredata.info/auto-build/2009-05-30/logs/2009-05-30_06.48.53_linux_debian-lenny-powerpc_pd-desiredata_run-automated-builder.txt -s_audio_oss.o s_audio_alsa.o s_audio_alsamm.o s_midi_alsa.o s_audio_jack.o s_midi_oss.o - diff --git a/desiredata/src/bgerror.tcl b/desiredata/src/bgerror.tcl deleted file mode 100644 index bff0dd2c..00000000 --- a/desiredata/src/bgerror.tcl +++ /dev/null @@ -1,254 +0,0 @@ -# bgerror.tcl -- -# -# Implementation of the bgerror procedure. It posts a dialog box with -# the error message and gives the user a chance to see a more detailed -# stack trace, and possible do something more interesting with that -# trace (like save it to a log). This is adapted from work done by -# Donal K. Fellows. -# -# Copyright (c) 1998-2000 by Ajuba Solutions. -# All rights reserved. -# -# RCS: @(#) $Id: bgerror.tcl,v 1.1.2.2.2.2 2007-08-12 02:38:45 matju Exp $ -# $Id: bgerror.tcl,v 1.1.2.2.2.2 2007-08-12 02:38:45 matju Exp $ - -package provide bgerror 8.4 - -namespace eval ::tk::dialog::error { - namespace import -force ::tk::msgcat::* - namespace export bgerror - option add *ErrorDialog.function.text [mc "Save To Log"] \ - widgetDefault - option add *ErrorDialog.function.command [namespace code SaveToLog] -} - -proc ::tk::dialog::error::Return {} { - variable button - .bgerrorDialog.ok configure -state active -relief sunken - update idletasks - after 100 - set button 0 -} - -proc ::tk::dialog::error::Details {} {if {[catch {Details2}]} {::error_dump}} -proc ::tk::dialog::error::Details2 {} { - set w .bgerrorDialog - set caption [option get $w.function text {}] - set command [option get $w.function command {}] - if { ($caption eq "") || ($command eq "") } { - grid forget $w.function - } - lappend command [.bgerrorDialog.top.info.text get 1.0 end-1c] - $w.function configure -text $caption -command $command - grid $w.top.info - -sticky nsew -padx 3m -pady 3m -} - -proc ::tk::dialog::error::SaveToLog {text} { - if { $::tcl_platform(platform) eq "windows" } { - set allFiles *.* - } else { - set allFiles * - } - set types [list \ - [list [mc "Log Files"] .log] \ - [list [mc "Text Files"] .txt] \ - [list [mc "All Files"] $allFiles]] - set filename [tk_getSaveFile -title [mc "Select Log File"] \ - -filetypes $types -defaultextension .log -parent .bgerrorDialog] - if {![string length $filename]} { - return - } - set f [open $filename w] - puts -nonewline $f $text - close $f -} - -proc ::tk::dialog::error::Destroy {w} { - if {$w eq ".bgerrorDialog"} { - variable button - set button -1 - } -} - -# ::tk::dialog::error::bgerror -- -# This is the default version of bgerror. -# It tries to execute tkerror, if that fails it posts a dialog box containing -# the error message and gives the user a chance to ask to see a stack -# trace. -# Arguments: -# err - The error message. - -proc ::tk::dialog::error::bgerror {err} {if {[catch { - global errorInfo tcl_platform - variable button - -# matju: use objective.tcl's -# set info $errorInfo - set info [::error_text] - - set ret [catch {::tkerror $err} msg]; - if {$ret != 1} {return -code $ret $msg} - - # Ok the application's tkerror either failed or was not found - # we use the default dialog then : - if {($tcl_platform(platform) eq "macintosh") - || ([tk windowingsystem] eq "aqua")} { - set ok [mc Ok] - set messageFont system - set textRelief flat - set textHilight 0 - } else { - set ok [mc OK] - set messageFont {Helvetica -14 bold} - set textRelief sunken - set textHilight 1 - } - - # Truncate the message if it is too wide (longer than 30 characacters) or - # too tall (more than 4 newlines). Truncation occurs at the first point at - # which one of those conditions is met. - set displayedErr "" - set lines 0 - foreach line [split $err \n] { - if {[string length $line]>30} { - append displayedErr "[string range $line 0 29]..." - break - } - if {$lines>4} { - append displayedErr "..." - break - } else { - append displayedErr "${line}\n" - } - incr lines - } - - set w .bgerrorDialog - set title [mc "Application Error"] - set text [mc {Error: %1$s} $err] - set buttons [list ok $ok dismiss [mc "Skip Messages"] \ - function [mc "Details >>"]] - - # 1. Create the top-level window and divide it into top - # and bottom parts. - - catch {destroy .bgerrorDialog} - toplevel .bgerrorDialog -class ErrorDialog - wm withdraw .bgerrorDialog - wm title .bgerrorDialog $title - wm iconname .bgerrorDialog ErrorDialog - wm protocol .bgerrorDialog WM_DELETE_WINDOW { } - - if {($tcl_platform(platform) eq "macintosh") - || ([tk windowingsystem] eq "aqua")} { - ::tk::unsupported::MacWindowStyle style .bgerrorDialog zoomDocProc - } - - frame .bgerrorDialog.bot - frame .bgerrorDialog.top - if {[tk windowingsystem] eq "x11"} { - .bgerrorDialog.bot configure -relief raised -bd 1 - .bgerrorDialog.top configure -relief raised -bd 1 - } - pack .bgerrorDialog.bot -side bottom -fill both - pack .bgerrorDialog.top -side top -fill both -expand 1 - - set W [frame $w.top.info] - text $W.text -bd 2 -yscrollcommand [list $W.scroll set] -setgrid true \ - -width 80 -height 10 -state normal -relief $textRelief -highlightthickness $textHilight -wrap char - - scrollbar $W.scroll -relief sunken -command [list $W.text yview] - pack $W.scroll -side right -fill y - pack $W.text -side left -expand yes -fill both -# $W.text insert 0.0 "$err\n$info" - $W.text insert 0.0 $info - $W.text mark set insert 0.0 - bind $W.text <ButtonPress-1> { focus %W } - $W.text configure -state disabled - - # 2. Fill the top part with bitmap and message. - # Max-width of message is the width of the screen... - set wrapwidth [winfo screenwidth .bgerrorDialog] - # ...minus the width of the icon, padding and a fudge factor for - # the window manager decorations and aesthetics. - set wrapwidth [expr {$wrapwidth-60-[winfo pixels .bgerrorDialog 9m]}] - label .bgerrorDialog.msg -justify left -text $text -font $messageFont \ - -wraplength $wrapwidth - if {($tcl_platform(platform) eq "macintosh") - || ([tk windowingsystem] eq "aqua")} { - # On the Macintosh, use the stop bitmap - label .bgerrorDialog.bitmap -bitmap stop - } else { - # On other platforms, make the error icon - canvas .bgerrorDialog.bitmap -width 32 -height 32 -highlightthickness 0 -bd 0 - .bgerrorDialog.bitmap create oval 0 0 31 31 -fill red -outline black - .bgerrorDialog.bitmap create line 9 9 23 23 -fill white -width 4 - .bgerrorDialog.bitmap create line 9 23 23 9 -fill white -width 4 - } - grid .bgerrorDialog.bitmap .bgerrorDialog.msg \ - -in .bgerrorDialog.top \ - -row 0 \ - -padx 3m \ - -pady 3m - grid configure .bgerrorDialog.msg -sticky nsw -padx {0 3m} - grid rowconfigure .bgerrorDialog.top 1 -weight 1 - grid columnconfigure .bgerrorDialog.top 1 -weight 1 - - # 3. Create a row of buttons at the bottom of the dialog. - set i 0 - foreach {name caption} $buttons { - button .bgerrorDialog.$name -text $caption -default normal -command [namespace code [list set button $i]] - grid .bgerrorDialog.$name -in .bgerrorDialog.bot -column $i -row 0 -sticky ew -padx 10 - grid columnconfigure .bgerrorDialog.bot $i -weight 1 - # We boost the size of some Mac buttons for l&f - if {($tcl_platform(platform) eq "macintosh") - || ([tk windowingsystem] eq "aqua")} { - if {($name eq "ok") || ($name eq "dismiss")} { - grid columnconfigure .bgerrorDialog.bot $i -minsize 79 - } - } - incr i - } - # The "OK" button is the default for this dialog. - .bgerrorDialog.ok configure -default active - - bind .bgerrorDialog <Return> [namespace code Return] - bind .bgerrorDialog <Destroy> [namespace code [list Destroy %W]] - .bgerrorDialog.function configure -command [namespace code Details] - - # 6. Update all the geometry information so we know how big it wants - # to be, then center the window in the display and deiconify it. - ::tk::PlaceWindow .bgerrorDialog - - # 7. Ensure that we are topmost. - raise .bgerrorDialog - if {$tcl_platform(platform) eq "windows"} { - # Place it topmost if we aren't at the top of the stacking - # order to ensure that it's seen - if {[lindex [wm stackorder .] end] ne ".bgerrorDialog"} { - wm attributes .bgerrorDialog -topmost 1 - } - } - - # 8. Set a grab and claim the focus too. - ::tk::SetFocusGrab .bgerrorDialog .bgerrorDialog.ok - - # 9. Wait for the user to respond, then restore the focus and - # return the index of the selected button. Restore the focus - # before deleting the window, since otherwise the window manager - # may take the focus away so we can't redirect it. Finally, - # restore any grab that was in effect. - vwait [namespace which -variable button] - set copy $button; # Save a copy... - ::tk::RestoreFocusGrab .bgerrorDialog .bgerrorDialog.ok destroy - if {$copy == 1} {return -code break} -}]} { - ::error_dump -}} - -namespace eval :: { - # Fool the indexer - proc bgerror err {} - rename bgerror {} - namespace import ::tk::dialog::error::bgerror -} diff --git a/desiredata/src/builtins.c b/desiredata/src/builtins.c deleted file mode 100644 index f1848957..00000000 --- a/desiredata/src/builtins.c +++ /dev/null @@ -1,3019 +0,0 @@ -/* Copyright (c) 2007 Mathieu Bouchard - Copyright (c) 1997-1999 Miller Puckette. - For information on usage and redistribution, - and for a DISCLAIMER OF ALL WARRANTIES, - see the file "LICENSE.txt" in this distribution. */ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include <stdlib.h> -#include <stdarg.h> -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <sstream> -#ifdef UNISTD -#include <sys/types.h> -#include <sys/time.h> -#include <sys/times.h> -#include <sys/param.h> -#include <unistd.h> -#endif -#ifdef MSW -#include <wtypes.h> -#include <time.h> -#endif -#ifdef MSW -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <netdb.h> -#include <stdio.h> -#define SOCKET_ERROR -1 -#endif -#ifdef MSW -#include <io.h> -#endif -#if defined (__APPLE__) || defined (__FreeBSD__) -#define HZ CLK_TCK -#endif -#include "config.h" - -#define a_float a_w.w_float -#define a_symbol a_w.w_symbol -#define a_pointer a_w.w_gpointer - -#define LIST_NGETBYTE 100 /* bigger that this we use alloc, not alloca */ - -/* #include <string.h> */ -#ifdef MSW -#include <malloc.h> -#else -#include <alloca.h> -#endif - -#define LOGTEN 2.302585092994 -#undef min -#undef max - -//conflict with min,max -//using namespace std; - -float mtof(float f) {return f>-1500 ? 8.17579891564 * exp(.0577622650 * min(f,1499.f)) : 0;} -float ftom(float f) {return f>0 ? 17.3123405046 * log(.12231220585 * f) : -1500;} -float powtodb(float f) {return f>0 ? max(100 + 10./LOGTEN * log(f),0.) : 0;} -float rmstodb(float f) {return f>0 ? max(100 + 20./LOGTEN * log(f),0.) : 0;} -float dbtopow(float f) {return f>0 ? exp((LOGTEN * 0.1 ) * (min(f,870.f)-100.)) : 0;} -float dbtorms(float f) {return f>0 ? exp((LOGTEN * 0.05) * (min(f,485.f)-100.)) : 0;} - -/* ------------- corresponding objects ----------------------- */ - -#define FUNC1(C,EXPR) \ -static t_class *C##_class; \ -static void *C##_new() { \ - t_object *x = (t_object *)pd_new(C##_class); \ - outlet_new(x, &s_float); return x;} \ -static void C##_float(t_object *x, t_float a) {x->outlet->send(EXPR);} -#define FUNC1DECL(C,SYM) \ - C##_class = class_new2(SYM,C##_new,0,sizeof(t_object),0,""); \ - class_addfloat(C##_class, (t_method)C##_float); \ - class_sethelpsymbol(C##_class,s); - -FUNC1(mtof, mtof(a)) -FUNC1(ftom, ftom(a)) -FUNC1(powtodb,powtodb(a)) -FUNC1(rmstodb,rmstodb(a)) -FUNC1(dbtorms,dbtorms(a)) -FUNC1(dbtopow,dbtopow(a)) - -/* -------------------------- openpanel ------------------------------ */ -static t_class *openpanel_class; -struct t_openpanel : t_object { - t_symbol *s; - t_symbol *path; -}; -static void *openpanel_new(t_symbol *s) { - t_openpanel *x = (t_openpanel *)pd_new(openpanel_class); - x->s = symprintf("d%lx",(t_int)x); - x->path = s; - pd_bind(x,x->s); - outlet_new(x,&s_symbol); - return x; -} -static void openpanel_bang(t_openpanel *x) { - sys_vgui("pdtk_openpanel {%s} {%s}\n", x->s->name, (x->path&&x->path->name)?x->path->name:"\"\""); -} -static void openpanel_symbol(t_openpanel *x, t_symbol *s) { - sys_vgui("pdtk_openpanel {%s} {%s}\n", x->s->name, (s && s->name) ? s->name : "\"\""); -} -static void openpanel_callback(t_openpanel *x, t_symbol *s) {x->outlet->send(s);} -static void openpanel_path(t_openpanel *x, t_symbol *s) {x->path=s;} -static void openpanel_free(t_openpanel *x) {pd_unbind(x, x->s);} -static void openpanel_setup() { - t_class *c = openpanel_class = class_new2("openpanel",openpanel_new,openpanel_free,sizeof(t_openpanel),0,"S"); - class_addbang(c, openpanel_bang); - class_addmethod2(c, openpanel_path, "path","s"); - class_addmethod2(c, openpanel_callback,"callback","s"); - class_addsymbol(c, openpanel_symbol); -} - -/* -------------------------- savepanel ------------------------------ */ -static t_class *savepanel_class; -struct t_savepanel : t_object { - t_symbol *s; - t_symbol *path; -}; -static void *savepanel_new(t_symbol*s) { - t_savepanel *x = (t_savepanel *)pd_new(savepanel_class); - x->s = symprintf("d%lx",(t_int)x); - x->path=s; - pd_bind(x, x->s); - outlet_new(x, &s_symbol); - return x; -} -static void savepanel_bang(t_savepanel *x) { - sys_vgui("pdtk_savepanel {%s} {%s}\n", x->s->name, (x->path&&x->path->name)?x->path->name:"\"\""); -} -static void savepanel_symbol(t_savepanel *x, t_symbol *s) { - sys_vgui("pdtk_savepanel {%s} {%s}\n", x->s->name, (s && s->name) ? s->name : "\"\""); -} -static void savepanel_callback(t_savepanel *x, t_symbol *s) {x->outlet->send(s);} -static void savepanel_free(t_savepanel *x) {pd_unbind(x, x->s);} -static void savepanel_setup() { - t_class *c = savepanel_class = class_new2("savepanel",savepanel_new,savepanel_free,sizeof(t_savepanel),0,"S"); - class_addbang(c, savepanel_bang); - class_addmethod2(c, openpanel_path, "path","s"); - class_addmethod2(c, savepanel_callback, "callback","s"); - class_addsymbol(c, savepanel_symbol); -} - -/* ---------------------- key and its relatives ------------------ */ -static t_symbol *key_sym, *keyup_sym, *keyname_sym; -static t_class *key_class, *keyup_class, *keyname_class; -struct t_key : t_object {}; -static void *key_new() { - t_key *x = (t_key *)pd_new(key_class); - outlet_new(x, &s_float); - pd_bind(x, key_sym); - return x; -} -static void key_float(t_key *x, t_floatarg f) {x->outlet->send(f);} - -struct t_keyup : t_object {}; -static void *keyup_new() { - t_keyup *x = (t_keyup *)pd_new(keyup_class); - outlet_new(x, &s_float); - pd_bind(x, keyup_sym); - return x; -} -static void keyup_float(t_keyup *x, t_floatarg f) {x->outlet->send(f);} - -struct t_keyname : t_object {}; -static void *keyname_new() { - t_keyname *x = (t_keyname *)pd_new(keyname_class); - outlet_new(x, &s_float); - outlet_new(x, &s_symbol); - pd_bind(x, keyname_sym); - return x; -} -static void keyname_list(t_keyname *x, t_symbol *s, int ac, t_atom *av) { - x->out(1)->send(atom_getsymbolarg(1, ac, av)); - x->out(0)->send(atom_getfloatarg( 0, ac, av)); -} -static void key_free( t_key *x) {pd_unbind(x, key_sym);} -static void keyup_free( t_keyup *x) {pd_unbind(x, keyup_sym);} -static void keyname_free(t_keyname *x) {pd_unbind(x, keyname_sym);} - -static void key_setup() { - key_class = class_new2("key", key_new, key_free, sizeof(t_key), CLASS_NOINLET,""); - keyup_class = class_new2("keyup", keyup_new, keyup_free, sizeof(t_keyup), CLASS_NOINLET,""); - keyname_class = class_new2("keyname",keyname_new,keyname_free,sizeof(t_keyname),CLASS_NOINLET,""); - class_addfloat(key_class, key_float); - class_addfloat(keyup_class, keyup_float); - class_addlist( keyname_class, keyname_list); - class_sethelpsymbol(keyup_class, gensym("key")); - class_sethelpsymbol(keyname_class, gensym("key")); - key_sym = gensym("#key"); - keyup_sym = gensym("#keyup"); - keyname_sym = gensym("#keyname"); -} - -static t_class *netsend_class; -struct t_netsend : t_object { - int fd; - int protocol; -}; -static void *netsend_new(t_floatarg udpflag) { - t_netsend *x = (t_netsend *)pd_new(netsend_class); - outlet_new(x, &s_float); - x->fd = -1; - x->protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM); - return x; -} -static void netsend_connect(t_netsend *x, t_symbol *hostname, t_floatarg fportno) { - struct sockaddr_in server; - int portno = (int)fportno; - if (x->fd >= 0) {error("netsend_connect: already connected"); return;} - /* create a socket */ - int sockfd = socket(AF_INET, x->protocol, 0); - if (sockfd < 0) {sys_sockerror("socket"); return;} - /* connect socket using hostname provided in command line */ - server.sin_family = AF_INET; - struct hostent *hp = gethostbyname(hostname->name); - if (!hp) {error("bad host?"); return;} -#if 0 - int intarg = 0; - if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&intarg, sizeof(intarg)) < 0) - error("setsockopt (SO_RCVBUF) failed"); -#endif - /* for stream (TCP) sockets, specify "nodelay" */ - if (x->protocol == SOCK_STREAM) { - int intarg = 1; - if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&intarg, sizeof(intarg)) < 0) - error("setsockopt (TCP_NODELAY) failed"); - } - memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); - /* assign client port number */ - server.sin_port = htons((u_short)portno); - post("connecting to port %d", portno); - /* try to connect. LATER make a separate thread to do this because it might block */ - if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0) { - sys_sockerror("connecting stream socket"); - sys_closesocket(sockfd); - return; - } - x->fd = sockfd; - x->outlet->send(1.); -} - -static void netsend_disconnect(t_netsend *x) { - if (x->fd < 0) return; - sys_closesocket(x->fd); - x->fd = -1; - x->outlet->send(0.); -} -static void netsend_send(t_netsend *x, t_symbol *s, int argc, t_atom *argv) { - if (x->fd < 0) {error("netsend: not connected"); return;} - t_binbuf *b = binbuf_new(); - t_atom at; - binbuf_add(b, argc, argv); - SETSEMI(&at); - binbuf_add(b, 1, &at); - char *buf; - int length, sent=0; - binbuf_gettext(b, &buf, &length); - char *bp = buf; - while (sent < length) { - static double lastwarntime; - static double pleasewarn; - double timebefore = sys_getrealtime(); - int res = send(x->fd, buf, length-sent, 0); - double timeafter = sys_getrealtime(); - int late = (timeafter - timebefore > 0.005); - if (late || pleasewarn) { - if (timeafter > lastwarntime + 2) { - post("netsend blocked %d msec", (int)(1000 * ((timeafter - timebefore) + pleasewarn))); - pleasewarn = 0; - lastwarntime = timeafter; - } else if (late) pleasewarn += timeafter - timebefore; - } - if (res <= 0) { - sys_sockerror("netsend"); - netsend_disconnect(x); - break; - } else { - sent += res; - bp += res; - } - } - free(buf); - binbuf_free(b); -} -static void netsend_free(t_netsend *x) {netsend_disconnect(x);} -static void netsend_setup() { - netsend_class = class_new2("netsend",netsend_new,netsend_free,sizeof(t_netsend),0,"F"); - class_addmethod2(netsend_class, netsend_connect, "connect","sf"); - class_addmethod2(netsend_class, netsend_disconnect, "disconnect",""); - class_addmethod2(netsend_class, netsend_send, "send","*"); -} - -static t_class *netreceive_class; -struct t_netreceive : t_object { - t_outlet *msgout; - t_outlet *connectout; - int connectsocket; - int nconnections; - int udp; -/* only used for sending (bidirectional socket to desire.tk) */ - t_socketreceiver *sr; -}; -static void netreceive_notify(t_netreceive *x) { - x->connectout->send(--x->nconnections); -} -static void netreceive_doit(t_netreceive *x, t_binbuf *b) { - int natom = binbuf_getnatom(b); - t_atom *at = binbuf_getvec(b); - for (int msg = 0; msg < natom;) { - int emsg; - for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA && at[emsg].a_type != A_SEMI; emsg++) {} - if (emsg > msg) { - for (int i = msg; i < emsg; i++) if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM) { - error("netreceive: got dollar sign in message"); - goto nodice; - } - if (at[msg].a_type == A_FLOAT) { - if (emsg > msg + 1) x->msgout->send(emsg-msg, at + msg); - else x->msgout->send(at[msg].a_float); - } else if (at[msg].a_type == A_SYMBOL) - x->msgout->send(at[msg].a_symbol,emsg-msg-1,at+msg+1); - } - nodice: - msg = emsg + 1; - } -} -static void netreceive_connectpoll(t_netreceive *x) { - int fd = accept(x->connectsocket, 0, 0); - if (fd < 0) post("netreceive: accept failed"); - else { - t_socketreceiver *y = socketreceiver_new((t_pd *)x, fd, - (t_socketnotifier)netreceive_notify, x->msgout?(t_socketreceivefn)netreceive_doit:0, 0); - sys_addpollfn(fd, (t_fdpollfn)socketreceiver_read, y); - x->connectout->send(++x->nconnections); - y->next = x->sr; - x->sr = y; - } -} -extern "C" t_text *netreceive_new(t_symbol *compatflag, t_floatarg fportno, t_floatarg udpflag) { - struct sockaddr_in server; - int udp = !!udpflag; - int old = !strcmp(compatflag->name , "old"); - int intarg; - /* create a socket */ - int sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0); - if (sockfd < 0) {sys_sockerror("socket"); return 0;} - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; -#if 1 - /* ask OS to allow another Pd to reopen this port after we close it. */ - intarg = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&intarg, sizeof(intarg)) < 0) - post("setsockopt (SO_REUSEADDR) failed"); -#endif -#if 0 - intarg = 0; - if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &intarg, sizeof(intarg)) < 0) - post("setsockopt (SO_RCVBUF) failed"); -#endif - /* Stream (TCP) sockets are set NODELAY */ - if (!udp) { - intarg = 1; - if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&intarg, sizeof(intarg)) < 0) - post("setsockopt (TCP_NODELAY) failed"); - } - /* assign server port number */ - server.sin_port = htons((u_short)fportno); - /* name the socket */ - if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { - sys_sockerror("bind"); - sys_closesocket(sockfd); - return 0; - } - t_netreceive *x = (t_netreceive *)pd_new(netreceive_class); - if (old) { - /* old style, nonsecure version */ - x->msgout = 0; - } else x->msgout = outlet_new(x, &s_anything); - if (udp) { /* datagram protocol */ - t_socketreceiver *y = socketreceiver_new((t_pd *)x, sockfd, (t_socketnotifier)netreceive_notify, - x->msgout ? (t_socketreceivefn)netreceive_doit : 0, 1); - sys_addpollfn(sockfd, (t_fdpollfn)socketreceiver_read, y); - x->connectout = 0; - } else { /* streaming protocol */ - if (listen(sockfd, 5) < 0) { - sys_sockerror("listen"); - sys_closesocket(sockfd); - sockfd = -1; - } else { - sys_addpollfn(sockfd, (t_fdpollfn)netreceive_connectpoll, x); - x->connectout = outlet_new(x, &s_float); - } - } - x->connectsocket = sockfd; - x->nconnections = 0; - x->udp = udp; - x->sr = 0; - return x; -} -static void netreceive_free(t_netreceive *x) { - /* LATER make me clean up open connections */ - if (x->connectsocket >= 0) { - sys_rmpollfn(x->connectsocket); - sys_closesocket(x->connectsocket); - } -} -static void netreceive_setup() { - netreceive_class = class_new2("netreceive",netreceive_new,netreceive_free,sizeof(t_netreceive),CLASS_NOINLET,"FFS"); -} -extern "C" t_socketreceiver *netreceive_newest_receiver(t_netreceive *x) {return x->sr;} - -struct t_qlist : t_object { - t_binbuf *binbuf; - int onset; /* playback position */ - t_clock *clock; - float tempo; - double whenclockset; - float clockdelay; - t_symbol *dir; - t_canvas *canvas; - int reentered; -}; -static void qlist_tick(t_qlist *x); -static t_class *qlist_class; -static void *qlist_new() { - t_qlist *x = (t_qlist *)pd_new(qlist_class); - x->binbuf = binbuf_new(); - x->clock = clock_new(x, (t_method)qlist_tick); - outlet_new(x, &s_list); - outlet_new(x, &s_bang); - x->onset = 0x7fffffff; - x->tempo = 1; - x->whenclockset = 0; - x->clockdelay = 0; - x->canvas = canvas_getcurrent(); - x->reentered = 0; - return x; -} -static void qlist_rewind(t_qlist *x) { - x->onset = 0; - if (x->clock) clock_unset(x->clock); - x->whenclockset = 0; - x->reentered = 1; -} -static void qlist_donext(t_qlist *x, int drop, int automatic) { - t_pd *target = 0; - while (1) { - int argc = binbuf_getnatom(x->binbuf), count, onset = x->onset, onset2, wasreentered; - t_atom *argv = binbuf_getvec(x->binbuf); - t_atom *ap = argv + onset, *ap2; - if (onset >= argc) goto end; - while (ap->a_type == A_SEMI || ap->a_type == A_COMMA) { - if (ap->a_type == A_SEMI) target = 0; - onset++, ap++; - if (onset >= argc) goto end; - } - if (!target && ap->a_type == A_FLOAT) { - ap2 = ap + 1; - onset2 = onset + 1; - while (onset2 < argc && ap2->a_type == A_FLOAT) onset2++, ap2++; - x->onset = onset2; - if (automatic) { - clock_delay(x->clock, x->clockdelay = ap->a_float * x->tempo); - x->whenclockset = clock_getsystime(); - } else x->outlet->send(onset2-onset,ap); - return; - } - ap2 = ap + 1; - onset2 = onset + 1; - while (onset2 < argc && (ap2->a_type == A_FLOAT || ap2->a_type == A_SYMBOL)) onset2++, ap2++; - x->onset = onset2; - count = onset2 - onset; - if (!target) { - if (ap->a_type != A_SYMBOL) continue; - target = ap->a_symbol->thing; - if (!target) {error("qlist: %s: no such object", ap->a_symbol->name); continue;} - ap++; - onset++; - count--; - if (!count) {x->onset = onset2; continue;} - } - wasreentered = x->reentered; - x->reentered = 0; - if (!drop) { - if (ap->a_type == A_FLOAT) typedmess(target, &s_list, count, ap); - else if (ap->a_type == A_SYMBOL) typedmess(target, ap->a_symbol, count-1, ap+1); - } - if (x->reentered) return; - x->reentered = wasreentered; - } /* while (1); never falls through */ - -end: - x->onset = 0x7fffffff; - x->out(1)->send(); - x->whenclockset = 0; -} -static void qlist_next(t_qlist *x, t_floatarg drop) {qlist_donext(x, drop != 0, 0);} -static void qlist_bang(t_qlist *x) {qlist_rewind(x); qlist_donext(x, 0, 1);} -static void qlist_tick(t_qlist *x) {x->whenclockset=0; qlist_donext(x, 0, 1);} -static void qlist_add(t_qlist *x, t_symbol *s, int ac, t_atom *av) { - t_atom a; - SETSEMI(&a); - binbuf_add(x->binbuf, ac, av); - binbuf_add(x->binbuf, 1, &a); -} -static void qlist_add2(t_qlist *x, t_symbol *s, int ac, t_atom *av) { - binbuf_add(x->binbuf, ac, av); -} -static void qlist_clear(t_qlist *x) { - qlist_rewind(x); - binbuf_clear(x->binbuf); -} -static void qlist_set(t_qlist *x, t_symbol *s, int ac, t_atom *av) { - qlist_clear(x); - qlist_add(x, s, ac, av); -} -static void qlist_read(t_qlist *x, t_symbol *filename, t_symbol *format) { - int cr = 0; - if (!strcmp(format->name, "cr")) cr = 1; - else if (*format->name) error("qlist_read: unknown flag: %s", format->name); - if (binbuf_read_via_canvas(x->binbuf, filename->name, x->canvas, cr)) - error("%s: read failed", filename->name); - x->onset = 0x7fffffff; - x->reentered = 1; -} -static void qlist_write(t_qlist *x, t_symbol *filename, t_symbol *format) { - int cr = 0; - char *buf = canvas_makefilename(x->canvas,filename->name,0,0); - if (!strcmp(format->name, "cr")) cr = 1; - else if (*format->name) error("qlist_read: unknown flag: %s", format->name); - if (binbuf_write(x->binbuf,buf,"",cr)) error("%s: write failed", filename->name); - free(buf); -} -static void qlist_print(t_qlist *x) { - post("--------- textfile or qlist contents: -----------"); - binbuf_print(x->binbuf); -} -static void qlist_tempo(t_qlist *x, t_float f) { - float newtempo; - if (f < 1e-20) f = 1e-20; - else if (f > 1e20) f = 1e20; - newtempo = 1./f; - if (x->whenclockset != 0) { - float elapsed = clock_gettimesince(x->whenclockset); - float left = x->clockdelay - elapsed; - if (left < 0) left = 0; - left *= newtempo / x->tempo; - clock_delay(x->clock, left); - } - x->tempo = newtempo; -} -static void qlist_free(t_qlist *x) { - binbuf_free(x->binbuf); - if (x->clock) clock_free(x->clock); -} - -static t_class *textfile_class; -typedef t_qlist t_textfile; -static void *textfile_new() { - t_textfile *x = (t_textfile *)pd_new(textfile_class); - x->binbuf = binbuf_new(); - outlet_new(x, &s_list); - outlet_new(x, &s_bang); - x->onset = 0x7fffffff; - x->reentered = 0; - x->tempo = 1; - x->whenclockset = 0; - x->clockdelay = 0; - x->clock = NULL; - x->canvas = canvas_getcurrent(); - return x; -} -static void textfile_bang(t_textfile *x) { - int argc = binbuf_getnatom(x->binbuf), onset = x->onset, onset2; - t_atom *argv = binbuf_getvec(x->binbuf); - t_atom *ap = argv + onset, *ap2; - while (onset < argc && (ap->a_type == A_SEMI || ap->a_type == A_COMMA)) onset++, ap++; - onset2 = onset; - ap2 = ap; - while (onset2 < argc && (ap2->a_type != A_SEMI && ap2->a_type != A_COMMA)) onset2++, ap2++; - if (onset2 > onset) { - x->onset = onset2; - if (ap->a_type == A_SYMBOL) x->outlet->send(ap->a_symbol,onset2-onset-1,ap+1); - else x->outlet->send( onset2-onset ,ap ); - } else { - x->onset = 0x7fffffff; - x->out(1)->send(); - } -} - -static void textfile_rewind(t_qlist *x) {x->onset = 0;} -static void textfile_free(t_textfile *x) {binbuf_free(x->binbuf);} - -extern t_pd *newest; - -/* the "list" object family. - - list append - append a list to another - list prepend - prepend a list to another - list split - first n elements to first outlet, rest to second outlet - list trim - trim off "list" selector - list length - output number of items in list - -Need to think more about: - list foreach - spit out elements of a list one by one (also in reverse?) - list array - get items from a named array as a list - list reverse - permute elements of a list back to front - list pack - synonym for 'pack' - list unpack - synonym for 'unpack' - list cat - build a list by accumulating elements - -Probably don't need: - list first - output first n elements. - list last - output last n elements - list nth - nth item in list, counting from zero -*/ - -/* -------------- utility functions: storage, copying -------------- */ - -#if HAVE_ALLOCA -#define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)((n) < LIST_NGETBYTE ? \ - alloca((n) * sizeof(t_atom)) : getbytes((n) * sizeof(t_atom)))) -#define ATOMS_FREEA(x, n) ( \ - ((n) < LIST_NGETBYTE || (free((x)), 0))) -#else -#define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)getbytes((n) * sizeof(t_atom))) -#define ATOMS_FREEA(x, n) (free((x))) -#endif - -static void atoms_copy(int argc, t_atom *from, t_atom *to) { - for (int i = 0; i < argc; i++) to[i] = from[i]; -} - -/* ------------- fake class to divert inlets to ----------------- */ -static void alist_list(t_binbuf *x, t_symbol *s, int argc, t_atom *argv) { - binbuf_clear(x); - x->v = (t_atom *)getbytes(argc * sizeof(*x->v)); - if (!x->v) {x->n = 0; error("list_alloc: out of memory"); return;} - x->n = argc; - for (int i = 0; i < argc; i++) x->v[i] = argv[i]; -} -static void alist_anything(t_binbuf *x, t_symbol *s, int argc, t_atom *argv) { - binbuf_clear(x); - x->v = (t_atom *)getbytes((argc+1) * sizeof(*x->v)); - if (!x->v) {x->n = 0; error("list_alloc: out of memory"); return;} - x->n = argc+1; - SETSYMBOL(&x->v[0], s); - for (int i = 0; i < argc; i++) x->v[i+1] = argv[i]; -} -static void alist_toatoms(t_binbuf *x, t_atom *to) {for (size_t i=0; i<x->n; i++) to[i] = x->v[i];} - -//t_class *list_any_class; struct t_list_any : t_object {t_binbuf *alist;}; -t_class *list_append_class; struct t_list_append : t_object {t_binbuf *alist;}; -t_class *list_prepend_class; struct t_list_prepend : t_object {t_binbuf *alist;}; -t_class *list_split_class; struct t_list_split : t_object {t_float f;}; -t_class *list_trim_class; struct t_list_trim : t_object {}; -t_class *list_length_class; struct t_list_length : t_object {}; - -static t_pd *list_append_new(t_symbol *s, int argc, t_atom *argv) { - t_list_append *x = (t_list_append *)pd_new(list_append_class); - x->alist = binbuf_new(); alist_list(x->alist, 0, argc, argv); outlet_new(x, &s_list); inlet_new(x,x->alist, 0, 0); - return x; -} -static t_pd *list_prepend_new(t_symbol *s, int argc, t_atom *argv) { - t_list_prepend *x = (t_list_prepend *)pd_new(list_prepend_class); - x->alist = binbuf_new(); alist_list(x->alist, 0, argc, argv); outlet_new(x, &s_list); inlet_new(x,x->alist,0,0); - return x; -} -static void list_append_free (t_list_append *x) {binbuf_free(x->alist);} -static void list_prepend_free(t_list_prepend *x) {binbuf_free(x->alist);} - -static void list_append_list(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; int outc = x->alist->n + argc; ATOMS_ALLOCA(outv, outc); - atoms_copy(argc, argv, outv); - alist_toatoms(x->alist, outv+argc); - x->outlet->send(outc,outv); ATOMS_FREEA(outv,outc); -} -static void list_append_anything(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; int outc = x->alist->n+argc+1; ATOMS_ALLOCA(outv, outc); - SETSYMBOL(outv, s); - atoms_copy(argc, argv, outv + 1); - alist_toatoms(x->alist, outv + 1 + argc); - x->outlet->send(outc,outv); ATOMS_FREEA(outv,outc); -} -static void list_prepend_list(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; int outc = x->alist->n + argc; ATOMS_ALLOCA(outv, outc); - alist_toatoms(x->alist, outv); - atoms_copy(argc, argv, outv + x->alist->n); - x->outlet->send(outc,outv); ATOMS_FREEA(outv,outc); -} -static void list_prepend_anything(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; int outc = x->alist->n+argc+1; ATOMS_ALLOCA(outv, outc); - alist_toatoms(x->alist, outv); - SETSYMBOL(outv + x->alist->n, s); - atoms_copy(argc, argv, outv + x->alist->n + 1); - x->outlet->send(outc,outv); ATOMS_FREEA(outv,outc); -} -static t_pd *list_split_new(t_floatarg f) { - t_list_split *x = (t_list_split *)pd_new(list_split_class); - outlet_new(x, &s_list); - outlet_new(x, &s_list); - outlet_new(x, &s_list); - floatinlet_new(x, &x->f); - x->f = f; - return x; -} -static void list_split_list(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { - int n = (int)x->f; - if (n<0) n=0; - if (argc >= n) { - x->out(1)->send(argc-n,argv+n); - x->out(0)->send(n,argv); - } else x->out(2)->send(argc,argv); -} -static void list_split_anything(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; - ATOMS_ALLOCA(outv, argc+1); - SETSYMBOL(outv, s); - atoms_copy(argc, argv, outv + 1); - list_split_list(x, &s_list, argc+1, outv); - ATOMS_FREEA(outv, argc+1); -} - -static t_pd *list_trim_new() { - t_list_trim *x = (t_list_trim *)pd_new(list_trim_class); - outlet_new(x, &s_list); - return x; -} -static void list_trim_list(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { - if (argc < 1 || argv[0].a_type != A_SYMBOL) x->outlet->send(argc,argv); - else x->outlet->send(argv[0].a_symbol,argc-1,argv+1); -} -static void list_trim_anything(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(s,argc,argv);} - -static t_pd *list_length_new() { - t_list_length *x = (t_list_length *)pd_new(list_length_class); - outlet_new(x, &s_float); - return x; -} -static void list_length_list( t_list_length *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(float(argc));} -static void list_length_anything(t_list_length *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(float(argc+1));} - -static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { - t_pd *newest = 0; /* hide global var */ - if (!argc || argv[0].a_type != A_SYMBOL) newest = list_append_new(s, argc, argv); - else { - t_symbol *s2 = argv[0].a_symbol; - if (s2 == gensym("append")) newest = list_append_new(s, argc-1, argv+1); - else if (s2 == gensym("prepend")) newest = list_prepend_new(s, argc-1, argv+1); - else if (s2 == gensym("split")) newest = list_split_new(atom_getfloatarg(1, argc, argv)); - else if (s2 == gensym("trim")) newest = list_trim_new(); - else if (s2 == gensym("length")) newest = list_length_new(); - else error("list %s: unknown function", s2->name); - } - /* workaround for bug in kernel.c */ - if (newest) pd_set_newest(newest); - return newest; -} - -#define LISTOP(name,argspec,freer) \ - list_##name##_class = class_new2("list " #name,list_##name##_new,freer,sizeof(t_list_##name),0,argspec); \ - class_addlist(list_##name##_class, list_##name##_list); \ - class_addanything(list_##name##_class, list_##name##_anything); \ - class_sethelpsymbol(list_##name##_class, &s_list); - -static void list_setup () { - LISTOP(append,"*",list_append_free) - LISTOP(prepend,"*",list_prepend_free) - LISTOP(split,"F",0) - LISTOP(trim,"",0) - LISTOP(length,"",0) - class_addcreator2("list",list_new,"*"); -} - -/* miller's "homebrew" linear-congruential algorithm */ -static t_class *random_class; -struct t_random : t_object { - t_float f; - unsigned int state; -}; -static int makeseed() { - static unsigned int random_nextseed = 1489853723; - random_nextseed = random_nextseed * 435898247 + 938284287; - return random_nextseed & 0x7fffffff; -} -static void *random_new(t_floatarg f) { - t_random *x = (t_random *)pd_new(random_class); - x->f = f; - x->state = makeseed(); - floatinlet_new(x,&x->f); - outlet_new(x,&s_float); - return x; -} -static void random_bang(t_random *x) { - int n = (int)x->f, nval; - int range = max(n,1); - unsigned int randval = x->state; - x->state = randval = randval * 472940017 + 832416023; - nval = (int)((double)range * (double)randval * (1./4294967296.)); - if (nval >= range) nval = (int)(range-1); - x->outlet->send(nval); -} -static void random_seed(t_random *x, float f, float glob) {x->state = (int)f;} -static void random_setup() { - random_class = class_new2("random",random_new,0,sizeof(t_random),0,"F"); - class_addbang(random_class, random_bang); - class_addmethod2(random_class, random_seed,"seed","f"); -} - -static t_class *loadbang_class; -struct t_loadbang : t_object {}; -static void *loadbang_new() { - t_loadbang *x = (t_loadbang *)pd_new(loadbang_class); - outlet_new(x,&s_bang); - return x; -} -static void loadbang_loadbang(t_loadbang *x) { - if (!sys_noloadbang) x->outlet->send(); -} -static void loadbang_setup() { - loadbang_class = class_new2("loadbang",loadbang_new,0,sizeof(t_loadbang),CLASS_NOINLET,""); - class_addmethod2(loadbang_class, loadbang_loadbang, "loadbang",""); -} - -static t_class *namecanvas_class; -struct t_namecanvas : t_object { - t_symbol *sym; - t_pd *owner; -}; -static void *namecanvas_new(t_symbol *s) { - t_namecanvas *x = (t_namecanvas *)pd_new(namecanvas_class); - x->owner = (t_pd *)canvas_getcurrent(); - x->sym = s; - if (*s->name) pd_bind(x->owner, s); - return x; -} -static void namecanvas_free(t_namecanvas *x) { - if (*x->sym->name) pd_unbind(x->owner, x->sym); -} -static void namecanvas_setup() { - namecanvas_class = class_new2("namecanvas",namecanvas_new,namecanvas_free,sizeof(t_namecanvas),CLASS_NOINLET,"S"); -} - -static t_class *cputime_class; -struct t_cputime : t_object { -#ifdef UNISTD - struct tms setcputime; -#endif -#ifdef MSW - LARGE_INTEGER kerneltime; - LARGE_INTEGER usertime; - bool warned; -#endif -}; -static t_class *realtime_class; struct t_realtime : t_object {double setrealtime;}; -static t_class *timer_class; struct t_timer : t_object {double settime;}; - - -static void cputime_bang(t_cputime *x) { -#ifdef UNISTD - times(&x->setcputime); -#endif -#ifdef MSW - FILETIME ignorethis, ignorethat; - BOOL retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, - (FILETIME *)&x->kerneltime, (FILETIME *)&x->usertime); - if (!retval) { - if (!x->warned) {error("cputime is apparently not supported on your platform"); return;} - x->warned = 1; - x->kerneltime.QuadPart = 0; - x->usertime.QuadPart = 0; - } -#endif -} -static void cputime_bang2(t_cputime *x) { -#ifdef UNISTD - struct tms newcputime; - times(&newcputime); - float elapsedcpu = 1000 * (newcputime.tms_utime + newcputime.tms_stime - - x->setcputime.tms_utime - x->setcputime.tms_stime) / HZ; -#endif -#ifdef MSW - FILETIME ignorethis, ignorethat; - LARGE_INTEGER usertime, kerneltime; - BOOL retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, (FILETIME *)&kerneltime, (FILETIME *)&usertime); - float elapsedcpu = retval ? 0.0001 * - ((kerneltime.QuadPart - x->kerneltime.QuadPart) + - (usertime.QuadPart - x->usertime.QuadPart)) : 0; -#endif - x->outlet->send(elapsedcpu); -} - -static void realtime_bang(t_realtime *x) {x->setrealtime = sys_getrealtime();} -static void timer_bang(t_timer *x ) {x->settime = clock_getsystime();} -static void realtime_bang2(t_realtime *x) {x->outlet->send((sys_getrealtime() - x->setrealtime) * 1000.);} -static void timer_bang2(t_timer *x ) {x->outlet->send(clock_gettimesince(x->settime));} - -static void *cputime_new() { - t_cputime *x = (t_cputime *)pd_new(cputime_class); - outlet_new(x,gensym("float")); - inlet_new(x,x,gensym("bang"),gensym("bang2")); -#ifdef MSW - x->warned = 0; -#endif - cputime_bang(x); - return x; -} -static void *realtime_new() { - t_realtime *x = (t_realtime *)pd_new(realtime_class); - outlet_new(x,gensym("float")); - inlet_new(x,x,gensym("bang"),gensym("bang2")); - realtime_bang(x); - return x; -} -static void *timer_new(t_floatarg f) { - t_timer *x = (t_timer *)pd_new(timer_class); - timer_bang(x); - outlet_new(x, gensym("float")); - inlet_new(x, x, gensym("bang"), gensym("bang2")); - return x; -} -static void timer_setup() { - realtime_class = class_new2("realtime",realtime_new,0,sizeof(t_realtime),0,""); - cputime_class = class_new2("cputime", cputime_new, 0,sizeof(t_cputime), 0,""); - timer_class = class_new2("timer", timer_new, 0,sizeof(t_timer), 0,"F"); - class_addbang(realtime_class, realtime_bang); - class_addbang(cputime_class, cputime_bang); - class_addbang(timer_class, timer_bang); - class_addmethod2(realtime_class,realtime_bang2,"bang2",""); - class_addmethod2(cputime_class, cputime_bang2, "bang2",""); - class_addmethod2(timer_class, timer_bang2, "bang2",""); -} - -static t_class *print_class; -struct t_print : t_object { - t_symbol *sym; -}; -static void *print_new(t_symbol *s) { - t_print *x = (t_print *)pd_new(print_class); - if (*s->name) x->sym = s; - else x->sym = gensym("print"); - return x; -} -static void print_bang(t_print *x) {post("%s: bang", x->sym->name);} -static void print_pointer(t_print *x, t_gpointer *gp) {post("%s: (gpointer)", x->sym->name);} -static void print_float(t_print *x, t_float f) {post("%s: %g", x->sym->name, f);} -static void print_list(t_print *x, t_symbol *s, int argc, t_atom *argv) { - if (argc && argv->a_type != A_SYMBOL) startpost("%s:", x->sym->name); - else startpost("%s: %s", x->sym->name, (argc>1 ? s_list : argc==1 ? s_symbol : s_bang).name); - postatom(argc, argv); - endpost(); -} -static void print_anything(t_print *x, t_symbol *s, int argc, t_atom *argv) { - startpost("%s: %s", x->sym->name, s->name); - postatom(argc, argv); - endpost(); -} -static void print_setup() { - t_class *c = print_class = class_new2("print",print_new,0,sizeof(t_print),0,"S"); - class_addbang(c, print_bang); - class_addfloat(c, print_float); - class_addpointer(c, print_pointer); - class_addlist(c, print_list); - class_addanything(c, print_anything); -} - -/*---- Macro ----*/ -static t_class *macro_class; -struct t_macro : t_object { - t_symbol *sym; - t_outlet *bangout; -}; - -static void *macro_new(t_symbol *s) { - t_macro *x = (t_macro *)pd_new(macro_class); - if (*s->name) x->sym = s; - else x->sym = gensym("macro"); - x-> bangout = outlet_new(x, &s_bang); - return x; -} - -static void macro_bang(t_macro *x) {x->bangout->send();} - -static void macro_send(t_macro *x, t_symbol *s, int argc, t_atom *argv) { - std::ostringstream t; - t << s->name; - for (int i=0; i<argc; i++) {t << " " << &argv[i];} - sys_mgui(x->dix->canvas, "macro_event_append", "Sp", t.str().data(), x); -} -static void macro_setup() { - t_class *c = macro_class = class_new2("macro",macro_new,0,sizeof(t_macro),0,"S"); - class_addanything(c, macro_send); - class_addmethod2(c, macro_bang, "mbang",""); -} - -/*---- Clipboard ----*/ -static t_class *clipboard_class; -struct t_clipboard : t_object { - t_binbuf *alist; - t_symbol *sym; - t_outlet *dump; -}; - -static void *clipboard_new(t_symbol *s) { - t_clipboard *x = (t_clipboard *)pd_new(clipboard_class); - if (*s->name) x->sym = s; - else x->sym = gensym("clipboard"); - x->alist = binbuf_new(); - x->dump = outlet_new(x,&s_list); - return x; -} - -static void clipboard_bang(t_clipboard *x) {sys_mgui(x->dix->canvas, "get_clipboard", "p", x);} -static void clipboard_reply (t_clipboard *x, t_symbol *s, int argc, t_atom *argv) {x->dump->send(argc,argv);} - -static void clipboard_setup() { - t_class *c = clipboard_class = class_new2("clipboard",clipboard_new,0,sizeof(t_clipboard),0,"S"); - class_addbang(c, clipboard_bang); - class_addmethod2(c, clipboard_reply,"clipboard_set","*"); -} - -/*---- Display ----*/ -static t_class *display_class; -struct t_display : t_object { - t_float height; -}; - -static void *display_new(t_floatarg f) { - t_display *x = (t_display *)pd_new(display_class); - x->height = f; - if (!x->height) x->height = 1; - return x; -} - -static void display_height (t_display *x) {sys_mgui(x, "height=", "i", (int)x->height);} - -static void display_send(t_display *x, t_symbol *s, int argc, t_atom *argv) { - std::ostringstream t; - t << s->name; - for (int i=0; i<argc; i++) {t << " " << &argv[i];} - sys_mgui(x, "dis", "S", t.str().data()); -} - -static void display_setup() { - t_class *c = display_class = class_new2("display",display_new,0,sizeof(t_display),0,"F"); - class_addanything(c, display_send); - class_addmethod2(c, display_height, "height",""); -} - -/*---- Any ----*/ -static t_class *any_class; -struct t_any : t_object {t_binbuf *alist;}; - -static void *any_new(t_symbol *s,int argc, t_atom *argv) { - t_any *x = (t_any *)pd_new(any_class); - x->alist = binbuf_new(); - if (argc) { - if (argv[0].a_type == A_FLOAT) {alist_list(x->alist, 0, argc, argv);} - if (argv[0].a_type == A_SYMBOL) {alist_anything(x->alist, argv[0].a_symbol, argc-1, argv+1);} - } - outlet_new(x, &s_anything); - inlet_new(x,x->alist, 0, 0); - return x; -} - -static void any_anything(t_any *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *outv; int outc = x->alist->n+argc+1; ATOMS_ALLOCA(outv, outc); - if ((argv[0].a_type == A_FLOAT && s==&s_list) || s==&s_float) { - alist_list(x->alist,0,argc,argv); x->outlet->send(argc,argv); return; - } - if ( argv[0].a_type == A_SYMBOL || s!=&s_list || s!=&s_float) { - alist_anything(x->alist,s,argc,argv); x->outlet->send(s,argc,argv); - } -} - -static void any_bang(t_any *x) { - t_atom *outv; int outc = x->alist->n; - ATOMS_ALLOCA(outv, outc); - alist_toatoms(x->alist, outv); - if (!binbuf_getnatom(x->alist)) {x->outlet->send();return;} - if (outv[0].a_type == A_FLOAT) {x->outlet->send(outc,outv);} - if (outv[0].a_type == A_SYMBOL) {x->outlet->send(outv[0].a_symbol,outc-1,outv+1);} - ATOMS_FREEA(outv, outc); -} - -static void any_setup() { - post("DesireData iemlib2 [any] clone"); - t_class *c = any_class = class_new2("any",any_new,0,sizeof(t_any),0,"*"); - class_addanything(c, any_anything); - class_addbang(c, any_bang); -} - -/* MSW and OSX don't appear to have single-precision ANSI math */ -#if defined(MSW) || defined(__APPLE__) -#define sinf sin -#define cosf cos -#define atanf atan -#define atan2f atan2 -#define sqrtf sqrt -#define logf log -#define expf exp -#define fabsf fabs -#define powf pow -#endif - -struct t_binop : t_object { - t_float f1; - t_float f2; -}; -static void *binop_new(t_class *floatclass, t_floatarg f) { - t_binop *x = (t_binop *)pd_new(floatclass); - outlet_new(x, &s_float); - floatinlet_new(x, &x->f2); - x->f1 = 0; - x->f2 = f; - return x; -} - -#define BINOP(NAME,EXPR) \ -static t_class *NAME##_class; \ -static void *NAME##_new(t_floatarg f) {return binop_new(NAME##_class, f);} \ -static void NAME##_bang(t_binop *x) {float a=x->f1,b=x->f2; x->outlet->send(EXPR);} \ -static void NAME##_float(t_binop *x, t_float f) {x->f1=f; NAME##_bang(x);} - -BINOP(binop_plus,a+b) -BINOP(binop_minus,a-b) -BINOP(binop_times,a*b) -BINOP(binop_div,a/b) -BINOP(binop_pow, a>0?powf(a,b):0) -BINOP(binop_max, a>b?a:b) -BINOP(binop_min, a<b?a:b) -BINOP(binop_ee,a==b) -BINOP(binop_ne,a!=b) -BINOP(binop_gt,a>b) -BINOP(binop_lt,a<b) -BINOP(binop_ge,a>=b) -BINOP(binop_le,a<=b) -BINOP(binop_ba,(int)a&(int)b) -BINOP(binop_la,a&&b) -BINOP(binop_bo,(int)a|(int)b) -BINOP(binop_lo,a||b) -BINOP(binop_ls,(int)a<<(int)b) -BINOP(binop_rs,(int)a>>(int)b) -BINOP(binop_pc,(int)a % (b?(int)b:1)) -static int mymod(int a, int b) { - int n2 = (int)b; - if (n2 < 0) n2 = -n2; else if (!n2) n2 = 1; - int r = (int)a % n2; - return r<0 ? r+n2 : r; -} -BINOP(binop_mymod, (float)mymod((int)a,(int)b)) -static int mydiv(int a, int b) { - if (b < 0) b=-b; else if (!b) b=1; - if (a < 0) a -= b-1; - return a/b; -} -BINOP(binop_mydiv, (float)mydiv((int)a,(int)b)) - -BINOP(binop_atan2, (a==0 && b==0 ? 0 : atan2f(a,b))); - -FUNC1(sin,sinf(a)) -FUNC1(cos,cosf(a)) -FUNC1(tan,tanf(a)) -FUNC1(atan,atanf(a)) - -FUNC1(sqrt,sqrtf(a)) -FUNC1(log, a>0 ? logf(a) : -1000) -FUNC1(exp,expf(min(a,87.3365f))) -FUNC1(abs,fabsf(a)) - -static t_class *clip_class; -struct t_clip : t_object { - float f1; - float f2; - float f3; -}; -static void *clip_new(t_floatarg f2, t_floatarg f3) { - t_clip *x = (t_clip *)pd_new(clip_class); - floatinlet_new(x, &x->f2); x->f2 = f2; - floatinlet_new(x, &x->f3); x->f3 = f3; - outlet_new(x, &s_float); - return x; -} -static void clip_bang( t_clip *x) { x->outlet->send(clip(x->f1,x->f2,x->f3));} -static void clip_float(t_clip *x, t_float f) {x->f1 = f; x->outlet->send(clip(x->f1,x->f2,x->f3));} - -void arithmetic_setup() { - t_symbol *s = gensym("operators"); -#define BINOPDECL(NAME,SYM) \ - NAME##_class = class_new2(SYM,NAME##_new,0,sizeof(t_binop),0,"F"); \ - class_addbang(NAME##_class, NAME##_bang); \ - class_addfloat(NAME##_class, (t_method)NAME##_float); \ - class_sethelpsymbol(NAME##_class,s); - - BINOPDECL(binop_plus,"+") - BINOPDECL(binop_minus,"-") - BINOPDECL(binop_times,"*") - BINOPDECL(binop_div,"/") - BINOPDECL(binop_pow,"pow") - BINOPDECL(binop_max,"max") - BINOPDECL(binop_min,"min") - - s = gensym("otherbinops"); - - BINOPDECL(binop_ee,"==") - BINOPDECL(binop_ne,"!=") - BINOPDECL(binop_gt,">") - BINOPDECL(binop_lt,"<") - BINOPDECL(binop_ge,">=") - BINOPDECL(binop_le,"<=") - - BINOPDECL(binop_ba,"&") - BINOPDECL(binop_la,"&&") - BINOPDECL(binop_bo,"|") - BINOPDECL(binop_lo,"||") - BINOPDECL(binop_ls,"<<") - BINOPDECL(binop_rs,">>") - - BINOPDECL(binop_pc,"%") - BINOPDECL(binop_mymod,"mod") - BINOPDECL(binop_mydiv,"div") - BINOPDECL(binop_atan2,"atan2"); - - s = gensym("math"); - -#define FUNCDECL(NAME,SYM) \ - NAME##_class = class_new2(SYM,NAME##_new,0,sizeof(t_object),0,""); \ - class_addfloat(NAME##_class, (t_method)NAME##_float); \ - class_sethelpsymbol(NAME##_class,s); - - FUNCDECL(sin,"sin"); - FUNCDECL(cos,"cos"); - FUNCDECL(tan,"tan"); - FUNCDECL(atan,"atan"); - FUNCDECL(sqrt,"sqrt"); - FUNCDECL(log,"log"); - FUNCDECL(exp,"exp"); - FUNCDECL(abs,"abs"); - - clip_class = class_new2("clip",clip_new,0,sizeof(t_clip),0,"FF"); - class_addfloat(clip_class, clip_float); - class_addbang(clip_class, clip_bang); -} - -static t_class *pdint_class; struct t_pdint : t_object {t_float v;}; -static t_class *pdfloat_class; struct t_pdfloat : t_object {t_float v;}; -static t_class *pdsymbol_class; struct t_pdsymbol : t_object {t_symbol *v;}; -static t_class *bang_class; struct t_bang : t_object {}; - -static void pdint_bang(t_pdint *x) {x->outlet->send(t_float(int(x->v)));} -static void pdint_float(t_pdint *x, t_float v) {x->v = v; pdint_bang(x);} - -static void pdfloat_bang(t_pdfloat *x) {x->outlet->send(x->v);} -static void pdfloat_float(t_pdfloat *x, t_float v) {x->v=v; pdfloat_bang(x);} - -static void pdsymbol_bang(t_pdsymbol *x) {x->outlet->send(x->v);} -static void pdsymbol_symbol( t_pdsymbol *x, t_symbol *v ) {x->v=v; pdsymbol_bang(x);} -static void pdsymbol_anything(t_pdsymbol *x, t_symbol *v, int ac, t_atom *av) {x->v=v; pdsymbol_bang(x);} - -/* For "list" message don't just output "list"; if empty, we want to bang the symbol and - if it starts with a symbol, we output that. Otherwise it's not clear what we should do - so we just go for the "anything" method. LATER figure out if there are other places - where empty lists aren't equivalent to "bang"??? Should Pd's message passer always check - and call the more specific method, or should it be the object's responsibility? Dunno... */ -#if 0 -static void pdsymbol_list(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av) { - if (!ac) pdsymbol_bang(x); - else if (av->a_type == A_SYMBOL) pdsymbol_symbol(x, av->a_symbol); - else pdsymbol_anything(x, s, ac, av); -} -#endif - -static void *pdint_new(t_floatarg v) { - t_pdint *x = (t_pdint *) pd_new(pdint_class ); x->v=v; outlet_new(x,&s_float); floatinlet_new(x,&x->v); - return x; -} -static void *pdfloat_new(t_pd *dummy, t_float v) { - t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class); x->v=v; outlet_new(x,&s_float); floatinlet_new(x,&x->v); - pd_set_newest((t_pd *)x); - return x; -} -static void *pdfloat_new2(t_floatarg f) {return pdfloat_new(0, f);} -static void *pdsymbol_new(t_pd *dummy, t_symbol *v) { - t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class); x->v=v; outlet_new(x, &s_symbol); symbolinlet_new(x, &x->v); - pd_set_newest((t_pd *)x); - return x; -} -static void *bang_new(t_pd *dummy) { - t_bang *x = (t_bang *)pd_new(bang_class); - outlet_new(x, &s_bang); - pd_set_newest((t_pd *)x); - return x; -} -static void *bang_new2(t_bang f) {return bang_new(0);} -static void bang_bang(t_bang *x) {x->outlet->send();} - -void misc_setup() { - pdint_class = class_new2("int",pdint_new,0,sizeof(t_pdint),0,"F"); - class_addcreator2("i",pdint_new,"F"); - class_addbang(pdint_class, pdint_bang); - class_addfloat(pdint_class, pdint_float); - pdfloat_class = class_new2("float",pdfloat_new,0,sizeof(t_pdfloat),0,"F"); - class_addcreator2("f",pdfloat_new2,"F"); - class_addbang(pdfloat_class, pdfloat_bang); - class_addfloat(pdfloat_class, pdfloat_float); - pdsymbol_class = class_new2("symbol",pdsymbol_new,0,sizeof(t_pdsymbol),0,"S"); - class_addbang(pdsymbol_class, pdsymbol_bang); - class_addsymbol(pdsymbol_class, pdsymbol_symbol); - class_addanything(pdsymbol_class, pdsymbol_anything); - t_class *c = bang_class = class_new2("bang",bang_new,0,sizeof(t_bang),0,""); - class_addcreator2("b",bang_new2,""); - class_addbang(c, bang_bang); - class_addfloat(c, bang_bang); - class_addsymbol(c, bang_bang); - class_addlist(c, bang_bang); - class_addanything(c, bang_bang); -} - -/* -------------------- send & receive ------------------------------ */ - -static t_class * send_class; struct t_send : t_object {t_symbol *sym;}; -static t_class *receive_class; struct t_receive : t_object {t_symbol *sym;}; - -static void send_bang( t_send *x) { if (x->sym->thing) pd_bang(x->sym->thing);} -static void send_float( t_send *x, t_float f) { if (x->sym->thing) pd_float(x->sym->thing,f);} -static void send_symbol( t_send *x, t_symbol *s) { if (x->sym->thing) pd_symbol(x->sym->thing,s);} -static void send_pointer( t_send *x, t_gpointer *gp) { if (x->sym->thing) pd_pointer(x->sym->thing,gp);} -static void send_list( t_send *x, t_symbol *s, int argc, t_atom *argv) {if (x->sym->thing) pd_list(x->sym->thing,s,argc,argv);} -static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv) {if (x->sym->thing) typedmess(x->sym->thing,s,argc,argv);} - -static void receive_bang( t_receive *x) { x->outlet->send();} -static void receive_float( t_receive *x, t_float v) { x->outlet->send(v);} -static void receive_symbol( t_receive *x, t_symbol *v) { x->outlet->send(v);} -static void receive_pointer( t_receive *x, t_gpointer *v) { x->outlet->send(v);} -static void receive_list( t_receive *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send( argc,argv);} -static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(s,argc,argv);} -static void *receive_new(t_symbol *s) { - t_receive *x = (t_receive *)pd_new(receive_class); - x->sym = s; - pd_bind(x, s); - outlet_new(x, 0); - return x; -} -static void receive_free(t_receive *x) {pd_unbind(x, x->sym);} - -static void *send_new(t_symbol *s) { - t_send *x = (t_send *)pd_new(send_class); - if (!*s->name) symbolinlet_new(x, &x->sym); - x->sym = s; - return x; -} -static void sendreceive_setup() { - t_class *c; - c = send_class = class_new2("send",send_new,0,sizeof(t_send),0,"S"); - class_addcreator2("s",send_new,"S"); - class_addbang(c, send_bang); - class_addfloat(c, send_float); - class_addsymbol(c, send_symbol); - class_addpointer(c, send_pointer); - class_addlist(c, send_list); - class_addanything(c, send_anything); - c = receive_class = class_new2("receive",receive_new,receive_free,sizeof(t_receive),CLASS_NOINLET,"S"); - class_addcreator2("r",receive_new,"S"); - class_addbang(c, receive_bang); - class_addfloat(c, receive_float); - class_addsymbol(c, receive_symbol); - class_addpointer(c, receive_pointer); - class_addlist(c, receive_list); - class_addanything(c, receive_anything); -} - -/* -------------------------- select ------------------------------ */ - -static t_class *select_class; -struct t_selectelement { - t_atom a; - t_outlet *out; -}; -struct t_select : t_object { - t_int nelement; - t_selectelement *vec; - t_outlet *rejectout; -}; -#define select_each(e,x) for (t_selectelement *e = x->vec;e;e=0) for (int nelement = x->nelement; nelement--; e++) - -static void select_float(t_select *x, t_float f) { - select_each(e,x) if (e->a.a_type==A_FLOAT && e->a.a_float==f) {e->out->send(); return;} - x->rejectout->send(f); -} -static void select_symbol(t_select *x, t_symbol *s) { - select_each(e,x) if (e->a.a_type==A_SYMBOL && e->a.a_symbol==s) {e->out->send(); return;} - x->rejectout->send(s); -} -static void select_free(t_select *x) {free(x->vec);} -static void *select_new(t_symbol *s, int argc, t_atom *argv) { - t_atom a; - if (argc == 0) { - argc = 1; - SETFLOAT(&a, 0); - argv = new t_atom[1]; - } - t_select *x = (t_select *)pd_new(select_class); - x->nelement = argc; - x->vec = (t_selectelement *)getbytes(argc * sizeof(*x->vec)); - t_selectelement *e = x->vec; - for (int n = 0; n < argc; n++, e++) { - e->out = outlet_new(x, &s_bang); - e->a = argv[n]; - if (e->a.a_type == A_FLOAT) - floatinlet_new(x, &x->vec[n].a.a_float); - else symbolinlet_new(x, &x->vec[n].a.a_symbol); - } - x->rejectout = outlet_new(x, &s_float); - return x; -} -void select_setup() { - select_class = class_new2("select",0,select_free,sizeof(t_select),0,""); - class_addfloat(select_class, select_float); - class_addsymbol(select_class, select_symbol); - class_addcreator2("select",select_new,"*"); - class_addcreator2("sel", select_new,"*"); -} - -/* -------------------------- route ------------------------------ */ - -static t_class *route_class; -struct t_routeelement { - t_atom a; - t_outlet *out; -}; -struct t_route : t_object { - t_int n; - t_routeelement *vec; - t_outlet *rejectout; -}; -static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv) { - t_routeelement *e = x->vec; - post("1: sel=%s",sel->name); - for (int n = x->n; n--; e++) if (e->a.a_type == A_SYMBOL) if (e->a.a_symbol == sel) { - if (argc > 0 && argv[0].a_type == A_SYMBOL) e->out->send(argv[0].a_symbol,argc-1,argv+1); - else { /* tb {: avoid 1 element lists */ - if (argc > 1) e->out->send(argc,argv); - else if (argc == 0) e->out->send(); - else e->out->send(&argv[0]); - } /* tb } */ - return; - } - x->rejectout->send(sel,argc,argv); -} - -#define route_eachr(E,L) for (t_routeelement *E = L->vec;E;E=0) for (int ROUTEN = x->n; ROUTEN--; E++) -static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv) { - if (argc && argv->a_type == A_FLOAT) { - float f = atom_getfloat(argv); - route_eachr(e,x) if (e->a.a_type == A_FLOAT && e->a.a_float == f) { - if (argc > 1 && argv[1].a_type == A_SYMBOL) e->out->send(argv[1].a_symbol,argc-2,argv+2); - else { - argc--; argv++; - if (argc>1) e->out->send(argc,argv); else if (argc==0) e->out->send(); else e->out->send(&argv[0]); - } - return; - } else if (e->a.a_type == A_SYMBOL && e->a.a_symbol == &s_float) { - e->out->send(argv[0].a_float); - return; - } - } else { /* symbol arguments */ - if (argc > 1) { /* 2 or more args: treat as "list" */ - route_eachr(e,x) if (e->a.a_type == A_SYMBOL && e->a.a_symbol == &s_list) { - if (argv[0].a_type==A_SYMBOL) e->out->send(argv[0].a_symbol,argc-1,argv+1); - else e->out->send(argc,argv); - return; - } - } else if (argc==0) {route_eachr(e,x) {if (e->a.a_symbol==&s_bang ) {e->out->send( ); return;}} - } else if (argv[0].a_type==A_FLOAT) {route_eachr(e,x) {if (e->a.a_symbol==&s_float ) {e->out->send(&argv[0]); return;}} - } else if (argv[0].a_type==A_SYMBOL) {route_eachr(e,x) {if (e->a.a_symbol==&s_symbol ) {e->out->send(&argv[0]); return;}} - } else if (argv[0].a_type==A_POINTER){route_eachr(e,x) {if (e->a.a_symbol==&s_pointer) {e->out->send(&argv[0]); return;}} - } - } - if (!argc) x->rejectout->send(); else x->rejectout->send(argc,argv); -} - -static void route_free(t_route *x) {free(x->vec);} -static void *route_new(t_symbol *s, int argc, t_atom *argv) { - t_route *x = (t_route *)pd_new(route_class); - if (argc == 0) { - t_atom a; - argc = 1; - SETFLOAT(&a, 0); - argv = &a; - } - x->n = argc; - x->vec = (t_routeelement *)getbytes(argc * sizeof(*x->vec)); - t_routeelement *e = x->vec; - for (int n = 0; n < argc; n++, e++) { - e->out = outlet_new(x, &s_list); - e->a = argv[n]; - } - x->rejectout = outlet_new(x, &s_list); - return x; -} -void route_setup() { - route_class = class_new2("route",route_new,route_free,sizeof(t_route),0,"*"); - class_addlist(route_class, route_list); - class_addanything(route_class, route_anything); -} - -static t_class *pack_class; -struct t_pack : t_object { - t_int n; /* number of args */ - t_atom *vec; /* input values */ - t_atom *outvec; /* space for output values */ -}; -static void *pack_new(t_symbol *s, int argc, t_atom *argv) { - t_pack *x = (t_pack *)pd_new(pack_class); - t_atom defarg[2], *ap, *vec, *vp; - if (!argc) { - argv = defarg; - argc = 2; - SETFLOAT(&defarg[0], 0); - SETFLOAT(&defarg[1], 0); - } - x->n = argc; - vec = x->vec = (t_atom *)getbytes(argc * sizeof(*x->vec)); - x->outvec = (t_atom *)getbytes(argc * sizeof(*x->outvec)); - vp = x->vec; - ap = argv; - for (int i = 0; i < argc; i++, ap++, vp++) { - if (ap->a_type == A_FLOAT) { - *vp = *ap; - if (i) floatinlet_new(x, &vp->a_float); - } else if (ap->a_type == A_SYMBOL) { - char c = *ap->a_symbol->name; - if (c == 's') { SETSYMBOL(vp, &s_symbol); if (i) symbolinlet_new(x, &vp->a_symbol);} - else if (c == 'p') { /* SETPOINTER(vp, gpointer_new()) if (i) pointerinlet_new(x, gp); */} - else if (c == 'f') { SETFLOAT(vp, 0); if (i) floatinlet_new(x, &vp->a_float);} - else error("pack: %s: bad type '%c'", ap->a_symbol->name, c); - } - } - outlet_new(x, &s_list); - return x; -} -static void pack_bang(t_pack *x) { - int reentered = 0, size = x->n * sizeof (t_atom); - t_atom *outvec; - /* reentrancy protection. The first time through use the pre-allocated outvec; if we're reentered we have to allocate new memory. */ - if (!x->outvec) { - outvec = (t_atom *)t_getbytes(size); - reentered = 1; - } else { - outvec = x->outvec; - x->outvec = 0; - } - memcpy(outvec, x->vec, size); - x->outlet->send(x->n,outvec); - if (reentered) free(outvec); else x->outvec = outvec; -} - -static void pack_pointer(t_pack *x, t_gpointer *gp) { - if (x->vec->a_type == A_POINTER) { - //gpointer_unset(x->gpointer); - //*x->gpointer = *gp; - //if (gp->o) gp->o->refcount++; - pack_bang(x); - } else error("pack_pointer: wrong type"); -} -static void pack_float(t_pack *x, t_float f) { - if (x->vec->a_type == A_FLOAT ) {x->vec->a_float = f; pack_bang(x);} else error("pack_float: wrong type"); -} -static void pack_symbol(t_pack *x, t_symbol *s) { - if (x->vec->a_type == A_SYMBOL) {x->vec->a_symbol = s; pack_bang(x);} else error("pack_symbol: wrong type"); -} -static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av) {obj_list(x, 0, ac, av);} -static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av) { - t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom)); - for (int i = 0; i < ac; i++) av2[i + 1] = av[i]; - SETSYMBOL(av2, s); - obj_list(x, 0, ac+1, av2); - free(av2); -} -static void pack_free(t_pack *x) { - free(x->vec); - free(x->outvec); -} -static void pack_setup() { - t_class *c = pack_class = class_new2("pack",pack_new,pack_free,sizeof(t_pack),0,"*"); - class_addbang(c, pack_bang); - class_addpointer(c, pack_pointer); - class_addfloat(c, pack_float); - class_addsymbol(c, pack_symbol); - class_addlist(c, pack_list); - class_addanything(c, pack_anything); -} - -static t_class *unpack_class; -struct t_unpack : t_object { - t_int n; - t_outlet **vec; - char *vat; -}; - -static t_atomtype atomtype_from_letter(char c) { - switch (c) { - case 'e': return A_ATOM; - case 'f': return A_FLOAT; - case 's': return A_SYMBOL; - case 'p': return A_POINTER; - default: return A_CANT; - } -} - -static void *unpack_new(t_symbol *s, int argc, t_atom *argv) { - t_unpack *x = (t_unpack *)pd_new(unpack_class); - t_atom defarg[2]; - if (!argc) { - argv = defarg; - argc = 2; - SETFLOAT(&defarg[0], 0); - SETFLOAT(&defarg[1], 0); - } - x->n = argc; - x->vec = (t_outlet **)getbytes(argc * sizeof(*x->vec)); - x->vat = (char *)getbytes(argc); - t_atom *ap=argv; - for (int i=0; i<argc; ap++, i++) { - x->vec[i] = outlet_new(x,0); - switch (argv[i].a_type) { - case A_FLOAT: x->vat[i]=A_FLOAT; break; - case A_SYMBOL: { - const char *s = atom_getstring(&argv[i]); - if (strlen(s)<1 || (x->vat[i]=atomtype_from_letter(s[0]))==A_CANT) {error("%s: bad type", s); x->vat[i]=A_FLOAT;} - break; - } - default: error("bad type"); - } - } - return x; -} -static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv) { - if (argc > x->n) argc = x->n; - //for (int i=argc-1; i>=0; i--) x->vec[i]->send(&argv[i]); - for (int i=argc-1; i>=0; i--) { - if (x->vat[i]==A_ATOM || x->vat[i]==argv[i].a_type) x->vec[i]->send(&argv[i]); - else error("type mismatch"); - } -} -static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av) { - t_atom *av2 = (t_atom *)getbytes((ac+1) * sizeof(t_atom)); - for (int i=0; i<ac; i++) av2[i+1] = av[i]; - SETSYMBOL(av2, s); - unpack_list(x, 0, ac+1, av2); - free(av2); -} -static void unpack_free(t_unpack *x) {free(x->vec); free(x->vat);} -static void unpack_setup() { - unpack_class = class_new2("unpack",unpack_new,unpack_free,sizeof(t_unpack),0,"*"); - class_addlist(unpack_class, unpack_list); - class_addanything(unpack_class, unpack_anything); -} - -static t_class *trigger_class; -struct t_triggerout { - int type; - t_outlet *outlet; -}; -struct t_trigger : t_object { - t_int n; - t_triggerout *vec; -}; -static void *trigger_new(t_symbol *s, int argc, t_atom *argv) { - t_trigger *x = (t_trigger *)pd_new(trigger_class); - t_atom defarg[2]; - if (!argc) { - argv = defarg; - argc = 2; - SETSYMBOL(&defarg[0], &s_bang); - SETSYMBOL(&defarg[1], &s_bang); - } - x->n = argc; - x->vec = (t_triggerout *)getbytes(argc * sizeof(*x->vec)); - t_triggerout *u = x->vec; - t_atom *ap = argv; - for (int i=0; i<argc; u++, ap++, i++) { - t_atomtype thistype = ap->a_type; - char c; - if (thistype == A_SYMBOL) c = ap->a_symbol->name[0]; - else if (thistype == A_FLOAT) c = 'f'; - else c = 0; - if (c == 'p') u->outlet = outlet_new(x, &s_pointer); - else if (c == 'f') u->outlet = outlet_new(x, &s_float); - else if (c == 'b') u->outlet = outlet_new(x, &s_bang); - else if (c == 'l') u->outlet = outlet_new(x, &s_list); - else if (c == 's') u->outlet = outlet_new(x, &s_symbol); - else if (c == 'a') u->outlet = outlet_new(x, &s_symbol); - else { - error("trigger: %s: bad type", ap->a_symbol->name); - c='f'; u->outlet = outlet_new(x, &s_float); - } - u->type = c; - } - return x; -} -static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv) { - t_triggerout *u = x->vec+x->n; - for (int i = x->n; u--, i--;) { - if (u->type == 'f') u->outlet->send(argc ? atom_getfloat(argv) : 0); - else if (u->type == 'b') u->outlet->send(); - else if (u->type == 's') u->outlet->send(argc ? atom_getsymbol(argv) : &s_symbol); - else if (u->type == 'p') { - if (!argc || argv->a_type != 'p') error("unpack: bad pointer"); else u->outlet->send(argv->a_pointer); - } else u->outlet->send(argc,argv); - } -} -static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv) { - t_triggerout *u = x->vec+x->n; - for (int i = x->n; u--, i--;) { - if (u->type == 'b') u->outlet->send(); - else if (u->type == 'a') u->outlet->send(s,argc,argv); - else error("trigger: can only convert 's' to 'b' or 'a'; got %s", s->name); - } -} -static void trigger_bang(t_trigger *x) {trigger_list(x,0,0,0 );} -static void trigger_pointer(t_trigger *x, t_gpointer *gp) {t_atom at; SETPOINTER(&at, gp); trigger_list(x,0,1,&at);} -static void trigger_float(t_trigger *x, t_float f) { t_atom at; SETFLOAT(&at, f); trigger_list(x,0,1,&at);} -static void trigger_symbol(t_trigger *x, t_symbol *s) { t_atom at; SETSYMBOL(&at, s); trigger_list(x,0,1,&at);} -static void trigger_free(t_trigger *x) {free(x->vec);} -static void trigger_setup() { - t_class *c = trigger_class = class_new2("trigger",trigger_new,trigger_free,sizeof(t_trigger),0,"*"); - class_addcreator2("t",trigger_new,"*"); - class_addlist(c, trigger_list); - class_addbang(c, trigger_bang); - class_addpointer(c, trigger_pointer); - class_addfloat(c, trigger_float); - class_addsymbol(c, trigger_symbol); - class_addanything(c, trigger_anything); -} - -static t_class *spigot_class; -struct t_spigot : t_object {float state;}; -static void *spigot_new(t_floatarg f) { - t_spigot *x = (t_spigot *)pd_new(spigot_class); - floatinlet_new(x, &x->state); - outlet_new(x, 0); - x->state = f; - return x; -} -static void spigot_bang( t_spigot *x) { if (x->state) x->outlet->send();} -static void spigot_pointer( t_spigot *x, t_gpointer *v) { if (x->state) x->outlet->send(v);} -static void spigot_float( t_spigot *x, t_float v) { if (x->state) x->outlet->send(v);} -static void spigot_symbol( t_spigot *x, t_symbol *v) { if (x->state) x->outlet->send(v);} -static void spigot_list( t_spigot *x, t_symbol *s, int argc, t_atom *argv) {if (x->state) x->outlet->send( argc,argv);} -static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv) {if (x->state) x->outlet->send(s,argc,argv);} -static void spigot_setup() { - t_class *c = spigot_class = class_new2("spigot",spigot_new,0,sizeof(t_spigot),0,"F"); - class_addbang(c, spigot_bang); - class_addpointer(c, spigot_pointer); - class_addfloat(c, spigot_float); - class_addsymbol(c, spigot_symbol); - class_addlist(c, spigot_list); - class_addanything(c, spigot_anything); -} - -static t_class *moses_class; -struct t_moses : t_object {float y;}; -static void *moses_new(t_floatarg f) { - t_moses *x = (t_moses *)pd_new(moses_class); - floatinlet_new(x, &x->y); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - x->y = f; - return x; -} -static void moses_float(t_moses *x, t_float v) {x->out(v>=x->y)->send(v);} -static void moses_setup() { - moses_class = class_new2("moses",moses_new,0,sizeof(t_moses),0,"F"); - class_addfloat(moses_class, moses_float); -} -static t_class *until_class; -struct t_until : t_object { - int run; - int count; -}; -static void *until_new() { - t_until *x = (t_until *)pd_new(until_class); - inlet_new(x, x, gensym("bang"), gensym("bang2")); - outlet_new(x, &s_bang); - x->run = 0; - return x; -} -static void until_bang(t_until *x) { x->run=1; x->count=-1; while (x->run && x->count) {x->count--; x->outlet->send();}} -static void until_float(t_until *x, t_float f) {x->run=1; x->count=(int)f; while (x->run && x->count) {x->count--; x->outlet->send();}} -static void until_bang2(t_until *x) {x->run = 0;} -static void until_setup() { - until_class = class_new2("until",until_new,0,sizeof(t_until),0,""); - class_addbang(until_class, until_bang); - class_addfloat(until_class, until_float); - class_addmethod2(until_class, until_bang2,"bang2",""); -} - -static t_class *makefilename_class; -struct t_makefilename : t_object {t_symbol *format;}; -static void *makefilename_new(t_symbol *s) { - t_makefilename *x = (t_makefilename *)pd_new(makefilename_class); - if (!s->name) s = gensym("file.%d"); - outlet_new(x, &s_symbol); - x->format = s; - return x; -} - -/* doesn't do any typechecking or even counting the % signs properly */ -static void makefilename_float(t_makefilename *x, t_floatarg f) {x->outlet->send(symprintf(x->format->name,(int)f));} -static void makefilename_symbol(t_makefilename *x, t_symbol *s) {x->outlet->send(symprintf(x->format->name,s->name));} -static void makefilename_set(t_makefilename *x, t_symbol *s) {x->format = s;} - -static void makefilename_setup() { - t_class *c = makefilename_class = class_new2("makefilename",makefilename_new,0,sizeof(t_makefilename),0,"S"); - class_addfloat(c, makefilename_float); - class_addsymbol(c, makefilename_symbol); - class_addmethod2(c, makefilename_set, "set","s"); -} - -static t_class *swap_class; -struct t_swap : t_object { - t_float f1; - t_float f2; -}; -static void *swap_new(t_floatarg f) { - t_swap *x = (t_swap *)pd_new(swap_class); - x->f2 = f; - x->f1 = 0; - outlet_new(x, &s_float); - outlet_new(x, &s_float); - floatinlet_new(x, &x->f2); - return x; -} -static void swap_bang(t_swap *x) { - x->out(1)->send(x->f1); - x->out(0)->send(x->f2); -} -static void swap_float(t_swap *x, t_float f) { - x->f1 = f; - swap_bang(x); -} -void swap_setup() { - swap_class = class_new2("swap",swap_new,0,sizeof(t_swap),0,"F"); - class_addcreator2("fswap",swap_new,"F"); - class_addbang(swap_class, swap_bang); - class_addfloat(swap_class, swap_float); -} - -static t_class *change_class; -struct t_change : t_object {t_float f;}; -static void *change_new(t_floatarg f) { - t_change *x = (t_change *)pd_new(change_class); - x->f = f; - outlet_new(x, &s_float); - return x; -} -static void change_bang(t_change *x) {x->outlet->send(x->f);} -static void change_float(t_change *x, t_float f) { - if (f != x->f) { - x->f = f; - x->outlet->send(x->f); - } -} -static void change_set(t_change *x, t_float f) {x->f = f;} -void change_setup() { - change_class = class_new2("change",change_new,0,sizeof(t_change),0,"F"); - class_addbang(change_class, change_bang); - class_addfloat(change_class, change_float); - class_addmethod2(change_class, change_set, "set","F"); -} - -static t_class *value_class, *vcommon_class; -struct t_vcommon : t_pd { - int c_refcount; - t_float f; -}; -struct t_value : t_object { - t_symbol *sym; - t_float *floatstar; -}; - -/* get a pointer to a named floating-point variable. The variable - belongs to a "vcommon" object, which is created if necessary. */ -t_float *value_get(t_symbol *s) { - t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class); - if (!c) { - c = (t_vcommon *)pd_new(vcommon_class); - c->f = 0; - c->c_refcount = 0; - pd_bind(c,s); - } - c->c_refcount++; - return &c->f; -} -/* release a variable. This only frees the "vcommon" resource when the last interested party releases it. */ -void value_release(t_symbol *s) { - t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class); - if (c) { - if (!--c->c_refcount) { - pd_unbind(c,s); - pd_free(c); - } - } else bug("value_release"); -} -int value_getfloat(t_symbol *s, t_float *f) {t_vcommon *c=(t_vcommon *)pd_findbyclass(s,vcommon_class); if (!c) return 1; *f=c->f;return 0;} -int value_setfloat(t_symbol *s, t_float f) {t_vcommon *c=(t_vcommon *)pd_findbyclass(s,vcommon_class); if (!c) return 1; c->f=f; return 0;} -static void *value_new(t_symbol *s) { - t_value *x = (t_value *)pd_new(value_class); - x->sym = s; - x->floatstar = value_get(s); - outlet_new(x, &s_float); - return x; -} -static void value_bang(t_value *x) {x->outlet->send(*x->floatstar);} -static void value_float(t_value *x, t_float f) {*x->floatstar = f;} -static void value_ff(t_value *x) {value_release(x->sym);} -static void value_setup() { - value_class = class_new2("value",value_new,value_ff,sizeof(t_value),0,"S"); - class_addcreator2("v",value_new,"S"); - class_addbang(value_class, value_bang); - class_addfloat(value_class, value_float); - vcommon_class = class_new2("value",0,0,sizeof(t_vcommon),CLASS_PD,""); -} - -/* MIDI. */ - -void outmidi_noteon(int portno, int channel, int pitch, int velo); -void outmidi_controlchange(int portno, int channel, int ctlno, int value); -void outmidi_programchange(int portno, int channel, int value); -void outmidi_pitchbend(int portno, int channel, int value); -void outmidi_aftertouch(int portno, int channel, int value); -void outmidi_polyaftertouch(int portno, int channel, int pitch, int value); -void outmidi_mclk(int portno); - -static t_symbol *midiin_sym, *sysexin_sym, *notein_sym, *ctlin_sym; -static t_class *midiin_class, *sysexin_class, *notein_class, *ctlin_class; -struct t_midiin : t_object {}; -struct t_notein : t_object {t_float ch;}; -struct t_ctlin : t_object {t_float ch; t_float ctlno;}; - -static void midiin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av) { - x->out(1)->send(atom_getfloatarg(1,ac,av) + 1); - x->out(0)->send(atom_getfloatarg(0,ac,av)); -} -void inmidi_byte(int portno, int byte) { - if ( midiin_sym->thing) {t_atom at[2]; SETFLOAT(at, byte); SETFLOAT(at+1, portno+1); pd_list( midiin_sym->thing, 0, 2, at);} -} -void inmidi_sysex(int portno, int byte) { - if (sysexin_sym->thing) {t_atom at[2]; SETFLOAT(at, byte); SETFLOAT(at+1, portno+1); pd_list(sysexin_sym->thing, 0, 2, at);} -} - -static void notein_list(t_notein *x, t_symbol *s, int argc, t_atom *argv) { - float pitch = atom_getfloatarg(0, argc, argv); - float velo = atom_getfloatarg(1, argc, argv); - float channel = atom_getfloatarg(2, argc, argv); - if (x->ch) {if (channel != x->ch) return;} else x->out(2)->send(channel); - x->out(1)->send(velo); - x->out(0)->send(pitch); -} - -void inmidi_noteon(int portno, int channel, int pitch, int velo) { - if (notein_sym->thing) { - t_atom at[3]; - SETFLOAT(at, pitch); - SETFLOAT(at+1, velo); - SETFLOAT(at+2, (channel + (portno << 4) + 1)); - pd_list(notein_sym->thing, &s_list, 3, at); - } -} - -static void *midiin_new() { - t_midiin *x = (t_midiin *)pd_new(midiin_class); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - pd_bind(x, midiin_sym); - return x; -} -static void *sysexin_new() { - t_midiin *x = (t_midiin *)pd_new(sysexin_class); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - pd_bind(x, sysexin_sym); - return x; -} -static void *notein_new(t_floatarg f) { - t_notein *x = (t_notein *)pd_new(notein_class); - x->ch = f; - outlet_new(x, &s_float); - outlet_new(x, &s_float); - if (f == 0) outlet_new(x, &s_float); - pd_bind(x, notein_sym); - return x; -} -static void *ctlin_new(t_symbol *s, int argc, t_atom *argv) { - t_ctlin *x = (t_ctlin *)pd_new(ctlin_class); - int ctlno = (int)(argc ? atom_getfloatarg(0, argc, argv) : -1); - int channel = (int)atom_getfloatarg(1, argc, argv); - x->ch = channel; - x->ctlno = ctlno; - outlet_new(x, &s_float); - if (!channel) { - if (x->ctlno < 0) outlet_new(x, &s_float); - outlet_new(x, &s_float); - } - pd_bind(x, ctlin_sym); - return x; -} -static void ctlin_list(t_ctlin *x, t_symbol *s, int argc, t_atom *argv) { - t_float ctlnumber = atom_getfloatarg(0, argc, argv); - t_float value = atom_getfloatarg(1, argc, argv); - t_float channel = atom_getfloatarg(2, argc, argv); - if (x->ctlno >= 0 && x->ctlno != ctlnumber) return; - if (x->ch > 0 && x->ch != channel) return; - if (x->ch == 0) x->out(2)->send(channel); - if (x->ctlno < 0) x->out(1)->send(ctlnumber); - x->out(0)->send(value); -} - -static void midiin_free(t_midiin *x) {pd_unbind(x, midiin_sym);} -static void sysexin_free(t_midiin *x) {pd_unbind(x, sysexin_sym);} -static void notein_free(t_notein *x) {pd_unbind(x, notein_sym);} -static void ctlin_free(t_ctlin *x) {pd_unbind(x, ctlin_sym);} - -void inmidi_controlchange(int portno, int channel, int ctlnumber, int value) { - if (ctlin_sym->thing) { - t_atom at[3]; - SETFLOAT(at, ctlnumber); - SETFLOAT(at+1, value); - SETFLOAT(at+2, (channel + (portno << 4) + 1)); - pd_list(ctlin_sym->thing, &s_list, 3, at); - } -} - -struct t_midi2 : t_object {t_float ch;}; -static void *midi2_new(t_class *cl, t_floatarg ch) { - t_midi2 *x = (t_midi2 *)pd_new(cl); - x->ch = ch; - outlet_new(x, &s_float); - if (!ch) outlet_new(x, &s_float); - return x; -} -static void midi2_list(t_midi2 *x, t_symbol *s, int argc, t_atom *argv) { - float value = atom_getfloatarg(0, argc, argv); - float channel = atom_getfloatarg(1, argc, argv); - if (x->ch) {if (channel != x->ch) return;} else x->out(1)->send(channel); - x->out(0)->send(value); -} -static t_symbol *pgmin_sym, *bendin_sym, *touchin_sym; -static t_class *pgmin_class, *bendin_class, *touchin_class; -struct t_pgmin : t_midi2 {}; -struct t_bendin : t_midi2 {}; -struct t_touchin : t_midi2 {}; -static void *pgmin_new(t_floatarg f) { t_pgmin *x = (t_pgmin *) midi2_new(pgmin_class ,f);pd_bind(x, pgmin_sym);return x;} -static void *bendin_new(t_floatarg f) { t_bendin *x = (t_bendin *) midi2_new(bendin_class ,f);pd_bind(x, bendin_sym);return x;} -static void *touchin_new(t_floatarg f) {t_touchin *x = (t_touchin *)midi2_new(touchin_class,f);pd_bind(x,touchin_sym);return x;} -static void pgmin_free( t_pgmin *x) {pd_unbind(x, pgmin_sym);} -static void bendin_free( t_bendin *x) {pd_unbind(x, bendin_sym);} -static void touchin_free(t_touchin *x) {pd_unbind(x, touchin_sym);} -void inmidi_programchange(int portno, int channel, int value) { - if (pgmin_sym->thing) { - t_atom at[2]; SETFLOAT(at,value+1); SETFLOAT(at+1, channel+(portno<<4)+1); pd_list( pgmin_sym->thing, &s_list, 2, at); - } -} -void inmidi_pitchbend(int portno, int channel, int value) { - if (bendin_sym->thing) { - t_atom at[2]; SETFLOAT(at,value); SETFLOAT(at+1, channel+(portno<<4)+1); pd_list( bendin_sym->thing, &s_list, 2, at); - } -} -void inmidi_aftertouch(int portno, int channel, int value) { - if (touchin_sym->thing) { - t_atom at[2]; SETFLOAT(at,value); SETFLOAT(at+1, channel+(portno<<4)+1); pd_list(touchin_sym->thing, &s_list, 2, at); - } -} - -/* ----------------------- polytouchin ------------------------- */ -static t_symbol *polytouchin_sym; -static t_class *polytouchin_class; -struct t_polytouchin : t_object { - t_float ch; -}; -static void *polytouchin_new(t_floatarg f) { - t_polytouchin *x = (t_polytouchin *)pd_new(polytouchin_class); - x->ch = f; - outlet_new(x, &s_float); - outlet_new(x, &s_float); - if (f == 0) outlet_new(x, &s_float); - pd_bind(x, polytouchin_sym); - return x; -} -static void polytouchin_list(t_polytouchin *x, t_symbol *s, int argc, t_atom *argv) { - t_float channel = atom_getfloatarg(2, argc, argv); - if (x->ch) {if (channel != x->ch) return;} else x->out(2)->send(channel); - x->out(1)->send(atom_getfloatarg(0, argc, argv)); /*pitch*/ - x->out(0)->send(atom_getfloatarg(1, argc, argv)); /*value*/ -} -static void polytouchin_free(t_polytouchin *x) {pd_unbind(x, polytouchin_sym);} -static void polytouchin_setup() { - polytouchin_class = class_new2("polytouchin",polytouchin_new,polytouchin_free, - sizeof(t_polytouchin), CLASS_NOINLET,"F"); - class_addlist(polytouchin_class, polytouchin_list); - class_sethelpsymbol(polytouchin_class, gensym("midi")); - polytouchin_sym = gensym("#polytouchin"); -} -void inmidi_polyaftertouch(int portno, int channel, int pitch, int value) { - if (polytouchin_sym->thing) { - t_atom at[3]; - SETFLOAT(at, pitch); - SETFLOAT(at+1, value); - SETFLOAT(at+2, (channel + (portno << 4) + 1)); - pd_list(polytouchin_sym->thing, &s_list, 3, at); - } -} - -/*----------------------- midiclkin--(midi F8 message )---------------------*/ -static t_symbol *midiclkin_sym; -static t_class *midiclkin_class; -struct t_midiclkin : t_object {}; -static void *midiclkin_new(t_floatarg f) { - t_midiclkin *x = (t_midiclkin *)pd_new(midiclkin_class); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - pd_bind(x, midiclkin_sym); - return x; -} -static void midiclkin_list(t_midiclkin *x, t_symbol *s, int argc, t_atom *argv) { - x->out(1)->send(atom_getfloatarg(1, argc, argv)); /*count*/ - x->out(0)->send(atom_getfloatarg(0, argc, argv)); /*value*/ -} -static void midiclkin_free(t_midiclkin *x) {pd_unbind(x, midiclkin_sym);} -static void midiclkin_setup() { - midiclkin_class = class_new2("midiclkin",midiclkin_new,midiclkin_free,sizeof(t_midiclkin),CLASS_NOINLET,"F"); - class_addlist(midiclkin_class, midiclkin_list); - class_sethelpsymbol(midiclkin_class, gensym("midi")); - midiclkin_sym = gensym("#midiclkin"); -} -void inmidi_clk(double timing) { - static float prev = 0; - static float count = 0; - if (midiclkin_sym->thing) { - t_atom at[2]; - float diff = timing - prev; - count++; - /* 24 count per quarter note */ - if (count == 3) {SETFLOAT(at, 1); count = 0;} else SETFLOAT(at, 0); - SETFLOAT(at+1, diff); - pd_list(midiclkin_sym->thing, &s_list, 2, at); - prev = timing; - } -} - -/*----------midirealtimein (midi FA,FB,FC,FF message)-----------------*/ -static t_symbol *midirealtimein_sym; -static t_class *midirealtimein_class; -struct t_midirealtimein : t_object {}; -static void *midirealtimein_new() { - t_midirealtimein *x = (t_midirealtimein *)pd_new(midirealtimein_class); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - pd_bind(x, midirealtimein_sym); - return x; -} -static void midirealtimein_list(t_midirealtimein *x, t_symbol *s, int argc, t_atom *argv) { - x->out(1)->send(atom_getfloatarg(0, argc, argv)); /*portno*/ - x->out(0)->send(atom_getfloatarg(1, argc, argv)); /*byte*/ -} -static void midirealtimein_free(t_midirealtimein *x) {pd_unbind(x, midirealtimein_sym);} -static void midirealtimein_setup() { - midirealtimein_class = class_new2("midirealtimein",midirealtimein_new,midirealtimein_free, - sizeof(t_midirealtimein),CLASS_NOINLET,"F"); - class_addlist(midirealtimein_class, midirealtimein_list); - class_sethelpsymbol(midirealtimein_class, gensym("midi")); - midirealtimein_sym = gensym("#midirealtimein"); -} -void inmidi_realtimein(int portno, int SysMsg) { - if (midirealtimein_sym->thing) { - t_atom at[2]; - SETFLOAT(at, portno); - SETFLOAT(at+1, SysMsg); - pd_list(midirealtimein_sym->thing, &s_list, 2, at); - } -} - -void outmidi_byte(int portno, int byte); -static t_class *midiout_class; struct t_midiout : t_object {t_float portno;}; -static t_class *noteout_class; struct t_noteout : t_object {t_float v; t_float ch;}; -static t_class *ctlout_class; struct t_ctlout : t_object {t_float v; t_float ch;}; - -static void *noteout_new(t_floatarg channel) { - t_noteout *x = (t_noteout *)pd_new(noteout_class); - x->v = 0; - x->ch = channel<1?channel:1; - floatinlet_new(x, &x->v); - floatinlet_new(x, &x->ch); - return x; -} -static void *ctlout_new(t_floatarg v, t_floatarg channel) { - t_ctlout *x = (t_ctlout *)pd_new(ctlout_class); - x->v = v; - x->ch = channel<1?channel:1; - floatinlet_new(x, &x->v); - floatinlet_new(x, &x->ch); - return x; -} -static void *midiout_new(t_floatarg portno) { - t_midiout *x = (t_midiout *)pd_new(midiout_class); - if (portno <= 0) portno = 1; - x->portno = portno; - floatinlet_new(x, &x->portno); -#ifdef __irix__ - post("midiout: unimplemented in IRIX"); -#endif - return x; -} - -static void midiout_float(t_midiout *x, t_floatarg f){ - outmidi_byte((int)x->portno-1, (int)f); -} -static void noteout_float(t_noteout *x, t_float f) { - int binchan = max(0,(int)x->ch-1); - outmidi_noteon((binchan >> 4), (binchan & 15), (int)f, (int)x->v); -} -static void ctlout_float(t_ctlout *x, t_float f) { - int binchan = (int)x->ch - 1; - if (binchan < 0) binchan = 0; - outmidi_controlchange((binchan >> 4), (binchan & 15), (int)x->v, (int)f); -} - -static t_class *pgmout_class, *bendout_class, *touchout_class; -struct t_mido2 : t_object {t_float ch;}; -struct t_pgmout : t_mido2 {}; -struct t_bendout : t_mido2 {}; -struct t_touchout : t_mido2 {}; -static void *mido2_new(t_class *cl, t_floatarg channel) { - t_pgmout *x = (t_pgmout *)pd_new(cl); - x->ch = channel<1?channel:1; floatinlet_new(x, &x->ch); return x; -} -static void *pgmout_new( t_floatarg ch) {return mido2_new(pgmout_class,ch);} -static void *bendout_new( t_floatarg ch) {return mido2_new(bendout_class,ch);} -static void *touchout_new(t_floatarg ch) {return mido2_new(touchout_class,ch);} -static void pgmout_float(t_pgmout *x, t_floatarg f) { - int binchan = max(0,(int)x->ch-1); - outmidi_programchange(binchan>>4, binchan&15, min(127,max(0,(int)f-1))); -} -static void bendout_float(t_bendout *x, t_float f) { - int binchan = max(0,(int)x->ch-1); - outmidi_pitchbend(binchan>>4, binchan&15, (int)f+8192); -} -static void touchout_float(t_touchout *x, t_float f) { - int binchan = max(0,(int)x->ch-1); - outmidi_aftertouch(binchan>>4, binchan&15, (int)f); -} - -static t_class *polytouchout_class; -struct t_polytouchout : t_object { - t_float ch; - t_float pitch; -}; -static void *polytouchout_new(t_floatarg channel) { - t_polytouchout *x = (t_polytouchout *)pd_new(polytouchout_class); - x->ch = channel<1?channel:1; - x->pitch = 0; - floatinlet_new(x, &x->pitch); - floatinlet_new(x, &x->ch); - return x; -} -static void polytouchout_float(t_polytouchout *x, t_float n) { - int binchan = max(0,(int)x->ch-1); - outmidi_polyaftertouch((binchan >> 4), (binchan & 15), (int)x->pitch, (int)n); -} -static void polytouchout_setup() { - polytouchout_class = class_new2("polytouchout",polytouchout_new,0,sizeof(t_polytouchout),0,"F"); - class_addfloat(polytouchout_class, polytouchout_float); - class_sethelpsymbol(polytouchout_class, gensym("midi")); -} - -static t_class *makenote_class; -struct t_hang { - t_clock *clock; - t_hang *next; - t_float pitch; - struct t_makenote *owner; -}; -struct t_makenote : t_object { - t_float velo; - t_float dur; - t_hang *hang; -}; -static void *makenote_new(t_floatarg velo, t_floatarg dur) { - t_makenote *x = (t_makenote *)pd_new(makenote_class); - x->velo = velo; - x->dur = dur; - floatinlet_new(x, &x->velo); - floatinlet_new(x, &x->dur); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - x->hang = 0; - return x; -} -static void makenote_tick(t_hang *hang) { - t_makenote *x = hang->owner; - t_hang *h2, *h3; - x->out(1)->send(0.); - x->out(0)->send(hang->pitch); - if (x->hang == hang) x->hang = hang->next; - else for (h2 = x->hang; (h3 = h2->next); h2 = h3) { - if (h3 == hang) { - h2->next = h3->next; - break; - } - } - clock_free(hang->clock); - free(hang); -} -static void makenote_float(t_makenote *x, t_float f) { - if (!x->velo) return; - x->out(1)->send(x->velo); - x->out(0)->send(f); - t_hang *hang = (t_hang *)getbytes(sizeof *hang); - hang->next = x->hang; - x->hang = hang; - hang->pitch = f; - hang->owner = x; - hang->clock = clock_new(hang, (t_method)makenote_tick); - clock_delay(hang->clock, (x->dur >= 0 ? x->dur : 0)); -} -static void makenote_stop(t_makenote *x) { - t_hang *hang; - while ((hang = x->hang)) { - x->out(1)->send(0.); - x->out(0)->send(hang->pitch); - x->hang = hang->next; - clock_free(hang->clock); - free(hang); - } -} -static void makenote_clear(t_makenote *x) { - t_hang *hang; - while ((hang = x->hang)) { - x->hang = hang->next; - clock_free(hang->clock); - free(hang); - } -} -static void makenote_setup() { - makenote_class = class_new2("makenote",makenote_new,makenote_clear,sizeof(t_makenote),0,"FF"); - class_addfloat(makenote_class, makenote_float); - class_addmethod2(makenote_class, makenote_stop, "stop",""); - class_addmethod2(makenote_class, makenote_clear,"clear",""); -} - -static t_class *stripnote_class; -struct t_stripnote : t_object { - t_float velo; -}; -static void *stripnote_new() { - t_stripnote *x = (t_stripnote *)pd_new(stripnote_class); - floatinlet_new(x, &x->velo); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - return x; -} -static void stripnote_float(t_stripnote *x, t_float f) { - if (!x->velo) return; - x->out(1)->send(x->velo); - x->out(0)->send(f); -} -static void stripnote_setup() { - stripnote_class = class_new2("stripnote",stripnote_new,0,sizeof(t_stripnote),0,""); - class_addfloat(stripnote_class, stripnote_float); -} - -static t_class *poly_class; -struct t_voice { - float pitch; - int used; - unsigned long serial; -}; -struct t_poly : t_object { - int n; - t_voice *vec; - float vel; - unsigned long serial; - int steal; -}; -static void *poly_new(float fnvoice, float fsteal) { - int i, n = (int)fnvoice; - t_poly *x = (t_poly *)pd_new(poly_class); - t_voice *v; - if (n < 1) n = 1; - x->n = n; - x->vec = (t_voice *)getbytes(n * sizeof(*x->vec)); - for (v = x->vec, i = n; i--; v++) v->pitch = v->used = v->serial = 0; - x->vel = 0; - x->steal = (fsteal != 0); - floatinlet_new(x, &x->vel); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - x->serial = 0; - return x; -} -static void poly_float(t_poly *x, t_float f) { - int i; - t_voice *v; - t_voice *firston, *firstoff; - unsigned int serialon, serialoff, onindex = 0, offindex = 0; - if (x->vel > 0) { - /* note on. Look for a vacant voice */ - for (v=x->vec, i=0, firston=firstoff=0, serialon=serialoff=0xffffffff; i<x->n; v++, i++) { - if (v->used && v->serial < serialon) - firston = v, serialon = v->serial, onindex = i; - else if (!v->used && v->serial < serialoff) - firstoff = v, serialoff = v->serial, offindex = i; - } - if (firstoff) { - x->out(2)->send(x->vel); - x->out(1)->send(firstoff->pitch = f); - x->out(0)->send(offindex+1); - firstoff->used = 1; - firstoff->serial = x->serial++; - } - /* if none, steal one */ - else if (firston && x->steal) { - x->out(2)->send(0.); x->out(1)->send(firston->pitch ); x->out(0)->send(onindex+1); - x->out(2)->send(x->vel); x->out(1)->send(firston->pitch = f); x->out(0)->send(onindex+1); - firston->serial = x->serial++; - } - } else { /* note off. Turn off oldest match */ - for (v = x->vec, i = 0, firston = 0, serialon = 0xffffffff; i < x->n; v++, i++) - if (v->used && v->pitch == f && v->serial < serialon) - firston = v, serialon = v->serial, onindex = i; - if (firston) { - firston->used = 0; - firston->serial = x->serial++; - x->out(2)->send(0.); - x->out(1)->send(firston->pitch); - x->out(0)->send(onindex+1); - } - } -} -static void poly_stop(t_poly *x) { - t_voice *v = x->vec; - for (int i = 0; i < x->n; i++, v++) if (v->used) { - x->out(2)->send(0.); - x->out(1)->send(v->pitch); - x->out(0)->send(i+1); - v->used = 0; - v->serial = x->serial++; - } -} -static void poly_clear(t_poly *x) { - t_voice *v = x->vec; - for (int i = x->n; i--; v++) v->used = v->serial = 0; -} -static void poly_free(t_poly *x) {free(x->vec);} -static void poly_setup() { - poly_class = class_new2("poly",poly_new,poly_free,sizeof(t_poly),0,"FF"); - class_addfloat(poly_class, poly_float); - class_addmethod2(poly_class, poly_stop, "stop",""); - class_addmethod2(poly_class, poly_clear, "clear",""); -} - -static t_class *bag_class; -struct t_bagelem { - struct t_bagelem *next; - t_float value; -}; -struct t_bag : t_object { - t_float velo; - t_bagelem *first; -}; -static void *bag_new() { - t_bag *x = (t_bag *)pd_new(bag_class); - x->velo = 0; - floatinlet_new(x, &x->velo); - outlet_new(x, &s_float); - x->first = 0; - return x; -} -static void bag_float(t_bag *x, t_float f) { - t_bagelem *bagelem, *e2, *e3; - if (x->velo != 0) { - bagelem = (t_bagelem *)getbytes(sizeof *bagelem); - bagelem->next = 0; - bagelem->value = f; - if (!x->first) x->first = bagelem; - else { /* LATER replace with a faster algorithm */ - for (e2 = x->first; (e3 = e2->next); e2 = e3) {} - e2->next = bagelem; - } - } else { - if (!x->first) return; - if (x->first->value == f) { - bagelem = x->first; - x->first = x->first->next; - free(bagelem); - return; - } - for (e2 = x->first; (e3 = e2->next); e2 = e3) if (e3->value == f) { - e2->next = e3->next; - free(e3); - return; - } - } -} -static void bag_flush(t_bag *x) { - t_bagelem *bagelem; - while ((bagelem = x->first)) { - x->outlet->send(bagelem->value); - x->first = bagelem->next; - free(bagelem); - } -} -static void bag_clear(t_bag *x) { - t_bagelem *bagelem; - while ((bagelem = x->first)) { - x->first = bagelem->next; - free(bagelem); - } -} -static void bag_setup() { - bag_class = class_new2("bag",bag_new,bag_clear,sizeof(t_bag),0,""); - class_addfloat(bag_class, bag_float); - class_addmethod2(bag_class,bag_flush,"flush",""); - class_addmethod2(bag_class,bag_clear,"clear",""); -} -void midi_setup() { - midiin_class = class_new2( "midiin", midiin_new, midiin_free,sizeof(t_midiin),CLASS_NOINLET,"F"); - sysexin_class = class_new2("sysexin",sysexin_new,sysexin_free,sizeof(t_midiin),CLASS_NOINLET,"F"); - notein_class = class_new2( "notein", notein_new, notein_free,sizeof(t_notein),CLASS_NOINLET,"F"); - ctlin_class = class_new2( "ctlin", ctlin_new, ctlin_free,sizeof( t_ctlin),CLASS_NOINLET,"*"); - class_addlist( midiin_class, midiin_list); midiin_sym = gensym( "#midiin"); class_sethelpsymbol( midiin_class, gensym("midi")); - class_addlist(sysexin_class, midiin_list); sysexin_sym = gensym("#sysexin"); class_sethelpsymbol(sysexin_class, gensym("midi")); - class_addlist( notein_class, notein_list); notein_sym = gensym( "#notein"); class_sethelpsymbol( notein_class, gensym("midi")); - class_addlist( ctlin_class, ctlin_list); ctlin_sym = gensym( "#ctlin"); class_sethelpsymbol( ctlin_class, gensym("midi")); - - pgmin_class = class_new2("pgmin", pgmin_new, pgmin_free, sizeof(t_pgmin), CLASS_NOINLET,"F"); - bendin_class = class_new2("bendin", bendin_new, bendin_free, sizeof(t_bendin), CLASS_NOINLET,"F"); - touchin_class = class_new2("touchin",touchin_new,touchin_free,sizeof(t_touchin),CLASS_NOINLET,"F"); - class_addlist( pgmin_class,midi2_list); - class_addlist( bendin_class,midi2_list); - class_addlist(touchin_class,midi2_list); - class_sethelpsymbol( pgmin_class, gensym("midi")); - class_sethelpsymbol( bendin_class, gensym("midi")); - class_sethelpsymbol(touchin_class, gensym("midi")); - pgmin_sym = gensym("#pgmin"); - bendin_sym = gensym("#bendin"); - touchin_sym = gensym("#touchin"); - - polytouchin_setup(); midirealtimein_setup(); midiclkin_setup(); - midiout_class = class_new2("midiout", midiout_new, 0, sizeof(t_midiout), 0,"FF"); - ctlout_class = class_new2("ctlout", ctlout_new, 0, sizeof(t_ctlout), 0,"FF"); - noteout_class = class_new2("noteout", noteout_new, 0, sizeof(t_noteout), 0,"F"); - pgmout_class = class_new2("pgmout", pgmout_new, 0, sizeof(t_pgmout), 0,"F"); - bendout_class = class_new2("bendout", bendout_new, 0, sizeof(t_bendout), 0,"F"); - touchout_class = class_new2("touchout", touchout_new, 0, sizeof(t_touchout), 0,"F"); - class_addfloat( midiout_class, midiout_float); class_sethelpsymbol( midiout_class, gensym("midi")); - class_addfloat( ctlout_class, ctlout_float); class_sethelpsymbol( ctlout_class, gensym("midi")); - class_addfloat( noteout_class, noteout_float); class_sethelpsymbol( noteout_class, gensym("midi")); - class_addfloat( pgmout_class, pgmout_float); class_sethelpsymbol( pgmout_class, gensym("midi")); - class_addfloat( bendout_class, bendout_float); class_sethelpsymbol( bendout_class, gensym("midi")); - class_addfloat(touchout_class, touchout_float); class_sethelpsymbol(touchout_class, gensym("midi")); - polytouchout_setup(); makenote_setup(); stripnote_setup(); poly_setup(); bag_setup(); -} - -static t_class *delay_class; -struct t_delay : t_object { - t_clock *clock; - double deltime; -}; -static void delay_bang(t_delay *x) {clock_delay(x->clock, x->deltime);} -static void delay_stop(t_delay *x) {clock_unset(x->clock);} -static void delay_ft1(t_delay *x, t_floatarg g) {x->deltime = max(0.f,g);} -static void delay_float(t_delay *x, t_float f) {delay_ft1(x, f); delay_bang(x);} -static void delay_tick(t_delay *x) {x->outlet->send();} -static void delay_free(t_delay *x) {clock_free(x->clock);} -static void *delay_new(t_floatarg f) { - t_delay *x = (t_delay *)pd_new(delay_class); - delay_ft1(x, f); - x->clock = clock_new(x, (t_method)delay_tick); - outlet_new(x, gensym("bang")); - inlet_new(x, x, gensym("float"), gensym("ft1")); - return x; -} -static void delay_setup() { - t_class *c = delay_class = class_new2("delay",delay_new,delay_free,sizeof(t_delay),0,"F"); - class_addcreator2("del",delay_new,"F"); - class_addbang(c, delay_bang); - class_addmethod2(c,delay_stop,"stop",""); - class_addmethod2(c,delay_ft1,"ft1","f"); - class_addfloat(c, delay_float); -} - -static t_class *metro_class; -struct t_metro : t_object { - t_clock *clock; - double deltime; - int hit; -}; -static void metro_tick(t_metro *x) { - x->hit = 0; - x->outlet->send(); - if (!x->hit) clock_delay(x->clock, x->deltime); -} -static void metro_float(t_metro *x, t_float f) { - if (f) metro_tick(x); else clock_unset(x->clock); - x->hit = 1; -} -static void metro_bang(t_metro *x) {metro_float(x, 1);} -static void metro_stop(t_metro *x) {metro_float(x, 0);} -static void metro_ft1(t_metro *x, t_floatarg g) {x->deltime = max(1.f,g);} -static void metro_free(t_metro *x) {clock_free(x->clock);} -static void *metro_new(t_floatarg f) { - t_metro *x = (t_metro *)pd_new(metro_class); - metro_ft1(x, f); - x->hit = 0; - x->clock = clock_new(x, (t_method)metro_tick); - outlet_new(x, gensym("bang")); - inlet_new(x, x, gensym("float"), gensym("ft1")); - return x; -} -static void metro_setup() { - t_class *c = metro_class = class_new2("metro",metro_new,metro_free,sizeof(t_metro),0,"F"); - class_addbang(c, metro_bang); - class_addmethod2(c,metro_stop,"stop",""); - class_addmethod2(c,metro_ft1,"ft1","f"); - class_addfloat(c, metro_float); -} - -static t_class *line_class; -struct t_line : t_object { - t_clock *clock; - double targettime; - t_float targetval; - double prevtime; - t_float setval; - int gotinlet; - t_float grain; - double oneovertimediff; - double in1val; -}; -static void line_tick(t_line *x) { - double timenow = clock_getsystime(); - double msectogo = - clock_gettimesince(x->targettime); - if (msectogo < 1E-9) { - x->outlet->send(x->targetval); - } else { - x->outlet->send(x->setval + x->oneovertimediff * (timenow-x->prevtime) * (x->targetval-x->setval)); - clock_delay(x->clock, (x->grain > msectogo ? msectogo : x->grain)); - } -} -static void line_float(t_line *x, t_float f) { - double timenow = clock_getsystime(); - if (x->gotinlet && x->in1val > 0) { - if (timenow > x->targettime) x->setval = x->targetval; - else x->setval = x->setval + x->oneovertimediff * (timenow-x->prevtime) * (x->targetval-x->setval); - x->prevtime = timenow; - x->targettime = clock_getsystimeafter(x->in1val); - x->targetval = f; - line_tick(x); - x->gotinlet = 0; - x->oneovertimediff = 1./ (x->targettime - timenow); - clock_delay(x->clock, (x->grain > x->in1val ? x->in1val : x->grain)); - } else { - clock_unset(x->clock); - x->targetval = x->setval = f; - x->outlet->send(f); - } - x->gotinlet = 0; -} -static void line_ft1(t_line *x, t_floatarg g) { - x->in1val = g; - x->gotinlet = 1; -} -static void line_stop(t_line *x) { - x->targetval = x->setval; - clock_unset(x->clock); -} -static void line_set(t_line *x, t_floatarg f) { - clock_unset(x->clock); - x->targetval = x->setval = f; -} -static void line_set_granularity(t_line *x, t_floatarg grain) { - if (grain <= 0) grain = 20; - x->grain = grain; -} -static void line_free(t_line *x) { - clock_free(x->clock); -} -static void *line_new(t_floatarg f, t_floatarg grain) { - t_line *x = (t_line *)pd_new(line_class); - x->targetval = x->setval = f; - x->gotinlet = 0; - x->oneovertimediff = 1; - x->clock = clock_new(x, (t_method)line_tick); - x->targettime = x->prevtime = clock_getsystime(); - line_set_granularity(x, grain); - outlet_new(x, gensym("float")); - inlet_new(x, x, gensym("float"), gensym("ft1")); - return x; -} -static void line_setup() { - t_class *c = line_class = class_new2("line",line_new,line_free,sizeof(t_line),0,"FF"); - class_addmethod2(c,line_ft1,"ft1","f"); - class_addmethod2(c,line_stop,"stop",""); - class_addmethod2(c,line_set,"set","f"); - class_addmethod2(c,line_set_granularity,"granularity","f"); - class_addfloat(c,line_float); -} - -static t_class *pipe_class; -struct t_hang2 { - t_clock *clock; - t_hang2 *next; - struct t_pipe *owner; - union word vec[0]; /* not the actual number of elements */ -}; -struct t_pipe : t_object { - int n; - float deltime; - t_atom *vec; - t_hang2 *hang; -}; -static void *pipe_new(t_symbol *s, int argc, t_atom *argv) { - t_pipe *x = (t_pipe *)pd_new(pipe_class); - t_atom defarg, *ap; - t_atom *vec, *vp; - float deltime=0; - if (argc) { - if (argv[argc-1].a_type != A_FLOAT) { - std::ostringstream os; - atom_ostream(&argv[argc-1], os); - post("pipe: %s: bad time delay value", os.str().data()); - } else deltime = argv[argc-1].a_float; - argc--; - } - if (!argc) { - argv = &defarg; - argc = 1; - SETFLOAT(&defarg, 0); - } - x->n = argc; - vec = x->vec = (t_atom *)getbytes(argc * sizeof(*x->vec)); - vp = vec; - ap = argv; - for (int i=0; i<argc; i++, ap++, vp++) { - if (ap->a_type == A_FLOAT) { - *vp = *ap; - outlet_new(x, &s_float); - if (i) floatinlet_new(x, &vp->a_float); - } else if (ap->a_type == A_SYMBOL) { - char c = *ap->a_symbol->name; - if (c=='s') {SETSYMBOL(vp, &s_symbol); outlet_new(x, &s_symbol); if (i) symbolinlet_new(x, &vp->a_symbol);} - else if (c=='p') {vp->a_type = A_POINTER; outlet_new(x, &s_pointer); /*if (i) pointerinlet_new(x, gp);*/} - else if (c=='f') {SETFLOAT(vp,0); outlet_new(x, &s_float); if (i) floatinlet_new(x, &vp->a_float);} - else error("pack: %s: bad type", ap->a_symbol->name); - } - } - floatinlet_new(x, &x->deltime); - x->hang = 0; - x->deltime = deltime; - return x; -} -static void hang_free(t_hang2 *h) { - clock_free(h->clock); - free(h); -} -static void hang_tick(t_hang2 *h) { - t_pipe *x = h->owner; - t_hang2 *h2, *h3; - if (x->hang == h) x->hang = h->next; - else for (h2 = x->hang; (h3 = h2->next); h2 = h3) { - if (h3 == h) { - h2->next = h3->next; - break; - } - } - t_atom *p = x->vec + x->n-1; - t_word *w = h->vec + x->n-1; - for (int i = x->n; i--; p--, w--) { - switch (p->a_type) { - case A_FLOAT: x->out(i)->send(w->w_float ); break; - case A_SYMBOL: x->out(i)->send(w->w_symbol ); break; - case A_POINTER:x->out(i)->send(w->w_gpointer); break; - default:{} - } - } - hang_free(h); -} -static void pipe_list(t_pipe *x, t_symbol *s, int ac, t_atom *av) { - t_hang2 *h = (t_hang2 *)getbytes(sizeof(*h) + (x->n - 1) * sizeof(*h->vec)); - int n = x->n; - if (ac > n) ac = n; - t_atom *p = x->vec; - t_atom *ap = av; - for (int i=0; i<ac; i++, p++, ap++) *p = *ap; - t_word *w = h->vec; - p = x->vec; - for (int i=0; i< n; i++, p++, w++) *w = p->a_w; - h->next = x->hang; - x->hang = h; - h->owner = x; - h->clock = clock_new(h, (t_method)hang_tick); - clock_delay(h->clock, (x->deltime >= 0 ? x->deltime : 0)); -} -static void pipe_flush(t_pipe *x) { - while (x->hang) hang_tick(x->hang); -} -static void pipe_clear(t_pipe *x) { - t_hang2 *hang; - while ((hang = x->hang)) { - x->hang = hang->next; - hang_free(hang); - } -} -static void pipe_setup() { - pipe_class = class_new2("pipe",pipe_new,pipe_clear,sizeof(t_pipe),0,"*"); - class_addlist(pipe_class, pipe_list); - class_addmethod2(pipe_class,pipe_flush,"flush",""); - class_addmethod2(pipe_class,pipe_clear,"clear",""); -} - -/* ---------------------------------------------------------------- */ -/* new desiredata classes are below this point. */ - -static t_class *unpost_class; -struct t_unpost : t_object { - t_outlet *o0,*o1; -}; -struct t_unpost_frame { - t_unpost *self; - std::ostringstream buf; -}; -static t_unpost_frame *current_unpost; - -void *unpost_new (t_symbol *s) { - t_unpost *x = (t_unpost *)pd_new(unpost_class); - x->o0 = outlet_new(x,&s_symbol); - x->o1 = outlet_new(x,&s_symbol); - return x; -} -extern t_printhook sys_printhook; -void unpost_printhook (const char *s) { - std::ostringstream &b = current_unpost->buf; - b << s; - const char *p; - const char *d=b.str().data(),*dd=d; - for (;;) { - p = strchr(d,'\n'); - if (!p) break; - current_unpost->self->o1->send(gensym2(d,p-d)); - d=p+1; - } - if (d!=dd) { - char *q = strdup(d); /* well i could use memmove, but i'm not supposed to use strcpy because of overlap */ - current_unpost->buf.clear(); - current_unpost->buf << q; - free(q); - } -} -void unpost_anything (t_unpost *x, t_symbol *s, int argc, t_atom *argv) { - t_printhook backup1 = sys_printhook; - t_unpost_frame *backup2 = current_unpost; - sys_printhook = unpost_printhook; - current_unpost = new t_unpost_frame; - current_unpost->self = x; - x->o0->send(s,argc,argv); - sys_printhook = backup1; - current_unpost = backup2; -} - -struct t_unparse : t_object {}; -static t_class *unparse_class; -void *unparse_new (t_symbol *s) { - t_unparse *x = (t_unparse *)pd_new(unparse_class); - outlet_new(x,&s_symbol); - return x; -} -void unparse_list (t_unparse *x, t_symbol *s, int argc, t_atom *argv) { - std::ostringstream o; - for (int i=0; i<argc; i++) { - o << ' '; - atom_ostream(argv+i,o); - } - x->outlet->send(gensym(o.str().data()+1)); -} - -struct t_parse : t_object {}; -static t_class *parse_class; -void *parse_new (t_symbol *s) { - t_parse *x = (t_parse *)pd_new(parse_class); - outlet_new(x,&s_list); - return x; -} -void parse_symbol (t_unpost *x, t_symbol *s) { - t_binbuf *b = binbuf_new(); - binbuf_text(b,s->name,s->n); - x->outlet->send(&s_list,b->n,b->v); - binbuf_free(b); -} - -struct t_tracecall : t_object {}; -static t_class *tracecall_class; -void *tracecall_new (t_symbol *s) { - t_tracecall *x = (t_tracecall *)pd_new(tracecall_class); - outlet_new(x,&s_list); - return x; -} -void tracecall_anything (t_tracecall *x, t_symbol *dummy, int dum, t_atom *my) { - t_atom a[2]; - for (int i=pd_stackn-1; i>=0; i--) { - SETSYMBOL( &a[0],pd_stack[i].self->_class->name); - SETSYMBOL( &a[1],pd_stack[i].s); - //SETPOINTER(&a[2],pd_stack[i].self); - x->outlet->send(2,a); - } -} - -static void matju_setup() { - unpost_class = class_new2("unpost",unpost_new,0,sizeof(t_unpost),0,""); - class_addanything(unpost_class, unpost_anything); - unparse_class = class_new2("unparse",unparse_new,0,sizeof(t_unparse),0,""); - class_addlist(unparse_class, unparse_list); - parse_class = class_new2("parse",parse_new,0,sizeof(t_parse),0,""); - class_addsymbol(parse_class, parse_symbol); - tracecall_class = class_new2("tracecall",tracecall_new,0,sizeof(t_tracecall),0,""); - class_addanything(tracecall_class,tracecall_anything); -} - -/* end of new desiredata classes */ -/* ---------------------------------------------------------------- */ - -void builtins_setup() { - t_symbol *s = gensym("acoustics.pd"); - FUNC1DECL(mtof, "mtof"); - FUNC1DECL(ftom, "ftom"); - FUNC1DECL(powtodb,"powtodb"); - FUNC1DECL(rmstodb,"rmstodb"); - FUNC1DECL(dbtopow,"dbtopow"); - FUNC1DECL(dbtorms,"dbtorms"); - random_setup(); - loadbang_setup(); - namecanvas_setup(); - print_setup(); - macro_setup(); - display_setup(); - any_setup(); - clipboard_setup(); - delay_setup(); - metro_setup(); - line_setup(); - timer_setup(); - pipe_setup(); - misc_setup(); - sendreceive_setup(); - select_setup(); - route_setup(); - pack_setup(); - unpack_setup(); - trigger_setup(); - spigot_setup(); - moses_setup(); - until_setup(); - makefilename_setup(); - swap_setup(); - change_setup(); - value_setup(); - - t_class *c; - qlist_class = c = class_new2("qlist",qlist_new,qlist_free,sizeof(t_qlist),0,""); - class_addmethod2(c,qlist_rewind, "rewind",""); - class_addmethod2(c,qlist_next, "next","F"); - class_addmethod2(c,qlist_set, "set","*"); - class_addmethod2(c,qlist_clear, "clear",""); - class_addmethod2(c,qlist_add, "add","*"); - class_addmethod2(c,qlist_add2, "add2","*"); - class_addmethod2(c,qlist_add, "append","*"); - class_addmethod2(c,qlist_read, "read","sS"); - class_addmethod2(c,qlist_write, "write","sS"); - class_addmethod2(c,qlist_print, "print","S"); - class_addmethod2(c,qlist_tempo, "tempo","f"); - class_addbang(c,qlist_bang); - - textfile_class = c = class_new2("textfile",textfile_new,textfile_free,sizeof(t_textfile),0,""); - class_addmethod2(c,textfile_rewind, "rewind",""); - class_addmethod2(c,qlist_set, "set","*"); - class_addmethod2(c,qlist_clear, "clear",""); - class_addmethod2(c,qlist_add, "add","*"); - class_addmethod2(c,qlist_add2, "add2","*"); - class_addmethod2(c,qlist_add, "append","*"); - class_addmethod2(c,qlist_read, "read","sS"); - class_addmethod2(c,qlist_write, "write","sS"); - class_addmethod2(c,qlist_print, "print","S"); - class_addbang(c,textfile_bang); - netsend_setup(); - netreceive_setup(); - openpanel_setup(); - savepanel_setup(); - key_setup(); - -extern t_class *binbuf_class; - class_addlist(binbuf_class, alist_list); - class_addanything(binbuf_class, alist_anything); - list_setup(); - arithmetic_setup(); - midi_setup(); - matju_setup(); -} diff --git a/desiredata/src/builtins_dsp.c b/desiredata/src/builtins_dsp.c deleted file mode 100644 index 2f0aec63..00000000 --- a/desiredata/src/builtins_dsp.c +++ /dev/null @@ -1,3632 +0,0 @@ -/* Copyright (c) 2007 Mathieu Bouchard - Copyright (c) 1997-1999 Miller Puckette. - For information on usage and redistribution, - and for a DISCLAIMER OF ALL WARRANTIES, - see the file "LICENSE.txt" in this distribution. */ - -/* arithmetic binops (+, -, *, /). -If no creation argument is given, there are two signal inlets for vector/vector -operation; otherwise it's vector/scalar and the second inlet takes a float -to reset the value. -*/ - -//#define HAVE_LIBFFTW3F - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include "m_simd.h" -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -extern int ugen_getsortno (); -#define DEFDELVS 64 /* LATER get this from canvas at DSP time */ -#ifdef HAVE_LIBFFTW3F -#include <fftw3.h> -#endif -#define DEFSENDVS 64 /* LATER get send to get this from canvas */ -#define LOGTEN 2.302585092994 -#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */ -#define int32 int -#ifdef BIGENDIAN -#define HIOFFSET 0 /* word offset to find MSB */ -#define LOWOFFSET 1 /* word offset to find LSB */ -#else -#define HIOFFSET 1 -#define LOWOFFSET 0 -#endif - -#undef CLASS_MAINSIGNALIN -/* because C++ bitches about null pointers, we'll use 8 instead (really): */ -#define CLASS_MAINSIGNALIN(c, type, field) class_domainsignalin(c, (char *)(&((type *)8)->field) - (char *)8) - -#define clock_new(a,b) clock_new(a,(t_method)b) - -#undef min -#undef max - -/* ----------------------------- plus ----------------------------- */ - -struct t_dop : t_object { - float a; - t_float b; /* inlet value, if necessary */ -}; - -#define DSPDECL(NAME) static t_class *NAME##_class, *scalar##NAME##_class; typedef t_dop t_##NAME, t_scalar##NAME; -DSPDECL(plus) -DSPDECL(minus) -DSPDECL(times) -DSPDECL(over) -DSPDECL(max) -DSPDECL(min) -DSPDECL(lt) -DSPDECL(gt) -DSPDECL(le) -DSPDECL(ge) -DSPDECL(eq) -DSPDECL(ne) - -#define DSPNEW(NAME,SYM) \ -static void *NAME##_new(t_symbol *s, int argc, t_atom *argv) { \ - if (argc > 1) error("extra arguments ignored"); \ - t_dop *x = (t_dop *)pd_new(argc ? scalar##NAME##_class : NAME##_class); \ - if (argc) { \ - floatinlet_new(x, &x->b); \ - x->b = atom_getfloatarg(0, argc, argv); \ - } else inlet_new(x, x, &s_signal, &s_signal); \ - outlet_new(x, &s_signal); \ - x->a = 0; \ - return x;} \ -static void NAME##_setup() { \ - t_class *c = NAME##_class = class_new2(SYM,NAME##_new,0,sizeof(t_dop),0,"*"); \ - class_addmethod2(c, NAME##_dsp, "dsp",""); \ - CLASS_MAINSIGNALIN(c, t_dop, a); \ - class_sethelpsymbol(NAME##_class, gensym("sigbinops")); \ - c = scalar##NAME##_class = class_new2(SYM,0,0,sizeof(t_dop),0,""); \ - CLASS_MAINSIGNALIN(c, t_dop, a); \ - class_addmethod2(c, scalar##NAME##_dsp, "dsp",""); \ - class_sethelpsymbol(scalar##NAME##_class, gensym("sigbinops"));} - -/* use when simd functions are present */ -#define DSPDSP(NAME) \ -static void NAME##_dsp(t_minus *x, t_signal **sp) { \ - const int n = sp[0]->n; \ - if(n&7) dsp_add(NAME##_perform, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); \ - else if(SIMD_CHECK3(n,sp[0]->v,sp[1]->v,sp[2]->v)) \ - dsp_add(NAME##_perf_simd, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); \ - else dsp_add(NAME##_perf8, 4, sp[0]->v, sp[1]->v, sp[2]->v, n);} \ -static void scalar##NAME##_dsp(t_scalarminus *x, t_signal **sp) { \ - const int n = sp[0]->n;\ - if(n&7) dsp_add(scalar##NAME##_perform, 4, sp[0]->v, &x->b,sp[1]->v, n);\ - else if(SIMD_CHECK2(n,sp[0]->v,sp[1]->v)) \ - dsp_add(scalar##NAME##_perf_simd, 4, sp[0]->v, &x->b, sp[1]->v, n);\ - else dsp_add(scalar##NAME##_perf8, 4, sp[0]->v, &x->b, sp[1]->v, n);} - -/* use when simd functions are missing */ -#define DSPDSP2(NAME) \ -static void NAME##_dsp(t_minus *x, t_signal **sp) { \ - const int n = sp[0]->n; \ - if(n&7) dsp_add(NAME##_perform, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); \ - else dsp_add(NAME##_perf8, 4, sp[0]->v, sp[1]->v, sp[2]->v, n);} \ -static void scalar##NAME##_dsp(t_scalarminus *x, t_signal **sp) { \ - const int n = sp[0]->n;\ - if(n&7) dsp_add(scalar##NAME##_perform, 4, sp[0]->v, &x->b,sp[1]->v, n);\ - else dsp_add(scalar##NAME##_perf8, 4, sp[0]->v, &x->b, sp[1]->v, n);} - -#define PERFORM(NAME,EXPR) \ -t_int *NAME##_perform(t_int *w) { \ - PERFORM4ARGS(t_float *,in1, t_float *,in2, t_float *,out, int,n); \ - while (n--) {t_float a=*in1++, b=*in2++; *out++ = (EXPR);} \ - return w+5;} \ -t_int *NAME##_perf8(t_int *w) { \ - PERFORM4ARGS(t_float *,in1, t_float *,in2, t_float *,out, int,n); \ - for (; n; n -= 8, in1 += 8, in2 += 8, out += 8) { \ - {t_float a=in1[0], b=in2[0]; out[0] = (EXPR);} \ - {t_float a=in1[1], b=in2[1]; out[1] = (EXPR);} \ - {t_float a=in1[2], b=in2[2]; out[2] = (EXPR);} \ - {t_float a=in1[3], b=in2[3]; out[3] = (EXPR);} \ - {t_float a=in1[4], b=in2[4]; out[4] = (EXPR);} \ - {t_float a=in1[5], b=in2[5]; out[5] = (EXPR);} \ - {t_float a=in1[6], b=in2[6]; out[6] = (EXPR);} \ - {t_float a=in1[7], b=in2[7]; out[7] = (EXPR);}} \ - return w+5;} \ -t_int *scalar##NAME##_perform(t_int *w) { \ - PERFORM4ARGS(t_float *,in, t_float *,in2, t_float *,out, int,n); t_float b=*in2; \ - while (n--) {t_float a=*in++; *out++ = (EXPR);} \ - return w+5;} \ -t_int *scalar##NAME##_perf8(t_int *w) { \ - PERFORM4ARGS(t_float *,in, t_float *,in2, t_float *,out, int,n); t_float b=*in2; \ - for (; n; n -= 8, in += 8, out += 8) { \ - {t_float a=in[0]; out[0] = (EXPR);} \ - {t_float a=in[1]; out[1] = (EXPR);} \ - {t_float a=in[2]; out[2] = (EXPR);} \ - {t_float a=in[3]; out[3] = (EXPR);} \ - {t_float a=in[4]; out[4] = (EXPR);} \ - {t_float a=in[5]; out[5] = (EXPR);} \ - {t_float a=in[6]; out[6] = (EXPR);} \ - {t_float a=in[7]; out[7] = (EXPR);}} \ - return w+5;} - -void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n) { - if (n&7) dsp_add(plus_perform, 4, in1, in2, out, n); - else if(SIMD_CHECK3(n,in1,in2,out)) dsp_add(plus_perf_simd, 4, in1, in2, out, n); - else dsp_add(plus_perf8, 4, in1, in2, out, n); -} - -/* T.Grill - squaring: optimized * for equal input signals */ -t_int *sqr_perf8(t_int *w) { - PERFORM3ARGS(t_float *,in, t_float *,out, int,n); - for (; n; n -= 8, in += 8, out += 8) { - float f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3]; - float f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7]; - out[0] = f0 * f0; out[1] = f1 * f1; out[2] = f2 * f2; out[3] = f3 * f3; - out[4] = f4 * f4; out[5] = f5 * f5; out[6] = f6 * f6; out[7] = f7 * f7; - } - return w+4; -} - -/* T.Grill - added optimization for equal input signals */ -static void times_dsp(t_times *x, t_signal **sp) { - const int n = sp[0]->n; - if (n&7) dsp_add(times_perform, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); - else if(sp[0]->v == sp[1]->v) { - if(SIMD_CHECK2(n,sp[0]->v,sp[2]->v)) dsp_add(sqr_perf_simd, 3, sp[0]->v, sp[2]->v, n); - else dsp_add(sqr_perf8, 3, sp[0]->v, sp[2]->v, n); - } else { - if(SIMD_CHECK3(n,sp[0]->v,sp[1]->v,sp[2]->v)) dsp_add(times_perf_simd, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); - else dsp_add(times_perf8, 4, sp[0]->v, sp[1]->v, sp[2]->v, n); - } -} -static void scalartimes_dsp(t_scalartimes *x, t_signal **sp) { - const int n = sp[0]->n; - if (n&7) dsp_add(scalartimes_perform, 4, sp[0]->v, &x->b, sp[1]->v, n); - else if(SIMD_CHECK2(n,sp[0]->v,sp[1]->v)) dsp_add(scalartimes_perf_simd, 4, sp[0]->v, &x->b, sp[1]->v, n); - else dsp_add(scalartimes_perf8, 4, sp[0]->v, &x->b, sp[1]->v, n); -} - -PERFORM(plus ,a+b) DSPDSP(plus) DSPNEW(plus ,"+~") -PERFORM(minus,a-b) DSPDSP(minus) DSPNEW(minus,"-~") -PERFORM(times,a*b) /*DSPDSP(times)*/ DSPNEW(times,"*~") -/*PERFORM(over,a/b)*/ DSPDSP(over) DSPNEW(over ,"/~") -PERFORM(min ,a<b?a:b) DSPDSP(min) DSPNEW(min ,"min~") -PERFORM(max ,a>b?a:b) DSPDSP(max) DSPNEW(max ,"max~") -PERFORM(lt ,a<b) DSPDSP2(lt) DSPNEW(lt ,"<~") -PERFORM(gt ,a>b) DSPDSP2(gt) DSPNEW(gt ,">~") -PERFORM(le ,a<=b) DSPDSP2(le) DSPNEW(le ,"<=~") -PERFORM(ge ,a>=b) DSPDSP2(ge) DSPNEW(ge ,">=~") -PERFORM(eq ,a==b) DSPDSP2(eq) DSPNEW(eq ,"==~") -PERFORM(ne ,a!=b) DSPDSP2(ne) DSPNEW(ne ,"!=~") - -t_int *over_perform(t_int *w) { - PERFORM4ARGS(t_float *,in1, t_float *,in2, t_float *,out, int,n); - while (n--) { - float g = *in2++; - *out++ = (g ? *in1++ / g : 0); - } - return w+5; -} -t_int *over_perf8(t_int *w) { - PERFORM4ARGS(t_float *,in1, t_float *,in2, t_float *,out, int,n); - for (; n; n -= 8, in1 += 8, in2 += 8, out += 8) { - float f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3]; - float f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7]; - float g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3]; - float g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7]; - out[0] = (g0? f0 / g0 : 0); - out[1] = (g1? f1 / g1 : 0); - out[2] = (g2? f2 / g2 : 0); - out[3] = (g3? f3 / g3 : 0); - out[4] = (g4? f4 / g4 : 0); - out[5] = (g5? f5 / g5 : 0); - out[6] = (g6? f6 / g6 : 0); - out[7] = (g7? f7 / g7 : 0); - } - return w+5; -} -/* T.Grill - added check for zero */ -t_int *scalarover_perform(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float,f, t_float *,out, int,n); - if(f) f = 1./f; - while (n--) *out++ = *in++ * f; - return w+5; -} -t_int *scalarover_perf8(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float,f, t_float *,out, int,n); - if (f) f = 1.f / f; - for (; n; n -= 8, in += 8, out += 8) { - out[0] = in[0]*f; out[1] = in[1]*f; out[2] = in[2]*f; out[3] = in[3]*f; - out[4] = in[4]*f; out[5] = in[5]*f; out[6] = in[6]*f; out[7] = in[7]*f; - } - return w+5; -} - -/* ------------------------- tabwrite~ -------------------------- */ -static t_class *tabwrite_tilde_class; -struct t_tabwrite_tilde : t_object { - int phase; - int nsampsintab; - float *vec; - t_symbol *arrayname; - float a; -}; -static void *tabwrite_tilde_new(t_symbol *s) { - t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class); - x->phase = 0x7fffffff; - x->arrayname = s; - x->a = 0; - return x; -} -static void tabwrite_tilde_redraw(t_tabwrite_tilde *x) { - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) bug("tabwrite_tilde_redraw"); - else garray_redraw(a); -} -static t_int *tabwrite_tilde_perform(t_int *w) { - PERFORM3ARGS(t_tabwrite_tilde *,x, t_float *,in, int,n); - int phase = x->phase, endphase = x->nsampsintab; - if (!x->vec) goto bad; - if (endphase > phase) { - int nxfer = endphase - phase; - float *fp = x->vec + phase; - if (nxfer > n) nxfer = n; - phase += nxfer; - testcopyvec(fp, in, nxfer); - if (phase >= endphase) { - tabwrite_tilde_redraw(x); - phase = 0x7fffffff; - } - x->phase = phase; - } else x->phase = 0x7fffffff; -bad: - return w+4; -} -static t_int *tabwrite_tilde_perf_simd(t_int *w) { - PERFORM3ARGS(t_tabwrite_tilde *,x, t_float *,in, int,n); - int phase = x->phase, endphase = x->nsampsintab; - if (!x->vec) goto bad; - if (endphase > phase) { - int nxfer = endphase - phase; - float *fp = x->vec + phase; - if (nxfer > n) nxfer = n; - phase += nxfer; - if (SIMD_CHKCNT(nxfer)) testcopyvec_simd(fp, in, nxfer); - else testcopyvec(fp, in, nxfer); - if (phase >= endphase) { - tabwrite_tilde_redraw(x); - phase = 0x7fffffff; - } - x->phase = phase; - } else x->phase = 0x7fffffff; -bad: - return w+4; -} -void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s) { - x->arrayname = s; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) { - if (*s->name) error("tabwrite~: %s: no such array", x->arrayname->name); - x->vec = 0; - } else if (!garray_getfloatarray(a, &x->nsampsintab, &x->vec)) { - error("%s: bad template for tabwrite~", x->arrayname->name); - x->vec = 0; - } else garray_usedindsp(a); -} -static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp) { - tabwrite_tilde_set(x, x->arrayname); - if (SIMD_CHECK1(sp[0]->n, sp[0]->v)) - dsp_add(tabwrite_tilde_perf_simd, 3, x, sp[0]->v, sp[0]->n); - else dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->v, sp[0]->n); -} -static void tabwrite_tilde_bang(t_tabwrite_tilde *x) {x->phase = 0;} -static void tabwrite_tilde_start(t_tabwrite_tilde *x, t_floatarg f) {x->phase = (int)max((int)f,0);} -static void tabwrite_tilde_stop(t_tabwrite_tilde *x) { - if (x->phase != 0x7fffffff) { - tabwrite_tilde_redraw(x); - x->phase = 0x7fffffff; - } -} - -/* ------------ tabplay~ - non-transposing sample playback --------------- */ -static t_class *tabplay_tilde_class; -struct t_tabplay_tilde : t_object { - int phase; - int nsampsintab; - int limit; - float *vec; - t_symbol *arrayname; - t_clock *clock; -}; -static void tabplay_tilde_tick(t_tabplay_tilde *x); -static void *tabplay_tilde_new(t_symbol *s) { - t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class); - x->clock = clock_new(x, tabplay_tilde_tick); - x->phase = 0x7fffffff; - x->limit = 0; - x->arrayname = s; - outlet_new(x, &s_signal); - outlet_new(x, &s_bang); - return x; -} -static t_int *tabplay_tilde_perform(t_int *w) { - PERFORM3ARGS(t_tabplay_tilde *,x, t_float *,out, int,n); - t_float *fp; - int phase = x->phase, endphase = (x->nsampsintab < x->limit ? x->nsampsintab : x->limit), nxfer, n3; - if (!x->vec || phase >= endphase) {while (n--) *out++ = 0; goto bye;} - nxfer = min(endphase-phase,n); - fp = x->vec + phase; - n3 = n - nxfer; - phase += nxfer; - while (nxfer--) *out++ = *fp++; - if (phase >= endphase) { - clock_delay(x->clock, 0); - x->phase = 0x7fffffff; - while (n3--) *out++ = 0; - } else x->phase = phase; -bye: - return w+4; -} -void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s) { - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - x->arrayname = s; - if (!a) { - if (*s->name) error("tabplay~: %s: no such array", x->arrayname->name); - x->vec = 0; - } else if (!garray_getfloatarray(a, &x->nsampsintab, &x->vec)) { - error("%s: bad template for tabplay~", x->arrayname->name); - x->vec = 0; - } else garray_usedindsp(a); -} -static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp) { - tabplay_tilde_set(x, x->arrayname); - dsp_add(tabplay_tilde_perform, 3, x, sp[0]->v, sp[0]->n); -} -static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s, int argc, t_atom *argv) { - long start = atom_getintarg(0, argc, argv); - long length = atom_getintarg(1, argc, argv); - if (start < 0) start = 0; - if (length <= 0) x->limit = 0x7fffffff; else x->limit = start + length; - x->phase = start; -} -static void tabplay_tilde_stop(t_tabplay_tilde *x) {x->phase = 0x7fffffff;} -static void tabplay_tilde_tick(t_tabplay_tilde *x) {x->out(1)->send();} -static void tabplay_tilde_free(t_tabplay_tilde *x) {clock_free(x->clock);} - -/******************** tabread~ ***********************/ -static t_class *tabread_tilde_class; -struct t_tabread_tilde : t_object { - int npoints; - float *vec; - t_symbol *arrayname; - float a; -}; -static void *tabread_tilde_new(t_symbol *s) { - t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class); - x->arrayname = s; - x->vec = 0; - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static t_int *tabread_tilde_perform(t_int *w) { - PERFORM4ARGS(t_tabread_tilde *,x, t_float *,in, t_float *,out, int,n); - float *buf = x->vec; - int maxindex = x->npoints - 1; - if (!buf) {while (n--) *out++ = 0; goto bad;} - for (int i = 0; i < n; i++) { - int index = (int)*in++; - if (index < 0) index = 0; else if (index > maxindex) index = maxindex; - *out++ = buf[index]; - } -bad:return w+5; -} -void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s) { - x->arrayname = s; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) { - if (*s->name) error("tabread~: %s: no such array", x->arrayname->name); - x->vec = 0; - } else if (!garray_getfloatarray(a, &x->npoints, &x->vec)) { - error("%s: bad template for tabread~", x->arrayname->name); - x->vec = 0; - } else garray_usedindsp(a); -} -static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp) { - tabread_tilde_set(x, x->arrayname); - dsp_add(tabread_tilde_perform, 4, x, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void tabread_tilde_free(t_tabread_tilde *x) {} - -/******************** tabread4~ ***********************/ -static t_class *tabread4_tilde_class; -struct t_tabread4_tilde : t_object { - int npoints; - float *vec; - t_symbol *arrayname; - float a; -}; -static void *tabread4_tilde_new(t_symbol *s) { - t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class); - x->arrayname = s; - x->vec = 0; - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static t_int *tabread4_tilde_perform(t_int *w) { - PERFORM4ARGS(t_tabread4_tilde *,x, t_float *,in, t_float *,out, int,n); - int maxindex; - float *buf = x->vec, *fp; - maxindex = x->npoints - 3; - if (!buf) goto zero; - for (int i=0; i<n; i++) { - float findex = *in++; - int index = (int)findex; - float frac; - if (index < 1) index = 1, frac = 0; - else if (index > maxindex) index = maxindex, frac = 1; - else frac = findex - index; - fp = buf + index; - float a=fp[-1], b=fp[0], c=fp[1], d=fp[2]; - /* if (!i && !(count++ & 1023)) post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */ - float cminusb = c-b; - *out++ = b + frac * (cminusb - 0.1666667f * (1.-frac) * ((d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))); - } - return w+5; - zero: - while (n--) *out++ = 0; - return w+5; -} -void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s) { - x->arrayname = s; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) { - if (*s->name) error("tabread4~: %s: no such array", x->arrayname->name); - x->vec = 0; - } else if (!garray_getfloatarray(a, &x->npoints, &x->vec)) { - error("%s: bad template for tabread4~", x->arrayname->name); - x->vec = 0; - } else garray_usedindsp(a); -} -static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp) { - tabread4_tilde_set(x, x->arrayname); - dsp_add(tabread4_tilde_perform, 4, x, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void tabread4_tilde_free(t_tabread4_tilde *x) {} - -/******************** tabosc4~ ***********************/ - -#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */ - -#ifdef BIGENDIAN -#define HIOFFSET 0 /* word offset to find MSB */ -#define LOWOFFSET 1 /* word offset to find LSB */ -#else -#define HIOFFSET 1 -#define LOWOFFSET 0 -#endif -#include <sys/types.h> -//#define int32 int32_t -#define int32 int - -union tabfudge { - double d; - int32 i[2]; -}; -static t_class *tabosc4_tilde_class; -struct t_tabosc4_tilde : t_object { - float fnpoints; - float finvnpoints; - float *vec; - t_symbol *arrayname; - float a; - double phase; - float conv; -}; -static void *tabosc4_tilde_new(t_symbol *s) { - t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class); - x->arrayname = s; - x->vec = 0; - x->fnpoints = 512.; - x->finvnpoints = (1./512.); - outlet_new(x, &s_signal); - inlet_new(x, x, &s_float, gensym("ft1")); - x->a = 0; - return x; -} -static t_int *tabosc4_tilde_perform(t_int *w) { - PERFORM4ARGS(t_tabosc4_tilde *,x, t_float *,in, t_float *,out, int,n); - union tabfudge tf; - float fnpoints = x->fnpoints; - int mask = (int)(fnpoints-1); - float conv = fnpoints * x->conv; - float *tab = x->vec, *addr; - double dphase = fnpoints * x->phase + UNITBIT32; - if (!tab) {while (n--) *out++ = 0; return w+5;} - tf.d = UNITBIT32; - int normhipart = tf.i[HIOFFSET]; - while (n--) { - tf.d = dphase; - dphase += *in++ * conv; - addr = tab + (tf.i[HIOFFSET] & mask); - tf.i[HIOFFSET] = normhipart; - float frac = tf.d - UNITBIT32; - float a = addr[0]; - float b = addr[1]; - float c = addr[2]; - float d = addr[3]; - float cminusb = c-b; - *out++ = b + frac * (cminusb - 0.1666667f * (1.-frac) * ((d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))); - } - tf.d = UNITBIT32 * fnpoints; - normhipart = tf.i[HIOFFSET]; - tf.d = dphase + (UNITBIT32 * fnpoints - UNITBIT32); - tf.i[HIOFFSET] = normhipart; - x->phase = (tf.d - UNITBIT32 * fnpoints) * x->finvnpoints; - return w+5; -} -void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s) { - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - int npoints, pointsinarray; - x->arrayname = s; - if (!a) { - if (*s->name) error("tabosc4~: %s: no such array", x->arrayname->name); - x->vec = 0; - } else if (!garray_getfloatarray(a, &pointsinarray, &x->vec)) { - error("%s: bad template for tabosc4~", x->arrayname->name); - x->vec = 0; - } else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3))) { - error("%s: number of points (%d) not a power of 2 plus three", x->arrayname->name, pointsinarray); - x->vec = 0; - garray_usedindsp(a); - } else { - x->fnpoints = npoints; - x->finvnpoints = 1./npoints; - garray_usedindsp(a); - } -} -static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f) { - x->phase = f; -} -static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp) { - x->conv = 1. / sp[0]->sr; - tabosc4_tilde_set(x, x->arrayname); - dsp_add(tabosc4_tilde_perform, 4, x, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void tabosc4_tilde_setup() { -} - -static void tab_tilde_setup() { - t_class *c; - c = tabwrite_tilde_class = class_new2("tabwrite~",tabwrite_tilde_new,0,sizeof(t_tabwrite_tilde),0,"S"); - CLASS_MAINSIGNALIN(c, t_tabwrite_tilde, a); - class_addmethod2(c, tabwrite_tilde_dsp, "dsp",""); - class_addmethod2(c, tabwrite_tilde_set, "set","s"); - class_addmethod2(c, tabwrite_tilde_stop,"stop",""); - class_addmethod2(c, tabwrite_tilde_start,"start","F"); - class_addbang(c, tabwrite_tilde_bang); - c = tabplay_tilde_class = class_new2("tabplay~",tabplay_tilde_new,tabplay_tilde_free,sizeof(t_tabplay_tilde),0,"S"); - class_addmethod2(c, tabplay_tilde_dsp, "dsp",""); - class_addmethod2(c, tabplay_tilde_stop, "stop",""); - class_addmethod2(c, tabplay_tilde_set, "set","S"); - class_addlist(c, tabplay_tilde_list); - c = tabread_tilde_class = class_new2("tabread~",tabread_tilde_new,tabread_tilde_free, sizeof(t_tabread_tilde),0,"S"); - CLASS_MAINSIGNALIN(c, t_tabread_tilde, a); - class_addmethod2(c, tabread_tilde_dsp, "dsp",""); - class_addmethod2(c, tabread_tilde_set, "set","s"); - c = tabread4_tilde_class = class_new2("tabread4~",tabread4_tilde_new,tabread4_tilde_free,sizeof(t_tabread4_tilde),0,"S"); - CLASS_MAINSIGNALIN(c, t_tabread4_tilde, a); - class_addmethod2(c, tabread4_tilde_dsp, "dsp",""); - class_addmethod2(c, tabread4_tilde_set, "set","s"); - c = tabosc4_tilde_class = class_new2("tabosc4~",tabosc4_tilde_new,0,sizeof(t_tabosc4_tilde),0,"S"); - CLASS_MAINSIGNALIN(c, t_tabosc4_tilde, a); - class_addmethod2(c, tabosc4_tilde_dsp, "dsp",""); - class_addmethod2(c, tabosc4_tilde_set, "set","s"); - class_addmethod2(c, tabosc4_tilde_ft1, "ft1","f"); -} - -/* ------------------------ tabsend~ ------------------------- */ -static t_class *tabsend_class; -struct t_tabsend : t_object { - float *vec; - int graphperiod; - int graphcount; - t_symbol *arrayname; - float a; -}; -static void *tabsend_new(t_symbol *s) { - t_tabsend *x = (t_tabsend *)pd_new(tabsend_class); - x->graphcount = 0; - x->arrayname = s; - x->a = 0; - return x; -} -static t_int *tabsend_perform(t_int *w) { - PERFORM3ARGS(t_tabsend *,x, t_float *,in, int,n); - t_float *dest = x->vec; - int i = x->graphcount; - if (!x->vec) goto bad; - testcopyvec(dest,in,n); - if (!i--) { - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) bug("tabsend_dsp"); - else garray_redraw(a); - i = x->graphperiod; - } - x->graphcount = i; -bad: - return w+4; -} -static t_int *tabsend_perf_simd(t_int *w) { - PERFORM3ARGS(t_tabsend *,x, t_float *,in, int,n); - t_float *dest = x->vec; - int i = x->graphcount; - if (!x->vec) goto bad; - testcopyvec_simd(dest,in,n); - if (!i--) { - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) bug("tabsend_dsp"); - else garray_redraw(a); - i = x->graphperiod; - } - x->graphcount = i; -bad: - return w+4; -} -static void tabsend_dsp(t_tabsend *x, t_signal **sp) { - int vecsize; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) { - if (*x->arrayname->name) {error("tabsend~: %s: no such array", x->arrayname->name); return;} - } else if (!garray_getfloatarray(a, &vecsize, &x->vec)) { - error("%s: bad template for tabsend~", x->arrayname->name); return; - } else { - int n = sp[0]->n; - int ticksper = (int)(sp[0]->sr/n); - if (ticksper < 1) ticksper = 1; - x->graphperiod = ticksper; - if (x->graphcount > ticksper) x->graphcount = ticksper; - if (n < vecsize) vecsize = n; - garray_usedindsp(a); - if(SIMD_CHECK1(vecsize,sp[0]->v)) - dsp_add(tabsend_perf_simd, 3, x, sp[0]->v, vecsize); - else dsp_add(tabsend_perform, 3, x, sp[0]->v, vecsize); - } -} - -static void tabsend_setup() { - tabsend_class = class_new2("tabsend~",tabsend_new,0,sizeof(t_tabsend),0,"S"); - CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, a); - class_addmethod2(tabsend_class, tabsend_dsp, "dsp",""); -} - -/* ------------------------ tabreceive~ ------------------------- */ -static t_class *tabreceive_class; -struct t_tabreceive : t_object { - float *vec; - int vecsize; - t_symbol *arrayname; -}; -static t_int *tabreceive_perform(t_int *w) { - PERFORM3ARGS(t_tabreceive *,x, t_float *,out, int,n); - t_float *from = x->vec; - if (from) { - int vecsize = x->vecsize; while (vecsize--) *out++ = *from++; - vecsize = n - x->vecsize; while (vecsize--) *out++ = 0; - } else while (n--) *out++ = 0; - return w+4; -} -static t_int *tabreceive_perf8(t_int *w) { - PERFORM3ARGS(t_tabreceive *,x, t_float *,out, int,n); - t_float *from = x->vec; - if (from) copyvec_8(out,from,n); - else zerovec_8(out, n); - return w+4; -} -static t_int *tabreceive_perfsimd(t_int *w) { - PERFORM3ARGS(t_tabreceive *,x, t_float *,out, int,n); - t_float *from = x->vec; - if(from) copyvec_simd(out,from,n); - else zerovec_simd(out, n); - return w+4; -} -static void tabreceive_dsp(t_tabreceive *x, t_signal **sp) { - t_garray *a; - if (!(a = (t_garray *)pd_findbyclass(x->arrayname, garray_class))) { - if (*x->arrayname->name) error("tabsend~: %s: no such array", x->arrayname->name); - } else if (!garray_getfloatarray(a, &x->vecsize, &x->vec)) { - error("%s: bad template for tabreceive~", x->arrayname->name); - } else { - if (x->vecsize > sp[0]->n) x->vecsize = sp[0]->n; - garray_usedindsp(a); - /* the array is aligned in any case */ - if(sp[0]->n&7) dsp_add(tabreceive_perform, 3, x, sp[0]->v, sp[0]->n); - else if(SIMD_CHECK1(sp[0]->n,sp[0]->v)) - dsp_add(tabreceive_perfsimd, 3, x, sp[0]->v, sp[0]->n); - else dsp_add(tabreceive_perf8, 3, x, sp[0]->v, sp[0]->n); - } -} -static void *tabreceive_new(t_symbol *s) { - t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class); - x->arrayname = s; - outlet_new(x, &s_signal); - return x; -} -static void tabreceive_setup() { - tabreceive_class = class_new2("tabreceive~",tabreceive_new,0,sizeof(t_tabreceive),0,"S"); - class_addmethod2(tabreceive_class, tabreceive_dsp, "dsp",""); -} - -/* ---------- tabread: control, non-interpolating ------------------------ */ -static t_class *tabread_class; -struct t_tabread : t_object { - t_symbol *arrayname; -}; -static void tabread_float(t_tabread *x, t_float f) { - int npoints; - t_float *vec; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - if (!a) {error("%s: no such array", x->arrayname->name); return;} - if (!garray_getfloatarray(a, &npoints, &vec)) {error("%s: bad template for tabread", x->arrayname->name); return;} - int n = clip(int(f),0,npoints-1); - x->outlet->send(npoints ? vec[n] : 0); -} -static void tabread_set(t_tabread *x, t_symbol *s) { - x->arrayname = s; -} -static void *tabread_new(t_symbol *s) { - t_tabread *x = (t_tabread *)pd_new(tabread_class); - x->arrayname = s; - outlet_new(x, &s_float); - return x; -} -static void tabread_setup() { - tabread_class = class_new2("tabread",tabread_new,0,sizeof(t_tabread),0,"S"); - class_addfloat(tabread_class, tabread_float); - class_addmethod2(tabread_class, tabread_set, "set","s"); -} - -/* ---------- tabread4: control, 4-point interpolation --------------- */ -static t_class *tabread4_class; -struct t_tabread4 : t_object { - t_symbol *arrayname; -}; -static void tabread4_float(t_tabread4 *x, t_float f) { - t_garray *ar = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - int npoints; - t_float *vec; - if (!ar) {error("%s: no such array", x->arrayname->name); return;} - if (!garray_getfloatarray(ar, &npoints, &vec)) {error("%s: bad template for tabread4", x->arrayname->name); return;} - if (npoints < 4) {x->outlet->send(0.); return;} - if (f <= 1) {x->outlet->send(vec[1]); return;} - if (f >= npoints-2) {x->outlet->send(vec[npoints-2]); return;} - int n = min(int(f),npoints-3); - float *fp = vec + n; - float frac = f - n; - float a=fp[-1], b=fp[0], c=fp[1], d=fp[2]; - float cminusb = c-b; - x->outlet->send (b + frac * (cminusb - 0.1666667f * (1.-frac) * ((d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)))); -} -static void tabread4_set(t_tabread4 *x, t_symbol *s) {x->arrayname = s;} -static void *tabread4_new(t_symbol *s) { - t_tabread4 *x = (t_tabread4 *)pd_new(tabread4_class); - x->arrayname = s; - outlet_new(x, &s_float); - return x; -} -static void tabread4_setup() { - tabread4_class = class_new2("tabread4",tabread4_new,0,sizeof(t_tabread4),0,"S"); - class_addfloat(tabread4_class, tabread4_float); - class_addmethod2(tabread4_class, tabread4_set, "set","s"); -} - -/* ------------------ tabwrite: control ------------------------ */ -static t_class *tabwrite_class; -struct t_tabwrite : t_object { - t_symbol *arrayname; - float ft1; -}; -static void tabwrite_float(t_tabwrite *x, t_float f) { - int vecsize; - t_garray *a = (t_garray *)pd_findbyclass(x->arrayname, garray_class); - t_float *vec; - if (!a) {error("%s: no such array", x->arrayname->name); return;} - if (!garray_getfloatarray(a, &vecsize, &vec)) {error("%s: bad template for tabwrite", x->arrayname->name); return;} - int n = (int)x->ft1; - if (n < 0) n = 0; else if (n > vecsize-1) n = vecsize-1; - vec[n] = f; - garray_redraw(a); -} -static void tabwrite_set(t_tabwrite *x, t_symbol *s) {x->arrayname = s;} -static void *tabwrite_new(t_symbol *s) { - t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class); - x->ft1 = 0; - x->arrayname = s; - floatinlet_new(x, &x->ft1); - return x; -} -void tabwrite_setup() { - tabwrite_class = class_new2("tabwrite",tabwrite_new,0,sizeof(t_tabwrite),0,"S"); - class_addfloat(tabwrite_class, tabwrite_float); - class_addmethod2(tabwrite_class, tabwrite_set, "set","s"); -} - -/* -------------------------- sig~ ------------------------------ */ -static t_class *sig_tilde_class; -struct t_sig : t_object { - float a; -}; -t_int *sig_tilde_perform(t_int *w) { - PERFORM3ARGS(t_float *,f, t_float *,out, int,n); - t_float g=*f; - while (n--) *out++ = g; - return w+4; -} -t_int *sig_tilde_perf8(t_int *w) { - PERFORM3ARGS(t_float,f, t_float *,out, int,n); - for (; n; n -= 8, out += 8) { - out[0] = f; out[1] = f; - out[2] = f; out[3] = f; - out[4] = f; out[5] = f; - out[6] = f; out[7] = f; - } - return w+4; -} -void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n) { - if (n&7) dsp_add(sig_tilde_perform, 3, in, out, n); - else if(SIMD_CHECK1(n,out)) dsp_add(sig_tilde_perf_simd, 3, in, out, n); - else dsp_add(sig_tilde_perf8, 3, in, out, n); -} -static void sig_tilde_float(t_sig *x, t_float f) { - x->a = f; -} -static void sig_tilde_dsp(t_sig *x, t_signal **sp) { -/* dsp_add(sig_tilde_perform, 3, &x->a, sp[0]->v, sp[0]->n); */ - /* T.Grill - use chance of unrolling */ - dsp_add_scalarcopy(&x->a, sp[0]->v, sp[0]->n); -} -static void *sig_tilde_new(t_floatarg f) { - t_sig *x = (t_sig *)pd_new(sig_tilde_class); - x->a = f; - outlet_new(x, &s_signal); - return x; -} -static void sig_tilde_setup() { - sig_tilde_class = class_new2("sig~",sig_tilde_new,0,sizeof(t_sig),0,"F"); - class_addfloat(sig_tilde_class, sig_tilde_float); - class_addmethod2(sig_tilde_class, sig_tilde_dsp,"dsp",""); -} - -/* -------------------------- line~ ------------------------------ */ -static t_class *line_tilde_class; -struct t_line : t_object { - float target; - float value; - float biginc; - float inc; - float oneovern; - float dspticktomsec; - float inletvalue; - float inletwas; - int ticksleft; - int retarget; - float* slopes; /* tb: for simd-optimized line */ - float slopestep; /* tb: 4*x->inc */ -}; -static t_int *line_tilde_perform(t_int *w) { - PERFORM3ARGS(t_line *,x, t_float *,out, int,n); - float f = x->value; - if (PD_BIGORSMALL(f)) x->value = f = 0; - if (x->retarget) { - int nticks = (int)(x->inletwas * x->dspticktomsec); - if (!nticks) nticks = 1; - x->ticksleft = nticks; - x->biginc = (x->target - x->value)/(float)nticks; - x->inc = x->oneovern * x->biginc; - x->retarget = 0; - } - if (x->ticksleft) { - float f = x->value; - float slope = x->inc; /* tb: make sure, x->inc is loaded to a register */ - while (n--) *out++ = f, f += slope; - x->value += x->biginc; - x->ticksleft--; - } else { - float g = x->value = x->target; - while (n--) - *out++ = g; - } - return w+4; -} -/* tb: vectorized / simd version { */ -static void line_tilde_slope(t_float* out, t_int n, t_float* value, t_float* slopes, t_float* slopestep) { - t_float slope = slopes[1]; - t_float f = *value; - n>>=3; - while (n--) { - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - *out++ = f;f += slope; - } -} -static t_int *line_tilde_perf8(t_int *w) { - PERFORM3ARGS(t_line *,x, t_float *,out, int,n); - float f = x->value; - if (PD_BIGORSMALL(f)) x->value = f = 0; - if (x->retarget) { - int nticks = (int)(x->inletwas * x->dspticktomsec); - if (!nticks) nticks = 1; - x->ticksleft = nticks; - x->biginc = (x->target - x->value)/(float)nticks; - x->inc = x->oneovern * x->biginc; - x->retarget = 0; - /* tb: rethink!!! this is ugly */ - for (int i = 0; i != 4; ++i) x->slopes[i] = i*x->inc; - x->slopestep = 4 * x->inc; - } - if (x->ticksleft) { - line_tilde_slope(out, n, &x->value, x->slopes, &x->slopestep); - x->value += x->biginc; - x->ticksleft--; - } else { - float f = x->value = x->target; - setvec_8(out,f,n); - } - return w+4; -} -static t_int *line_tilde_perfsimd(t_int *w) { - PERFORM3ARGS(t_line *,x, t_float *,out, int,n); - float f = x->value; - if (PD_BIGORSMALL(f)) x->value = f = 0; - if (x->retarget) { - int nticks = (int)(x->inletwas * x->dspticktomsec); - if (!nticks) nticks = 1; - x->ticksleft = nticks; - x->biginc = (x->target - x->value)/(float)nticks; - x->inc = x->oneovern * x->biginc; - x->retarget = 0; - for (int i = 0; i != 4; ++i) x->slopes[i] = i*x->inc; - x->slopestep = 4 * x->inc; - } - if (x->ticksleft) { - line_tilde_slope_simd(out, n, &x->value, x->slopes, &x->slopestep); - x->value += x->biginc; - x->ticksleft--; - } else { - float f = x->value = x->target; - setvec_simd(out,f,n); - } - return w+4; -} -/* tb } */ -static void line_tilde_float(t_line *x, t_float f) { - if (x->inletvalue <= 0) { - x->target = x->value = f; - x->ticksleft = x->retarget = 0; - } else { - x->target = f; - x->retarget = 1; - x->inletwas = x->inletvalue; - x->inletvalue = 0; - } -} -static void line_tilde_stop(t_line *x) { - x->target = x->value; - x->ticksleft = x->retarget = 0; -} -static void line_tilde_dsp(t_line *x, t_signal **sp) { - if(sp[0]->n&7) dsp_add(line_tilde_perform, 3, x, sp[0]->v, sp[0]->n); - else if (SIMD_CHECK1(sp[0]->n,sp[0]->v)) dsp_add(line_tilde_perfsimd, 3, x, sp[0]->v, sp[0]->n); - else dsp_add(line_tilde_perf8, 3, x, sp[0]->v, sp[0]->n); - x->oneovern = 1./sp[0]->n; - x->dspticktomsec = sp[0]->sr / (1000 * sp[0]->n); -} -/* tb: modified for simd-optimized line~ */ -static void *line_tilde_new() { - t_line *x = (t_line *)pd_new(line_tilde_class); - outlet_new(x, &s_signal); - floatinlet_new(x, &x->inletvalue); - x->ticksleft = x->retarget = 0; - x->value = x->target = x->inletvalue = x->inletwas = 0; - x->slopes = (t_float *)getalignedbytes(4*sizeof(t_float)); - return x; -} - -static void line_tilde_free(t_line * x) { - freealignedbytes(x->slopes, 4*sizeof(t_float)); -} -static void line_tilde_setup() { - line_tilde_class = class_new2("line~",line_tilde_new,line_tilde_free,sizeof(t_line),0,""); - class_addfloat(line_tilde_class, line_tilde_float); - class_addmethod2(line_tilde_class, line_tilde_dsp, "dsp",""); - class_addmethod2(line_tilde_class, line_tilde_stop,"stop",""); -} - -/* -------------------------- vline~ ------------------------------ */ -static t_class *vline_tilde_class; -struct t_vseg { - double s_targettime; - double s_starttime; - float s_target; - t_vseg *s_next; -}; -struct t_vline : t_object { - double value; - double inc; - double referencetime; - double samppermsec; - double msecpersamp; - double targettime; - float target; - float inlet1; - float inlet2; - t_vseg *list; -}; -static t_int *vline_tilde_perform(t_int *w) { - PERFORM3ARGS(t_vline *,x, t_float *,out, int,n); - double f = x->value; - double inc = x->inc; - double msecpersamp = x->msecpersamp; - double timenow = clock_gettimesince(x->referencetime) - n * msecpersamp; - t_vseg *s = x->list; - for (int i=0; i<n; i++) { - double timenext = timenow + msecpersamp; - checknext: - if (s) { - /* has starttime elapsed? If so update value and increment */ - if (s->s_starttime < timenext) { - if (x->targettime <= timenext) - f = x->target, inc = 0; - /* if zero-length segment bash output value */ - if (s->s_targettime <= s->s_starttime) { - f = s->s_target; - inc = 0; - } else { - double incpermsec = (s->s_target - f)/ - (s->s_targettime - s->s_starttime); - f = f + incpermsec * (timenext - s->s_starttime); - inc = incpermsec * msecpersamp; - } - x->inc = inc; - x->target = s->s_target; - x->targettime = s->s_targettime; - x->list = s->s_next; - free(s); - s = x->list; - goto checknext; - } - } - if (x->targettime <= timenext) - f = x->target, inc = x->inc = 0, x->targettime = 1e20; - *out++ = f; - f = f + inc; - timenow = timenext; - } - x->value = f; - return w+4; -} -static void vline_tilde_stop(t_vline *x) { - t_vseg *s1, *s2; - for (s1 = x->list; s1; s1 = s2) - s2 = s1->s_next, free(s1); - x->list = 0; - x->inc = 0; - x->inlet1 = x->inlet2 = 0; - x->target = x->value; - x->targettime = 1e20; -} -static void vline_tilde_float(t_vline *x, t_float f) { - double timenow = clock_gettimesince(x->referencetime); - float inlet1 = (x->inlet1 < 0 ? 0 : x->inlet1); - float inlet2 = x->inlet2; - double starttime = timenow + inlet2; - t_vseg *s1, *s2, *deletefrom = 0, *snew; - if (PD_BIGORSMALL(f)) f = 0; - /* negative delay input means stop and jump immediately to new value */ - if (inlet2 < 0) { - x->value = f; - vline_tilde_stop(x); - return; - } - snew = (t_vseg *)t_getbytes(sizeof(*snew)); - /* check if we supplant the first item in the list. We supplant - an item by having an earlier starttime, or an equal starttime unless - the equal one was instantaneous and the new one isn't (in which case - we'll do a jump-and-slide starting at that time.) */ - if (!x->list || x->list->s_starttime > starttime || - (x->list->s_starttime == starttime && - (x->list->s_targettime > x->list->s_starttime || inlet1 <= 0))) { - deletefrom = x->list; - x->list = snew; - } else { - for (s1 = x->list; (s2 = s1->s_next); s1 = s2) { - if (s2->s_starttime > starttime || - (s2->s_starttime == starttime && - (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) { - deletefrom = s2; - s1->s_next = snew; - goto didit; - } - } - s1->s_next = snew; - deletefrom = 0; - didit: ; - } - while (deletefrom) { - s1 = deletefrom->s_next; - free(deletefrom); - deletefrom = s1; - } - snew->s_next = 0; - snew->s_target = f; - snew->s_starttime = starttime; - snew->s_targettime = starttime + inlet1; - x->inlet1 = x->inlet2 = 0; -} -static void vline_tilde_dsp(t_vline *x, t_signal **sp) { - dsp_add(vline_tilde_perform, 3, x, sp[0]->v, sp[0]->n); - x->samppermsec = ((double)(sp[0]->sr)) / 1000; - x->msecpersamp = ((double)1000) / sp[0]->sr; -} -static void *vline_tilde_new() { - t_vline *x = (t_vline *)pd_new(vline_tilde_class); - outlet_new(x, &s_signal); - floatinlet_new(x, &x->inlet1); - floatinlet_new(x, &x->inlet2); - x->inlet1 = x->inlet2 = 0; - x->value = x->inc = 0; - x->referencetime = clock_getlogicaltime(); - x->list = 0; - x->samppermsec = 0; - x->targettime = 1e20; - return x; -} -static void vline_tilde_setup() { - vline_tilde_class = class_new2("vline~",vline_tilde_new,vline_tilde_stop,sizeof(t_vline),0,""); - class_addfloat(vline_tilde_class, vline_tilde_float); - class_addmethod2(vline_tilde_class, vline_tilde_dsp, "dsp",""); - class_addmethod2(vline_tilde_class, vline_tilde_stop,"stop",""); -} - -/* -------------------------- snapshot~ ------------------------------ */ -static t_class *snapshot_tilde_class; -struct t_snapshot : t_object { - t_sample value; - float a; -}; -static void *snapshot_tilde_new() { - t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class); - x->value = 0; - outlet_new(x, &s_float); - x->a = 0; - return x; -} -static t_int *snapshot_tilde_perform(t_int *w) { - PERFORM2ARGS(t_float *,in, t_float *,out); - *out = *in; - return w+3; -} -static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp) { - dsp_add(snapshot_tilde_perform, 2, sp[0]->v + (sp[0]->n-1), &x->value); -} -static void snapshot_tilde_bang(t_snapshot *x) {x->outlet->send(x->value);} -static void snapshot_tilde_set(t_snapshot *x, t_floatarg f) {x->value = f;} -static void snapshot_tilde_setup() { - snapshot_tilde_class = class_new2("snapshot~",snapshot_tilde_new,0,sizeof(t_snapshot),0,""); - CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, a); - class_addmethod2(snapshot_tilde_class, snapshot_tilde_dsp, "dsp",""); - class_addmethod2(snapshot_tilde_class, snapshot_tilde_set, "set","s"); - class_addbang(snapshot_tilde_class, snapshot_tilde_bang); -} - -/* -------------------------- vsnapshot~ ------------------------------ */ -static t_class *vsnapshot_tilde_class; -struct t_vsnapshot : t_object { - int n; - int gotone; - t_sample *vec; - float a; - float sampspermsec; - double time; -}; -static void *vsnapshot_tilde_new() { - t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class); - outlet_new(x, &s_float); - x->a = 0; - x->n = 0; - x->vec = 0; - x->gotone = 0; - return x; -} -static t_int *vsnapshot_tilde_perform(t_int *w) { - PERFORM2ARGS(t_float *,in, t_vsnapshot *,x); - t_float *out = x->vec; - int n = x->n, i; - for (i = 0; i < n; i++) out[i] = in[i]; - x->time = clock_getlogicaltime(); - x->gotone = 1; - return w+3; -} -static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp) { - int n = sp[0]->n; - if (n != x->n) { - if (x->vec) free(x->vec); - x->vec = (t_sample *)getbytes(n * sizeof(t_sample)); - x->gotone = 0; - x->n = n; - } - x->sampspermsec = sp[0]->sr / 1000; - dsp_add(vsnapshot_tilde_perform, 2, sp[0]->v, x); -} -static void vsnapshot_tilde_bang(t_vsnapshot *x) { - float val; - if (x->gotone) { - int indx = clip((int)(clock_gettimesince(x->time) * x->sampspermsec),0,x->n-1); - val = x->vec[indx]; - } else val = 0; - x->outlet->send(val); -} -static void vsnapshot_tilde_ff(t_vsnapshot *x) { - if (x->vec) free(x->vec); -} -static void vsnapshot_tilde_setup() { - vsnapshot_tilde_class = - class_new2("vsnapshot~",vsnapshot_tilde_new, vsnapshot_tilde_ff,sizeof(t_vsnapshot), 0,""); - CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, a); - class_addmethod2(vsnapshot_tilde_class, vsnapshot_tilde_dsp, "dsp",""); - class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang); -} - -/* ---------------- env~ - simple envelope follower. ----------------- */ -#define MAXOVERLAP 10 -#define MAXVSTAKEN 64 -struct t_sigenv : t_object { - t_clock *clock; /* a "clock" object */ - float *buf; /* a Hanning window */ - int phase; /* number of points since last output */ - int period; /* requested period of output */ - int realperiod; /* period rounded up to vecsize multiple */ - int npoints; /* analysis window size in samples */ - float result; /* result to output */ - float sumbuf[MAXOVERLAP]; /* summing buffer */ - float a; -}; -t_class *env_tilde_class; -static void env_tilde_tick(t_sigenv *x); -static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod) { - int npoints = (int)fnpoints; - int period = (int)fperiod; - float *buf; - if (npoints < 1) npoints = 1024; - if (period < 1) period = npoints/2; - if (period < npoints / MAXOVERLAP + 1) - period = npoints / MAXOVERLAP + 1; - if (!(buf = (float *)getalignedbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) { - error("env: couldn't allocate buffer"); - return 0; - } - t_sigenv *x = (t_sigenv *)pd_new(env_tilde_class); - x->buf = buf; - x->npoints = npoints; - x->phase = 0; - x->period = period; - int i; - for (i = 0; i < MAXOVERLAP; i++) x->sumbuf[i] = 0; - for (i = 0; i < npoints; i++) buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints; - for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; - x->clock = clock_new(x, env_tilde_tick); - x->outlet = outlet_new(x, &s_float); - x->a = 0; - return x; -} -static t_int *env_tilde_perform(t_int *w) { - PERFORM3ARGS(t_sigenv *,x, t_float *,in, int,n); - float *sump = x->sumbuf; - in += n; - for (int count = x->phase; count < x->npoints; count += x->realperiod, sump++) { - float *hp = x->buf + count; - float *fp = in; - float sum = *sump; - for (int i = 0; i < n; i++) { - fp--; - sum += *hp++ * (*fp * *fp); - } - *sump = sum; - } - sump[0] = 0; - x->phase -= n; - if (x->phase < 0) { - x->result = x->sumbuf[0]; - sump = x->sumbuf; - for (int count = x->realperiod; count < x->npoints; count += x->realperiod, sump++) sump[0] = sump[1]; - sump[0] = 0; - x->phase = x->realperiod - n; - clock_delay(x->clock, 0L); - } - return w+4; -} -/* tb: loop unrolling and simd */ -static float env_tilde_accum_8(t_float* in, t_float* hp, t_int n) { - float ret = 0; - n>>=3; - for (int i = 0; i !=n; ++i) { - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - in--; ret += *hp++ * (*in * *in); - } - return ret; -} -static t_int *env_tilde_perf8(t_int *w) { - PERFORM3ARGS(t_sigenv *,x, t_float *,in, int,n); - float *sump = x->sumbuf; - in += n; - for (int count = x->phase; count < x->npoints; count += x->realperiod, sump++) { - *sump += env_tilde_accum_8(in, x->buf + count, n); - } - sump[0] = 0; - x->phase -= n; - if (x->phase < 0) { - x->result = x->sumbuf[0]; - float *sump = x->sumbuf; - for (int count = x->realperiod; count < x->npoints; count += x->realperiod, sump++) sump[0] = sump[1]; - sump[0] = 0; - x->phase = x->realperiod - n; - clock_delay(x->clock, 0L); - } - return w+4; -} -static t_int *env_tilde_perf_simd(t_int *w) { - PERFORM3ARGS(t_sigenv *,x, t_float *,in, int,n); - float *sump = x->sumbuf; - in += n; - for (int count = x->phase; count < x->npoints; count += x->realperiod, sump++) { - *sump += env_tilde_accum_simd(in, x->buf + count, n); - } - sump[0] = 0; - x->phase -= n; - if (x->phase < 0) { - x->result = x->sumbuf[0]; - float *sump = x->sumbuf; - for (int count = x->realperiod; count < x->npoints; count += x->realperiod, sump++) sump[0] = sump[1]; - sump[0] = 0; - x->phase = x->realperiod - n; - clock_delay(x->clock, 0L); - } - return w+4; -} -static void env_tilde_dsp(t_sigenv *x, t_signal **sp) { - int mod = x->period % sp[0]->n; - if (mod) x->realperiod = x->period + sp[0]->n - mod; else x->realperiod = x->period; - if (sp[0]->n & 7) - dsp_add(env_tilde_perform, 3, x, sp[0]->v, sp[0]->n); - else if (SIMD_CHECK1(sp[0]->n, sp[0]->v)) - dsp_add(env_tilde_perf_simd, 3, x, sp[0]->v, sp[0]->n); - else dsp_add(env_tilde_perf8, 3, x, sp[0]->v, sp[0]->n); - if (sp[0]->n > MAXVSTAKEN) bug("env_tilde_dsp"); -} -static void env_tilde_tick(t_sigenv *x) {x->outlet->send(powtodb(x->result));} -static void env_tilde_ff(t_sigenv *x) { - clock_free(x->clock); - freealignedbytes(x->buf, (x->npoints + MAXVSTAKEN) * sizeof(float)); -} -void env_tilde_setup() { - env_tilde_class = class_new2("env~",env_tilde_new,env_tilde_ff,sizeof(t_sigenv),0,"FF"); - CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, a); - class_addmethod2(env_tilde_class, env_tilde_dsp, "dsp",""); -} - -/* --------------------- threshold~ ----------------------------- */ -static t_class *threshold_tilde_class; -struct t_threshold_tilde : t_object { - t_clock *clock; /* wakeup for message output */ - float a; /* scalar inlet */ - int state; /* 1 = high, 0 = low */ - float hithresh; /* value of high threshold */ - float lothresh; /* value of low threshold */ - float deadwait; /* msec remaining in dead period */ - float msecpertick; /* msec per DSP tick */ - float hideadtime; /* hi dead time in msec */ - float lodeadtime; /* lo dead time in msec */ -}; -static void threshold_tilde_tick(t_threshold_tilde *x); -/* "set" message to specify thresholds and dead times */ -static void threshold_tilde_set(t_threshold_tilde *x, - t_floatarg hithresh, t_floatarg hideadtime, - t_floatarg lothresh, t_floatarg lodeadtime) { - if (lothresh > hithresh) lothresh = hithresh; - x->hithresh = hithresh; x->hideadtime = hideadtime; - x->lothresh = lothresh; x->lodeadtime = lodeadtime; -} -static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh, - t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime) { - t_threshold_tilde *x = (t_threshold_tilde *)pd_new(threshold_tilde_class); - x->state = 0; /* low state */ - x->deadwait = 0; /* no dead time */ - x->clock = clock_new(x, threshold_tilde_tick); - outlet_new(x, &s_bang); - outlet_new(x, &s_bang); - inlet_new(x, x, &s_float, gensym("ft1")); - x->msecpertick = 0.; - x->a = 0; - threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime); - return x; -} -/* number in inlet sets state -- note incompatible with JMAX which used - "int" message for this, impossible here because of auto signal conversion */ -static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f) { - x->state = (f != 0); - x->deadwait = 0; -} -static void threshold_tilde_tick(t_threshold_tilde *x) {x->out(!x->state)->send();} -static t_int *threshold_tilde_perform(t_int *w) { - PERFORM3ARGS(float *,in1, t_threshold_tilde *,x, int,n); - if (x->deadwait > 0) - x->deadwait -= x->msecpertick; - else if (x->state) { - /* we're high; look for low sample */ - for (; n--; in1++) { - if (*in1 < x->lothresh) { - clock_delay(x->clock, 0L); - x->state = 0; - x->deadwait = x->lodeadtime; - goto done; - } - } - } else { - /* we're low; look for high sample */ - for (; n--; in1++) { - if (*in1 >= x->hithresh) { - clock_delay(x->clock, 0L); - x->state = 1; - x->deadwait = x->hideadtime; - goto done; - } - } - } -done: - return w+4; -} -void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp) { - x->msecpertick = 1000. * sp[0]->n / sp[0]->sr; - dsp_add(threshold_tilde_perform, 3, sp[0]->v, x, sp[0]->n); -} -static void threshold_tilde_ff(t_threshold_tilde *x) {clock_free(x->clock);} -static void threshold_tilde_setup() { - t_class *c = threshold_tilde_class = - class_new2("threshold~",threshold_tilde_new,threshold_tilde_ff,sizeof(t_threshold_tilde), 0, "FFFF"); - CLASS_MAINSIGNALIN(c, t_threshold_tilde, a); - class_addmethod2(c, threshold_tilde_set, "set","ffff"); - class_addmethod2(c, threshold_tilde_ft1, "ft1","f"); - class_addmethod2(c, threshold_tilde_dsp, "dsp",""); -} - -/* ----------------------------- dac~ --------------------------- */ -static t_class *dac_class; -struct t_dac : t_object { - t_int n; - t_int *vec; - float a; -}; -static void *dac_new(t_symbol *s, int argc, t_atom *argv) { - t_dac *x = (t_dac *)pd_new(dac_class); - t_atom defarg[2]; - if (!argc) { - argv = defarg; - argc = 2; - SETFLOAT(&defarg[0], 1); - SETFLOAT(&defarg[1], 2); - } - x->n = argc; - x->vec = (t_int *)getbytes(argc * sizeof(*x->vec)); - for (int i = 0; i < argc; i++) x->vec[i] = atom_getintarg(i, argc, argv); - for (int i = 1; i < argc; i++) inlet_new(x, x, &s_signal, &s_signal); - x->a = 0; - return x; -} -static void dac_dsp(t_dac *x, t_signal **sp) { - t_int i, *ip; - t_signal **sp2; - for (i = x->n, ip = x->vec, sp2 = sp; i--; ip++, sp2++) { - int ch = *ip - 1; - if ((*sp2)->n != sys_dacblocksize) error("dac~: bad vector size"); - else if (ch >= 0 && ch < sys_get_outchannels()) { - if(SIMD_CHECK3(sys_dacblocksize,sys_soundout + sys_dacblocksize*ch, (*sp2)->v,sys_soundout + sys_dacblocksize*ch)) - dsp_add(plus_perf_simd, 4, sys_soundout + sys_dacblocksize*ch, - (*sp2)->v, sys_soundout + sys_dacblocksize*ch, sys_dacblocksize); - else - dsp_add(plus_perform, 4, sys_soundout + sys_dacblocksize*ch, (*sp2)->v, sys_soundout + sys_dacblocksize*ch, - sys_dacblocksize); - } - } -} -static void dac_free(t_dac *x) {free(x->vec);} -static void dac_setup() { - dac_class = class_new2("dac~",dac_new,dac_free,sizeof(t_dac),0,"*"); - CLASS_MAINSIGNALIN(dac_class, t_dac, a); - class_addmethod2(dac_class, dac_dsp, "dsp","!"); - class_sethelpsymbol(dac_class, gensym("adc~_dac~")); -} - -/* ----------------------------- adc~ --------------------------- */ -static t_class *adc_class; -struct t_adc : t_object { - t_int n; - t_int *vec; -}; -static void *adc_new(t_symbol *s, int argc, t_atom *argv) { - t_adc *x = (t_adc *)pd_new(adc_class); - t_atom defarg[2]; - if (!argc) { - argv = defarg; - argc = 2; - SETFLOAT(&defarg[0], 1); - SETFLOAT(&defarg[1], 2); - } - x->n = argc; - x->vec = (t_int *)getbytes(argc * sizeof(*x->vec)); - for (int i = 0; i < argc; i++) x->vec[i] = atom_getintarg(i, argc, argv); - for (int i = 0; i < argc; i++) outlet_new(x, &s_signal); - return x; -} -t_int *copy_perform(t_int *w) { - PERFORM3ARGS(t_float *,in1, t_float *,out, int,n); - while (n--) *out++ = *in1++; - return w+4; -} -t_int *copy_perf8(t_int *w) { - PERFORM3ARGS(t_float *,in1, t_float *,out, int,n); - for (; n; n -= 8, in1 += 8, out += 8) { - out[0] = in1[0]; - out[1] = in1[1]; - out[2] = in1[2]; - out[3] = in1[3]; - out[4] = in1[4]; - out[5] = in1[5]; - out[6] = in1[6]; - out[7] = in1[7]; - } - return w+4; -} -void dsp_add_copy(t_sample *in, t_sample *out, int n) { - if (n&7) dsp_add(copy_perform, 3, in, out, n); - else if (SIMD_CHECK2(n,in,out)) dsp_add(copy_perf_simd, 3, in, out, n); - else dsp_add(copy_perf8, 3, in, out, n); -} -static void adc_dsp(t_adc *x, t_signal **sp) { - t_int i, *ip; - t_signal **sp2; - for (i = x->n, ip = x->vec, sp2 = sp; i--; ip++, sp2++) { - int ch = *ip - 1; - if ((*sp2)->n != sys_dacblocksize) - error("adc~: bad vector size"); - else if (ch >= 0 && ch < sys_get_inchannels()) - dsp_add_copy(sys_soundin + sys_dacblocksize*ch, (*sp2)->v, sys_dacblocksize); - else dsp_add_zero((*sp2)->v, sys_dacblocksize); - } -} -static void adc_free(t_adc *x) {free(x->vec);} -static void adc_setup() { - adc_class = class_new2("adc~",adc_new,adc_free,sizeof(t_adc),0,"*"); - class_addmethod2(adc_class, adc_dsp, "dsp","!"); - class_sethelpsymbol(adc_class, gensym("adc~_dac~")); -} - -/* ----------------------------- delwrite~ ----------------------------- */ -static t_class *sigdelwrite_class; -struct t_delwritectl { - int c_n; - float *c_vec; - int c_phase; -}; -struct t_sigdelwrite : t_object { - t_symbol *sym; - t_delwritectl cspace; - int sortno; /* DSP sort number at which this was last put on chain */ - int rsortno; /* DSP sort # for first delread or write in chain */ - int vecsize; /* vector size for delread~ to use */ - float a; -}; -#define XTRASAMPS 4 -#define SAMPBLK 4 -/* routine to check that all delwrites/delreads/vds have same vecsize */ -static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize) { - if (x->rsortno != ugen_getsortno()) { - x->vecsize = vecsize; - x->rsortno = ugen_getsortno(); - } - /* LATER this should really check sample rate and blocking, once that is supported. - Probably we don't actually care about vecsize. For now just suppress this check. */ -#if 0 - else if (vecsize != x->vecsize) error("delread/delwrite/vd vector size mismatch"); -#endif -} -static void *sigdelwrite_new(t_symbol *s, t_floatarg msec) { - t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class); - if (!*s->name) s = gensym("delwrite~"); - pd_bind(x, s); - x->sym = s; - int nsamps = (int)(msec * sys_getsr() * (float)(0.001f)); - if (nsamps < 1) nsamps = 1; - nsamps += ((- nsamps) & (SAMPBLK - 1)); - nsamps += DEFDELVS; -#ifdef SIMD_BYTEALIGN - nsamps += (SIMD_BYTEALIGN - nsamps) % SIMD_BYTEALIGN; /* tb: for simd */ -#endif - x->cspace.c_n = nsamps; - x->cspace.c_vec = (float *)getalignedbytes((nsamps + XTRASAMPS) * sizeof(float)); - x->cspace.c_phase = XTRASAMPS; - x->sortno = 0; - x->vecsize = 0; - x->a = 0; - return x; -} -static t_int *sigdelwrite_perform(t_int *w) { - PERFORM3ARGS(t_float *,in, t_delwritectl *,c, int,n); - int phase = c->c_phase, nsamps = c->c_n; - float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS); - phase += n; - while (n--) { - float f = *in++; - if (PD_BIGORSMALL(f)) - f = 0; - *bp++ = f; - if (bp == ep) { - vp[0] = ep[-4]; - vp[1] = ep[-3]; - vp[2] = ep[-2]; - vp[3] = ep[-1]; - bp = vp + XTRASAMPS; - phase -= nsamps; - } - } - c->c_phase = phase; - return w+4; -} -static t_int *sigdelwrite_perf8(t_int *w) { - PERFORM3ARGS(t_float *,in, t_delwritectl *,c, int,n); - int phase = c->c_phase, nsamps = c->c_n; - float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS); - phase += n; - if (phase > nsamps) - while (n--) { - float f = *in++; - if (PD_BIGORSMALL(f)) f = 0; - *bp++ = f; - if (bp == ep) { - vp[0] = ep[-4]; - vp[1] = ep[-3]; - vp[2] = ep[-2]; - vp[3] = ep[-1]; - bp = vp + XTRASAMPS; - phase -= nsamps; - } - } - else testcopyvec_8(bp, in, n); - c->c_phase = phase; - return w+4; -} -static t_int *sigdelwrite_perfsimd(t_int *w) { - PERFORM3ARGS(t_float *,in, t_delwritectl *,c, int,n); - int phase = c->c_phase, nsamps = c->c_n; - float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS); - phase += n; - if (phase > nsamps ) - while (n--) { - float f = *in++; - if (PD_BIGORSMALL(f)) f = 0; - *bp++ = f; - if (bp == ep) { - vp[0] = ep[-4]; - vp[1] = ep[-3]; - vp[2] = ep[-2]; - vp[3] = ep[-1]; - bp = vp + XTRASAMPS; - phase -= nsamps; - } - } - else testcopyvec_simd(bp, in, n); - c->c_phase = phase; - return w+4; -} -static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp) { - if (sp[0]->n & 7) dsp_add(sigdelwrite_perform, 3, sp[0]->v, &x->cspace, sp[0]->n); - else if (SIMD_CHECK1(sp[0]->n, sp[0]->v)) dsp_add(sigdelwrite_perfsimd, 3, sp[0]->v, &x->cspace, sp[0]->n); - else dsp_add(sigdelwrite_perf8, 3, sp[0]->v, &x->cspace, sp[0]->n); - x->sortno = ugen_getsortno(); - sigdelwrite_checkvecsize(x, sp[0]->n); -} -static void sigdelwrite_free(t_sigdelwrite *x) { - pd_unbind(x, x->sym); - freealignedbytes(x->cspace.c_vec, (x->cspace.c_n + XTRASAMPS) * sizeof(float)); -} -static void sigdelwrite_setup() { - sigdelwrite_class = class_new2("delwrite~",sigdelwrite_new,sigdelwrite_free,sizeof(t_sigdelwrite),0,"SF"); - CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, a); - class_addmethod2(sigdelwrite_class, sigdelwrite_dsp,"dsp",""); -} - -/* ----------------------------- delread~ ----------------------------- */ -static t_class *sigdelread_class; -struct t_sigdelread : t_object { - t_symbol *sym; - t_float deltime; /* delay in msec */ - int delsamps; /* delay in samples */ - t_float sr; /* samples per msec */ - t_float n; /* vector size */ - int zerodel; /* 0 or vecsize depending on read/write order */ - void (*copy_fp)(t_float*, const t_float*, int); /* tb: copy function */ -}; -static void sigdelread_float(t_sigdelread *x, t_float f); -static void *sigdelread_new(t_symbol *s, t_floatarg f) { - t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class); - x->sym = s; - x->sr = 1; - x->n = 1; - x->zerodel = 0; - sigdelread_float(x, f); - outlet_new(x, &s_signal); - return x; -} -static void sigdelread_float(t_sigdelread *x, t_float f) { - t_sigdelwrite *delwriter = (t_sigdelwrite *)pd_findbyclass(x->sym, sigdelwrite_class); - x->deltime = f; - if (delwriter) { - x->delsamps = (int)(0.5 + x->sr * x->deltime + x->n - x->zerodel); - if (x->delsamps < x->n) x->delsamps = (int)x->n; - else if (x->delsamps > delwriter->cspace.c_n - DEFDELVS) - x->delsamps = (int)(delwriter->cspace.c_n - DEFDELVS); - } - if (SIMD_CHKCNT(x->delsamps)) x->copy_fp = copyvec_simd; - else x->copy_fp = copyvec_simd_unalignedsrc; -} -static t_int *sigdelread_perform(t_int *w) { - PERFORM4ARGS(t_float *,out, t_delwritectl *,c, int *,delsampsp, int,n); - int delsamps = *delsampsp; - int phase = c->c_phase - delsamps, nsamps = c->c_n; - float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS); - if (phase < 0) phase += nsamps; - bp = vp + phase; - while (n--) { - *out++ = *bp++; - if (bp == ep) bp -= nsamps; - } - return w+5; -} -static t_int *sigdelread_perf8(t_int *w) { - PERFORM4ARGS(t_float *,out, t_delwritectl *,c, int *,delsampsp, int,n); - int delsamps = *delsampsp; - int phase = c->c_phase - delsamps, nsamps = c->c_n; - float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS); - if (phase < 0) phase += nsamps; - bp = vp + phase; - if (phase + n > nsamps) - while (n--) { - *out++ = *bp++; - if (bp == ep) bp -= nsamps; - } - else copyvec_8(out, bp, n); - return w+5; -} -static t_int *sigdelread_perfsimd(t_int *w) { - PERFORM5ARGS(t_float *,out, t_delwritectl *,c, int *,delsampsp, int,n, t_sigdelread *,x); - int delsamps = *delsampsp; - int phase = c->c_phase - delsamps, nsamps = c->c_n; - float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS); - if (phase < 0) phase += nsamps; - bp = vp + phase; - if (phase + n > nsamps) while (n--) {*out++ = *bp++; if (bp == ep) bp -= nsamps;} - else x->copy_fp(out, bp, n); - return w+6; -} -static void sigdelread_dsp(t_sigdelread *x, t_signal **sp) { - t_sigdelwrite *delwriter = (t_sigdelwrite *)pd_findbyclass(x->sym, sigdelwrite_class); - x->sr = sp[0]->sr * 0.001; - x->n = sp[0]->n; - if (delwriter) { - sigdelwrite_checkvecsize(delwriter, sp[0]->n); - x->zerodel = (delwriter->sortno == ugen_getsortno() ? - 0 : delwriter->vecsize); - sigdelread_float(x, x->deltime); - if (sp[0]->n & 7) - dsp_add(sigdelread_perform, 4, sp[0]->v, &delwriter->cspace, &x->delsamps, sp[0]->n); - else if (SIMD_CHECK1(sp[0]->n, sp[0]->v)) - dsp_add(sigdelread_perfsimd, 5, sp[0]->v, &delwriter->cspace, &x->delsamps, sp[0]->n, x); - else dsp_add(sigdelread_perf8, 4, sp[0]->v, &delwriter->cspace, &x->delsamps, sp[0]->n); - } else if (*x->sym->name) error("delread~: %s: no such delwrite~",x->sym->name); -} -static void sigdelread_setup() { - sigdelread_class = class_new2("delread~",sigdelread_new,0,sizeof(t_sigdelread),0,"SF"); - class_addmethod2(sigdelread_class, sigdelread_dsp,"dsp",""); - class_addfloat(sigdelread_class, sigdelread_float); -} - -/* ----------------------------- vd~ ----------------------------- */ -static t_class *sigvd_class; -struct t_sigvd : t_object { - t_symbol *sym; - t_float sr; /* samples per msec */ - int zerodel; /* 0 or vecsize depending on read/write order */ - float a; -}; -static void *sigvd_new(t_symbol *s) { - t_sigvd *x = (t_sigvd *)pd_new(sigvd_class); - if (!*s->name) s = gensym("vd~"); - x->sym = s; - x->sr = 1; - x->zerodel = 0; - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static t_int *sigvd_perform(t_int *w) { - PERFORM5ARGS(t_float *,in, t_float *,out, t_delwritectl *,ctl, t_sigvd *,x, int,n); - int nsamps = ctl->c_n; - float limit = nsamps - n - 1; - float fn = n-1; - float *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase; - float zerodel = x->zerodel; - while (n--) { - float delsamps = x->sr * *in++ - zerodel, frac; - int idelsamps; - float a, b, c, d, cminusb; - if (delsamps < 1.00001f) delsamps = 1.00001f; - if (delsamps > limit) delsamps = limit; - delsamps += fn; - fn = fn - 1.0f; - idelsamps = (int)delsamps; - frac = delsamps - (float)idelsamps; - bp = wp - idelsamps; - if (bp < vp + 4) bp += nsamps; - d = bp[-3]; - c = bp[-2]; - b = bp[-1]; - a = bp[0]; - cminusb = c-b; - *out++ = b + frac * ( - cminusb - 0.1666667f * (1.-frac) * ( - (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b) - ) - ); - } - return w+6; -} -static void sigvd_dsp(t_sigvd *x, t_signal **sp) { - t_sigdelwrite *delwriter = (t_sigdelwrite *)pd_findbyclass(x->sym, sigdelwrite_class); - x->sr = sp[0]->sr * 0.001; - if (delwriter) { - sigdelwrite_checkvecsize(delwriter, sp[0]->n); - x->zerodel = (delwriter->sortno == ugen_getsortno() ? 0 : delwriter->vecsize); - dsp_add(sigvd_perform, 5, sp[0]->v, sp[1]->v, &delwriter->cspace, x, sp[0]->n); - } else error("vd~: %s: no such delwrite~",x->sym->name); -} -static void sigvd_setup() { - sigvd_class = class_new2("vd~",sigvd_new,0,sizeof(t_sigvd),0,"S"); - class_addmethod2(sigvd_class, sigvd_dsp, "dsp",""); - CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, a); -} - -#ifndef HAVE_LIBFFTW3F -/* ------------------------ fft~ and ifft~ -------------------------------- */ -/* ----------------------- rfft~ -------------------------------- */ -/* ----------------------- rifft~ -------------------------------- */ -static t_class *sigfft_class; struct t_sigfft : t_object {float a;}; -static t_class *sigifft_class; struct t_sigifft : t_object {float a;}; -static t_class *sigrfft_class; struct t_sigrfft : t_object {float a;}; -static t_class *sigrifft_class; struct t_sigrifft : t_object {float a;}; - -static void *sigfft_new() { - t_sigfft *x = (t_sigfft *)pd_new(sigfft_class); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - inlet_new(x, x, &s_signal, &s_signal); x->a=0; return x;} -static void *sigifft_new() { - t_sigifft *x = (t_sigifft *)pd_new(sigifft_class); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - inlet_new(x, x, &s_signal, &s_signal); x->a=0; return x;} -static void *sigrfft_new() { - t_sigrfft *x = (t_sigrfft *)pd_new(sigrfft_class); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->a = 0; return x;} -static void *sigrifft_new() { - t_sigrifft *x = (t_sigrifft *)pd_new(sigrifft_class); - inlet_new(x, x, &s_signal, &s_signal); - outlet_new(x, &s_signal); - x->a = 0; return x;} - -static t_int *sigfft_swap(t_int *w) { - PERFORM3ARGS(float *,in1, float *,in2, int,n); - for (;n--; in1++, in2++) { - float f = *in1; - *in1 = *in2; - *in2 = f; - } - return w+4; -} -static t_int * sigfft_perform(t_int *w) {float *in1=(t_float *)w[1], *in2=(t_float *)w[2]; int n=w[3]; mayer_fft(n,in1,in2); return w+4;} -static t_int * sigifft_perform(t_int *w) {float *in1=(t_float *)w[1], *in2=(t_float *)w[2]; int n=w[3]; mayer_ifft(n,in1,in2); return w+4;} -static t_int * sigrfft_perform(t_int *w) {float *in =(t_float *)w[1]; int n = w[2]; mayer_realfft(n, in); return w+3;} -static t_int *sigrifft_perform(t_int *w) {float *in =(t_float *)w[1]; int n = w[2]; mayer_realifft(n, in); return w+3;} - -static void sigfft_dspx(t_sigfft *x, t_signal **sp, t_int *(*f)(t_int *w)) { - int n = sp[0]->n; - float *in1 = sp[0]->v; - float *in2 = sp[1]->v; - float *out1 = sp[2]->v; - float *out2 = sp[3]->v; - if (out1 == in2 && out2 == in1) - dsp_add(sigfft_swap, 3, out1, out2, n); - else if (out1 == in2) { - dsp_add(copy_perform, 3, in2, out2, n); - dsp_add(copy_perform, 3, in1, out1, n); - } else { - if (out1 != in1) dsp_add(copy_perform, 3, in1, out1, n); - if (out2 != in2) dsp_add(copy_perform, 3, in2, out2, n); - } - dsp_add(f, 3, sp[2]->v, sp[3]->v, n); -} -static void sigfft_dsp(t_sigfft *x, t_signal **sp) {sigfft_dspx(x, sp, sigfft_perform);} -static void sigifft_dsp(t_sigfft *x, t_signal **sp) {sigfft_dspx(x, sp, sigifft_perform);} - -static t_int *sigrfft_flip(t_int *w) { - PERFORM3ARGS(float *,in, float *,out, int,n); - while (n--) *(--out) = *in++; - *(--out) = 0; /* to hell with it */ - return w+4; -} -static void sigrfft_dsp(t_sigrfft *x, t_signal **sp) { - int n = sp[0]->n, n2 = (n>>1); - float *in1 = sp[0]->v; - float *out1 = sp[1]->v; - float *out2 = sp[2]->v; - if (n < 4) { - error("fft: minimum 4 points"); - return; - } - /* this probably never happens */ - if (in1 == out2) { - dsp_add(sigrfft_perform, 2, out2, n); - dsp_add(copy_perform, 3, out2, out1, n2); - dsp_add(sigrfft_flip, 3, out2 + (n2+1), out2 + n2, n2-1); - } else { - if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n); - dsp_add(sigrfft_perform, 2, out1, n); - dsp_add(sigrfft_flip, 3, out1 + (n2+1), out2 + n2, n2-1); - } - dsp_add_zero(out1 + n2, n2); - dsp_add_zero(out2 + n2, n2); -} - -static void sigrifft_dsp(t_sigrifft *x, t_signal **sp) { - int n = sp[0]->n, n2 = (n>>1); - float *in1 = sp[0]->v; - float *in2 = sp[1]->v; - float *out1 = sp[2]->v; - if (n < 4) {error("fft: minimum 4 points"); return;} - if (in2 == out1) { - dsp_add(sigrfft_flip, 3, out1+1, out1 + n, (n2-1)); - dsp_add(copy_perform, 3, in1, out1, n2); - } else { - if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2); - dsp_add(sigrfft_flip, 3, in2+1, out1 + n, n2-1); - } - dsp_add(sigrifft_perform, 2, out1, n); -} -static void sigfft_setup() { - sigfft_class = class_new2("fft~", sigfft_new, 0,sizeof(t_sigfft), 0,""); - sigifft_class = class_new2("ifft~", sigifft_new, 0,sizeof(t_sigfft), 0,""); - sigrfft_class = class_new2("rfft~", sigrfft_new, 0,sizeof(t_sigrfft), 0,""); - sigrifft_class = class_new2("rifft~",sigrifft_new,0,sizeof(t_sigrifft),0,""); - CLASS_MAINSIGNALIN(sigfft_class, t_sigfft, a); - CLASS_MAINSIGNALIN(sigifft_class, t_sigfft, a); - CLASS_MAINSIGNALIN(sigrfft_class, t_sigrfft, a); - CLASS_MAINSIGNALIN(sigrifft_class,t_sigrifft,a); - class_addmethod2(sigfft_class, sigfft_dsp, "dsp",""); - class_addmethod2(sigifft_class, sigifft_dsp, "dsp",""); - class_addmethod2(sigrfft_class, sigrfft_dsp, "dsp",""); - class_addmethod2(sigrifft_class,sigrifft_dsp,"dsp",""); - class_sethelpsymbol(sigifft_class, gensym("fft~")); - class_sethelpsymbol(sigrfft_class, gensym("fft~")); - class_sethelpsymbol(sigrifft_class,gensym("fft~")); -} - -#else -/* Support for fftw3 by Tim Blechmann */ -/* ------------------------ fft~ and ifft~ -------------------------------- */ -/* ----------------------- rfft~ --------------------------------- */ -/* ----------------------- rifft~ -------------------------------- */ - -static t_class *sigfftw_class; struct t_sigfftw : t_object {float a; fftwf_plan plan; fftwf_iodim dim;}; -static t_class *sigifftw_class; struct t_sigifftw : t_object {float a; fftwf_plan plan; fftwf_iodim dim;}; -static t_class *sigrfftw_class; struct t_sigrfftw : t_object {float a; fftwf_plan plan; fftwf_iodim dim;}; -static t_class *sigrifftw_class;struct t_sigrifftw : t_object {float a; fftwf_plan plan; fftwf_iodim dim;}; - -static void *sigfftw_new() { - t_sigfftw *x = (t_sigfftw *)pd_new(sigfftw_class); outlet_new(x, &s_signal); outlet_new(x, &s_signal); - inlet_new(x, x, &s_signal, &s_signal); x->a=0; return x;} -static void *sigifftw_new() { - t_sigifftw *x = (t_sigifftw *)pd_new(sigfftw_class); outlet_new(x, &s_signal); outlet_new(x, &s_signal); - inlet_new(x, x, &s_signal, &s_signal); x->a=0; return x;} -static void *sigrfftw_new() { - t_sigrfftw *x = (t_sigrfftw *)pd_new(sigrfftw_class); - outlet_new(x, &s_signal); outlet_new(x, &s_signal); x->a=0; return x;} -static void *sigrifftw_new() { - t_sigrifftw *x = (t_sigrifftw *)pd_new(sigrifftw_class); - inlet_new(x, x, &s_signal, &s_signal); - outlet_new(x, &s_signal); x->a=0; return x;} - -static void sigfftw_free( t_sigfftw *x) {fftwf_destroy_plan(x->plan);} -static void sigifftw_free( t_sigifftw *x) {fftwf_destroy_plan(x->plan);} -static void sigrfftw_free( t_sigrfftw *x) {fftwf_destroy_plan(x->plan);} -static void sigrifftw_free(t_sigrifftw *x) {fftwf_destroy_plan(x->plan);} - -/* for compatibility reasons with the mayer fft, we'll have to invert some samples. this is ugly, but someone might rely on that. */ -static void sigrfftw_invert(t_sample * s, t_int n) { - while (n!=0) {--n; s[n]=-s[n];} -} -static t_int *sigfftw_perform(t_int *w) { - fftwf_execute(*(fftwf_plan *)w[1]); - return w+2; -} -static t_int *sigrfftw_perform(t_int *w) { - fftwf_execute(*(fftwf_plan*)w[1]); - sigrfftw_invert((t_sample*)w[2],(t_int)w[3]); - return w+4; -} -static t_int *sigrifftw_perform(t_int *w) { - sigrfftw_invert((t_sample *)w[2],w[3]); - fftwf_execute(*(fftwf_plan*)w[1]); - return w+4; -} - -static void sigfftw_dsp(t_sigfftw *x, t_signal **sp) { - int n = sp[0]->n; - float *in1 = sp[0]->v; - float *in2 = sp[1]->v; - float *out1 = sp[2]->v; - float *out2 = sp[3]->v; - x->dim.n=n; - x->dim.is=1; - x->dim.os=1; - x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, in1, in2, out1, out2, FFTW_ESTIMATE); - dsp_add(sigfftw_perform, 1, &x->plan); -} -static void sigifftw_dsp(t_sigfftw *x, t_signal **sp) { - int n = sp[0]->n; - float *in1 = sp[0]->v; - float *in2 = sp[1]->v; - float *out1 = sp[2]->v; - float *out2 = sp[3]->v; - x->dim.n=n; - x->dim.is=1; - x->dim.os=1; - x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, in2, in1, out2, out1, FFTW_ESTIMATE); - dsp_add(sigfftw_perform, 1, &x->plan); -} - -static void sigrfftw_dsp(t_sigrfftw *x, t_signal **sp) { - int n = sp[0]->n, n2 = (n>>1); - float *in = sp[0]->v; - float *out1 = sp[1]->v; - float *out2 = sp[2]->v; - if (n < 4) {error("fft: minimum 4 points"); return;} - x->dim.n=n; - x->dim.is=1; - x->dim.os=1; - x->plan = fftwf_plan_guru_split_dft_r2c(1, &(x->dim), 0, NULL, in, out1, out2, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT); - dsp_add(sigrfftw_perform,3,&x->plan,out2+1,n2-1); - dsp_add_zero(out1 + n2, n2); - dsp_add_zero(out2 + n2, n2); -} - -static void sigrifftw_dsp(t_sigrifftw *x, t_signal **sp) { - int n = sp[0]->n, n2 = (n>>1); - float *in1 = sp[0]->v; - float *in2 = sp[1]->v; - float *out = sp[2]->v; - if (n < 4) {error("fft: minimum 4 points"); return;} - x->dim.n=n; - x->dim.is=1; - x->dim.os=1; - x->plan = fftwf_plan_guru_split_dft_c2r(1, &(x->dim), 0, NULL, in1, in2, out, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT); - dsp_add_zero(in1+ n/2, n/2); - dsp_add(sigrifftw_perform,3,&x->plan,in2,n2); -} -static void sigfftw_setup() { - sigfftw_class = class_new2( "fft~",sigfftw_new, sigfftw_free, sizeof(t_sigfftw), 0,""); - sigifftw_class = class_new2( "ifft~",sigifftw_new, sigifftw_free, sizeof(t_sigfftw), 0,""); - sigrfftw_class = class_new2( "rfft~",sigrfftw_new, sigrfftw_free, sizeof(t_sigrfftw), 0,""); - sigrifftw_class = class_new2("rifft~",sigrifftw_new,sigrifftw_free,sizeof(t_sigrifftw),0,""); - CLASS_MAINSIGNALIN(sigfftw_class, t_sigfftw, a); - CLASS_MAINSIGNALIN(sigifftw_class, t_sigfftw, a); - CLASS_MAINSIGNALIN(sigrfftw_class, t_sigrfftw, a); - CLASS_MAINSIGNALIN(sigrifftw_class,t_sigrifftw,a); - class_addmethod2(sigfftw_class, sigfftw_dsp, "dsp",""); - class_addmethod2(sigifftw_class, sigifftw_dsp, "dsp",""); - class_addmethod2(sigrfftw_class, sigrfftw_dsp, "dsp",""); - class_addmethod2(sigrifftw_class, sigrifftw_dsp,"dsp",""); - class_sethelpsymbol(sigifftw_class, gensym("fft~")); - class_sethelpsymbol(sigrfftw_class, gensym("fft~")); - class_sethelpsymbol(sigrifftw_class,gensym("fft~")); -} -#endif /* HAVE_LIBFFTW3F */ -/* end of FFTW support */ - -/* ----------------------- framp~ -------------------------------- */ -static t_class *sigframp_class; -struct t_sigframp : t_object { - float a; -}; -static void *sigframp_new() { - t_sigframp *x = (t_sigframp *)pd_new(sigframp_class); - inlet_new(x, x, &s_signal, &s_signal); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static t_int *sigframp_perform(t_int *w) { - PERFORM5ARGS(float *,inreal, float *,inimag, float *,outfreq, float *,outamp, int,n); - float lastreal = 0, currentreal = inreal[0], nextreal = inreal[1]; - float lastimag = 0, currentimag = inimag[0], nextimag = inimag[1]; - int m = n + 1; - float fbin = 1, oneovern2 = 1.f/((float)n * (float)n); - inreal += 2; - inimag += 2; - *outamp++ = *outfreq++ = 0; - n -= 2; - while (n--) { - float re, im, pow, freq; - lastreal = currentreal; - currentreal = nextreal; - nextreal = *inreal++; - lastimag = currentimag; - currentimag = nextimag; - nextimag = *inimag++; - re = currentreal - 0.5f * (lastreal + nextreal); - im = currentimag - 0.5f * (lastimag + nextimag); - pow = re * re + im * im; - if (pow > 1e-19) { - float detune = ((lastreal - nextreal) * re + - (lastimag - nextimag) * im) / (2.0f * pow); - if (detune > 2 || detune < -2) freq = pow = 0; - else freq = fbin + detune; - } - else freq = pow = 0; - *outfreq++ = freq; - *outamp++ = oneovern2 * pow; - fbin += 1.0f; - } - while (m--) *outamp++ = *outfreq++ = 0; - return w+6; -} -t_int *sigsqrt_perform(t_int *w); -static void sigframp_dsp(t_sigframp *x, t_signal **sp) { - int n = sp[0]->n, n2 = (n>>1); - if (n < 4) { - error("framp: minimum 4 points"); - return; - } - dsp_add(sigframp_perform, 5, sp[0]->v, sp[1]->v, - sp[2]->v, sp[3]->v, n2); - dsp_add(sigsqrt_perform, 3, sp[3]->v, sp[3]->v, n2); -} -static void sigframp_setup() { - sigframp_class = class_new2("framp~",sigframp_new,0,sizeof(t_sigframp),0,""); - CLASS_MAINSIGNALIN(sigframp_class, t_sigframp, a); - class_addmethod2(sigframp_class, sigframp_dsp, "dsp",""); -} - -/* ---------------- hip~ - 1-pole 1-zero hipass filter. ----------------- */ -/* ---------------- lop~ - 1-pole lopass filter. ----------------- */ -t_class *sighip_class; struct t_hipctl {float x; float coef;}; -t_class *siglop_class; struct t_lopctl {float x; float coef;}; -struct t_sighip : t_object {float sr; float hz; t_hipctl cspace; t_hipctl *ctl; float a;}; -struct t_siglop : t_object {float sr; float hz; t_lopctl cspace; t_lopctl *ctl; float a;}; - -static void sighip_ft1(t_sighip *x, t_floatarg f) {x->hz = max(f,0.f); x->ctl->coef = clip(1-f*(2*3.14159)/x->sr,0.,1.);} -static void siglop_ft1(t_siglop *x, t_floatarg f) {x->hz = max(f,0.f); x->ctl->coef = clip( f*(2*3.14159)/x->sr,0.,1.);} - -static void *sighip_new(t_floatarg f) { - t_sighip *x = (t_sighip *)pd_new(sighip_class); - inlet_new(x, x, &s_float, gensym("ft1")); outlet_new(x, &s_signal); - x->sr = 44100; x->ctl = &x->cspace; x->cspace.x = 0; sighip_ft1(x, f); x->a = 0; return x;} -static void *siglop_new(t_floatarg f) { - t_siglop *x = (t_siglop *)pd_new(siglop_class); - inlet_new(x, x, &s_float, gensym("ft1")); outlet_new(x, &s_signal); - x->sr = 44100; x->ctl = &x->cspace; x->cspace.x = 0; siglop_ft1(x, f); x->a = 0; return x;} - -static void sighip_clear(t_sighip *x, t_floatarg q) {x->cspace.x = 0;} -static void siglop_clear(t_siglop *x, t_floatarg q) {x->cspace.x = 0;} - -static t_int *sighip_perform(t_int *w) { - PERFORM4ARGS(float *,in, float *,out, t_hipctl *,c, int,n); - float last = c->x; - float coef = c->coef; - if (coef < 1) { - for (int i = 0; i < n; i++) { - float noo = *in++ + coef * last; - *out++ = noo - last; - last = noo; - } - if (PD_BIGORSMALL(last)) last = 0; - c->x = last; - } else { - for (int i = 0; i < n; i++) *out++ = *in++; - c->x = 0; - } - return w+5; -} -static t_int *siglop_perform(t_int *w) { - PERFORM4ARGS(float *,in, float *,out, t_lopctl *,c, int,n); - float last = c->x; - float coef = c->coef; - float feedback = 1 - coef; - for (int i = 0; i < n; i++) last = *out++ = coef * *in++ + feedback * last; - if (PD_BIGORSMALL(last)) last = 0; - c->x = last; - return w+5; -} -static void sighip_dsp(t_sighip *x, t_signal **sp) {x->sr = sp[0]->sr; sighip_ft1(x,x->hz); - dsp_add(sighip_perform,4,sp[0]->v,sp[1]->v,x->ctl,sp[0]->n);} -static void siglop_dsp(t_siglop *x, t_signal **sp) {x->sr = sp[0]->sr; siglop_ft1(x,x->hz); - dsp_add(siglop_perform,4,sp[0]->v,sp[1]->v,x->ctl,sp[0]->n);} - -void sighip_setup() { - sighip_class = class_new2("hip~",sighip_new,0,sizeof(t_sighip),0,"F"); - CLASS_MAINSIGNALIN(sighip_class, t_sighip, a); - class_addmethod2(sighip_class, sighip_dsp, "dsp",""); - class_addmethod2(sighip_class, sighip_ft1, "ft1","f"); - class_addmethod2(sighip_class, sighip_clear,"clear",""); -} -void siglop_setup() { - siglop_class = class_new2("lop~",siglop_new,0,sizeof(t_siglop),0,"F"); - CLASS_MAINSIGNALIN(siglop_class, t_siglop, a); - class_addmethod2(siglop_class, siglop_dsp, "dsp",""); - class_addmethod2(siglop_class, siglop_ft1, "ft1","f"); - class_addmethod2(siglop_class, siglop_clear, "clear",""); -} - -/* ---------------- bp~ - 2-pole bandpass filter. ----------------- */ -struct t_bpctl { - float x1; - float x2; - float coef1; - float coef2; - float gain; -}; -struct t_sigbp : t_object { - float sr; - float freq; - float q; - t_bpctl cspace; - t_bpctl *ctl; - float a; -}; -t_class *sigbp_class; -static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q); -static void *sigbp_new(t_floatarg f, t_floatarg q) { - t_sigbp *x = (t_sigbp *)pd_new(sigbp_class); - inlet_new(x, x, &s_float, gensym("ft1")); - inlet_new(x, x, &s_float, gensym("ft2")); - outlet_new(x, &s_signal); - x->sr = 44100; - x->ctl = &x->cspace; - x->cspace.x1 = 0; - x->cspace.x2 = 0; - sigbp_docoef(x, f, q); - x->a = 0; - return x; -} -static float sigbp_qcos(float f) { - if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f) { - float g = f*f; - return ((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1; - } else return 0; -} -static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q) { - float r, oneminusr, omega; - if (f < 0.001) f = 10; - if (q < 0) q = 0; - x->freq = f; - x->q = q; - omega = f * (2.0f * 3.14159f) / x->sr; - if (q < 0.001) oneminusr = 1.0f; - else oneminusr = omega/q; - if (oneminusr > 1.0f) oneminusr = 1.0f; - r = 1.0f - oneminusr; - x->ctl->coef1 = 2.0f * sigbp_qcos(omega) * r; - x->ctl->coef2 = - r * r; - x->ctl->gain = 2 * oneminusr * (oneminusr + r * omega); - /* post("r %f, omega %f, coef1 %f, coef2 %f", r, omega, x->ctl->coef1, x->ctl->coef2); */ -} -static void sigbp_ft1(t_sigbp *x, t_floatarg f) {sigbp_docoef(x, f, x->q);} -static void sigbp_ft2(t_sigbp *x, t_floatarg q) {sigbp_docoef(x, x->freq, q);} -static void sigbp_clear(t_sigbp *x, t_floatarg q) {x->ctl->x1 = x->ctl->x2 = 0;} -static t_int *sigbp_perform(t_int *w) { - PERFORM4ARGS(float *,in, float *,out, t_bpctl *,c, int,n); - float last = c->x1; - float prev = c->x2; - float coef1 = c->coef1; - float coef2 = c->coef2; - float gain = c->gain; - for (int i = 0; i < n; i++) { - float output = *in++ + coef1 * last + coef2 * prev; - *out++ = gain * output; - prev = last; - last = output; - } - if (PD_BIGORSMALL(last)) last = 0; - if (PD_BIGORSMALL(prev)) prev = 0; - c->x1 = last; - c->x2 = prev; - return w+5; -} -static void sigbp_dsp(t_sigbp *x, t_signal **sp) { - x->sr = sp[0]->sr; - sigbp_docoef(x, x->freq, x->q); - dsp_add(sigbp_perform, 4, sp[0]->v, sp[1]->v, x->ctl, sp[0]->n); - -} -void sigbp_setup() { - sigbp_class = class_new2("bp~",sigbp_new,0,sizeof(t_sigbp),0,"FF"); - CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, a); - class_addmethod2(sigbp_class, sigbp_dsp, "dsp",""); - class_addmethod2(sigbp_class, sigbp_ft1, "ft1","f"); - class_addmethod2(sigbp_class, sigbp_ft2, "ft2","f"); - class_addmethod2(sigbp_class, sigbp_clear, "clear",""); -} - -/* ---------------- biquad~ - raw biquad filter ----------------- */ -struct t_biquadctl { - float x1; - float x2; - float fb1; - float fb2; - float ff1; - float ff2; - float ff3; -}; -struct t_sigbiquad : t_object { - float a; - t_biquadctl cspace; - t_biquadctl *ctl; -}; -t_class *sigbiquad_class; -static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv); -static void *sigbiquad_new(t_symbol *s, int argc, t_atom *argv) { - t_sigbiquad *x = (t_sigbiquad *)pd_new(sigbiquad_class); - outlet_new(x, &s_signal); - x->ctl = &x->cspace; - x->cspace.x1 = x->cspace.x2 = 0; - sigbiquad_list(x, s, argc, argv); - x->a = 0; - return x; -} -static t_int *sigbiquad_perform(t_int *w) { - PERFORM4ARGS(float *,in, float *,out, t_biquadctl *,c, int,n); - float last = c->x1; - float prev = c->x2; - float fb1 = c->fb1; - float fb2 = c->fb2; - float ff1 = c->ff1; - float ff2 = c->ff2; - float ff3 = c->ff3; - for (int i = 0; i < n; i++) { - float output = *in++ + fb1 * last + fb2 * prev; - if (PD_BIGORSMALL(output)) output = 0; - *out++ = ff1 * output + ff2 * last + ff3 * prev; - prev = last; - last = output; - } - c->x1 = last; - c->x2 = prev; - return w+5; -} -/* tb: some loop unrolling & do some relaxed denormal bashing */ -/* (denormal bashing = non-Pentium4 penalised for Pentium4's failings) */ -static t_int *sigbiquad_perf8(t_int *w) { - PERFORM4ARGS(float *,in, float *,out, t_biquadctl *,c, int,n); - n>>=3; - float last = c->x1; - float prev = c->x2; - float fb1 = c->fb1; - float fb2 = c->fb2; - float ff1 = c->ff1; - float ff2 = c->ff2; - float ff3 = c->ff3; - for (int i = 0; i < n; i++) { - float output = *in++ + fb1*last + fb2*prev; - if (PD_BIGORSMALL(output)) output = 0; - *out++ = ff1 * output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - if (PD_BIGORSMALL(output)) output = 0; - *out++ = ff1 * output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - *out++ = ff1 * output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - *out++ = ff1 * output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - output += 1e-10; - output -= 1e-10; - *out++ = ff1*output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - *out++ = ff1*output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - *out++ = ff1*output + ff2*last + ff3*prev; prev=last; last=output; output = *in++ + fb1*last + fb2*prev; - *out++ = ff1*output + ff2*last + ff3*prev; prev=last; last=output; - } - c->x1 = last; - c->x2 = prev; - return w+5; -} -static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv) { - float fb1 = atom_getfloatarg(0, argc, argv); - float fb2 = atom_getfloatarg(1, argc, argv); - float ff1 = atom_getfloatarg(2, argc, argv); - float ff2 = atom_getfloatarg(3, argc, argv); - float ff3 = atom_getfloatarg(4, argc, argv); - float discriminant = fb1 * fb1 + 4 * fb2; - t_biquadctl *c = x->ctl; - /* imaginary roots -- resonant filter */ - if (discriminant < 0) { - /* they're conjugates so we just check that the product is less than one */ - if (fb2 >= -1.0f) goto stable; - } else { /* real roots */ - /* check that the parabola 1 - fb1 x - fb2 x^2 has a - vertex between -1 and 1, and that it's nonnegative - at both ends, which implies both roots are in [1-,1]. */ - if (fb1 <= 2.0f && fb1 >= -2.0f && 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0) goto stable; - } - /* if unstable, just bash to zero */ - fb1 = fb2 = ff1 = ff2 = ff3 = 0; -stable: - c->fb1 = fb1; - c->fb2 = fb2; - c->ff1 = ff1; - c->ff2 = ff2; - c->ff3 = ff3; -} -static void sigbiquad_set(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv) { - t_biquadctl *c = x->ctl; - c->x1 = atom_getfloatarg(0, argc, argv); - c->x2 = atom_getfloatarg(1, argc, argv); -} -static void sigbiquad_dsp(t_sigbiquad *x, t_signal **sp) { - const int n = sp[0]->n; - if (n&7) dsp_add(sigbiquad_perform, 4, sp[0]->v, sp[1]->v, x->ctl, sp[0]->n); - else dsp_add(sigbiquad_perf8, 4, sp[0]->v, sp[1]->v, x->ctl, sp[0]->n); -} -void sigbiquad_setup() { - sigbiquad_class = class_new2("biquad~",sigbiquad_new,0,sizeof(t_sigbiquad),0,"*"); - CLASS_MAINSIGNALIN(sigbiquad_class, t_sigbiquad, a); - class_addmethod2(sigbiquad_class, sigbiquad_dsp, "dsp",""); - class_addlist(sigbiquad_class, sigbiquad_list); - class_addmethod2(sigbiquad_class, sigbiquad_set, "set","*"); - class_addmethod2(sigbiquad_class, sigbiquad_set, "clear","*"); -} - -/* ---------------- samphold~ - sample and hold ----------------- */ -struct t_sigsamphold : t_object { - float a; - float lastin; - float lastout; -}; -t_class *sigsamphold_class; -static void *sigsamphold_new() { - t_sigsamphold *x = (t_sigsamphold *)pd_new(sigsamphold_class); - inlet_new(x, x, &s_signal, &s_signal); - outlet_new(x, &s_signal); - x->lastin = 0; - x->lastout = 0; - x->a = 0; - return x; -} -static t_int *sigsamphold_perform(t_int *w) { - PERFORM5ARGS(float *,in1, float *,in2, float *,out, t_sigsamphold *,x, int,n); - float lastin = x->lastin; - float lastout = x->lastout; - for (int i = 0; i < n; i++, *in1++) { - float next = *in2++; - if (next < lastin) lastout = *in1; - *out++ = lastout; - lastin = next; - } - x->lastin = lastin; - x->lastout = lastout; - return w+6; -} -static void sigsamphold_dsp(t_sigsamphold *x, t_signal **sp) { - dsp_add(sigsamphold_perform, 5, sp[0]->v, sp[1]->v, sp[2]->v, x, sp[0]->n); -} -static void sigsamphold_reset(t_sigsamphold *x, t_symbol *s, int argc, t_atom *argv) { - x->lastin = ((argc > 0 && (argv[0].a_type == A_FLOAT)) ? argv[0].a_w.w_float : 1e20); -} -static void sigsamphold_set(t_sigsamphold *x, t_float f) { - x->lastout = f; -} -void sigsamphold_setup() { - sigsamphold_class = class_new2("samphold~",sigsamphold_new,0,sizeof(t_sigsamphold),0,""); - CLASS_MAINSIGNALIN(sigsamphold_class, t_sigsamphold, a); - class_addmethod2(sigsamphold_class, sigsamphold_set, "set","F"); - class_addmethod2(sigsamphold_class, sigsamphold_reset, "reset","*"); - class_addmethod2(sigsamphold_class, sigsamphold_dsp, "dsp",""); -} - -/* ---------------- rpole~ - real one-pole filter (raw) ----------------- */ -/* ---------------- rzero~ - real one-zero filter (raw) ----------------- */ -/* --- rzero_rev~ - real, reverse one-zero filter (raw) ----------------- */ -t_class *sigrpole_class; struct t_sigrpole : t_object {float a; float last;}; -t_class *sigrzero_class; struct t_sigrzero : t_object {float a; float last;}; -t_class *sigrzrev_class; struct t_sigrzrev : t_object {float a; float last;}; - -static void *sigrpole_new(t_float f) { - t_sigrpole *x = (t_sigrpole *)pd_new(sigrpole_class); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), f); outlet_new(x, &s_signal); x->last=0; return x;} -static void *sigrzero_new(t_float f) { - t_sigrzero *x = (t_sigrzero *)pd_new(sigrzero_class); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), f); outlet_new(x, &s_signal); x->last=0; return x;} -static void *sigrzrev_new(t_float f) { - t_sigrzrev *x = (t_sigrzrev *)pd_new(sigrzrev_class); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), f); outlet_new(x, &s_signal); x->last=0; return x;} - -static t_int *sigrpole_perform(t_int *w) { - PERFORM5ARGS(float *,in1, float *,in2, float *,out, t_sigrpole *,x, t_int,n); - float last = x->last; - for (int i=0; i<n; i++) { - float next = *in1++, coef = *in2++; - *out++ = last = coef*last + next; - } - if (PD_BIGORSMALL(last)) last = 0; - x->last = last; - return w+6; -} -static t_int *sigrzero_perform(t_int *w) { - PERFORM5ARGS(float *,in1, float *,in2, float *,out, t_sigrzero *,x, t_int,n); - float last = x->last; - for (int i = 0; i < n; i++) { - float next = *in1++, coef = *in2++; - *out++ = next - coef*last; - last = next; - } - x->last = last; - return w+6; -} -static t_int *sigrzrev_perform(t_int *w) { - PERFORM5ARGS(float *,in1, float *,in2, float *,out, t_sigrzrev *,x, t_int,n); - float last = x->last; - for (int i = 0; i < n; i++) { - float next = *in1++, coef = *in2++; - *out++ = last - coef*next; - last = next; - } - x->last = last; - return w+6; -} - -static void sigrpole_dsp(t_sigrpole *x, t_signal **sp) {dsp_add(sigrpole_perform, 5, sp[0]->v, sp[1]->v, sp[2]->v, x, sp[0]->n);} -static void sigrzero_dsp(t_sigrzero *x, t_signal **sp) {dsp_add(sigrzero_perform, 5, sp[0]->v, sp[1]->v, sp[2]->v, x, sp[0]->n);} -static void sigrzrev_dsp(t_sigrzrev *x, t_signal **sp) {dsp_add(sigrzrev_perform, 5, sp[0]->v, sp[1]->v, sp[2]->v, x, sp[0]->n);} -static void sigrpole_clear(t_sigrpole *x) {x->last = 0;} -static void sigrzero_clear(t_sigrzero *x) {x->last = 0;} -static void sigrzrev_clear(t_sigrzrev *x) {x->last = 0;} -static void sigrpole_set(t_sigrpole *x, t_float f) {x->last = f;} -static void sigrzero_set(t_sigrzero *x, t_float f) {x->last = f;} -static void sigrzrev_set(t_sigrzrev *x, t_float f) {x->last = f;} -void sigr_setup() { - sigrpole_class = class_new2("rpole~", sigrpole_new,0,sizeof(t_sigrpole),0,"F"); - sigrzero_class = class_new2("rzero~", sigrzero_new,0,sizeof(t_sigrzero),0,"F"); - sigrzrev_class = class_new2("rzero_rev~",sigrzrev_new,0,sizeof(t_sigrzrev),0,"F"); - CLASS_MAINSIGNALIN(sigrpole_class, t_sigrpole, a); - CLASS_MAINSIGNALIN(sigrzero_class, t_sigrzero, a); - CLASS_MAINSIGNALIN(sigrzrev_class, t_sigrzrev, a); - class_addmethod2(sigrpole_class, sigrpole_set, "set","F"); - class_addmethod2(sigrzero_class, sigrzero_set, "set","F"); - class_addmethod2(sigrzrev_class, sigrzrev_set, "set","F"); - class_addmethod2(sigrpole_class, sigrpole_clear,"clear",""); - class_addmethod2(sigrzero_class, sigrzero_clear,"clear",""); - class_addmethod2(sigrzrev_class, sigrzrev_clear,"clear",""); - class_addmethod2(sigrpole_class, sigrpole_dsp, "dsp",""); - class_addmethod2(sigrzero_class, sigrzero_dsp, "dsp",""); - class_addmethod2(sigrzrev_class, sigrzrev_dsp, "dsp",""); -} - -/* -------------- cpole~ - complex one-pole filter (raw) --------------- */ -/* -------------- czero~ - complex one-pole filter (raw) --------------- */ -/* ---------- czero_rev~ - complex one-pole filter (raw) --------------- */ - -t_class *sigcpole_class; struct t_sigcpole : t_object {float a; float lastre; float lastim;}; -t_class *sigczero_class; struct t_sigczero : t_object {float a; float lastre; float lastim;}; -t_class *sigczrev_class; struct t_sigczrev : t_object {float a; float lastre; float lastim;}; - -static void *sigcpole_new(t_float re, t_float im) { - t_sigcpole *x = (t_sigcpole *)pd_new(sigcpole_class); - inlet_new(x, x, &s_signal, &s_signal); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), re); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), im); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->lastre = x->lastim = 0; - x->a = 0; - return x; -} -static void *sigczero_new(t_float re, t_float im) { - t_sigczero *x = (t_sigczero *)pd_new(sigczero_class); - inlet_new(x, x, &s_signal, &s_signal); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), re); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), im); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->lastre = x->lastim = 0; - x->a = 0; - return x; -} -static void *sigczrev_new(t_float re, t_float im) { - t_sigczrev *x = (t_sigczrev *)pd_new(sigczrev_class); - inlet_new(x, x, &s_signal, &s_signal); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), re); - pd_float((t_pd *)inlet_new(x, x, &s_signal, &s_signal), im); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->lastre = x->lastim = 0; - x->a = 0; - return x; -} - -static t_int *sigcpole_perform(t_int *w) { - PERFORM8ARGS(float *,inre1, float *,inim1, float *,inre2, float *,inim2, float *,outre, float *,outim, t_sigcpole *,x, int,n); - float lastre = x->lastre; - float lastim = x->lastim; - for (int i = 0; i < n; i++) { - float nextre = *inre1++, nextim = *inim1++; - float coefre = *inre2++, coefim = *inim2++; - float tempre = *outre++ = nextre + lastre * coefre - lastim * coefim; - lastim = *outim++ = nextim + lastre * coefim + lastim * coefre; - lastre = tempre; - } - if (PD_BIGORSMALL(lastre)) lastre = 0; - if (PD_BIGORSMALL(lastim)) lastim = 0; - x->lastre = lastre; - x->lastim = lastim; - return w+9; -} -static t_int *sigczero_perform(t_int *w) { - PERFORM8ARGS(float *,inre1, float *,inim1, float *,inre2, float *,inim2, float *,outre, float *,outim, t_sigczero *,x, int,n); - float lastre = x->lastre; - float lastim = x->lastim; - for (int i = 0; i < n; i++) { - float nextre = *inre1++, nextim = *inim1++; - float coefre = *inre2++, coefim = *inim2++; - *outre++ = nextre - lastre * coefre + lastim * coefim; - *outim++ = nextim - lastre * coefim - lastim * coefre; - lastre = nextre; - lastim = nextim; - } - x->lastre = lastre; - x->lastim = lastim; - return w+9; -} -static t_int *sigczrev_perform(t_int *w) { - PERFORM8ARGS(float *,inre1, float *,inim1, float *,inre2, float *,inim2, float *,outre, float *,outim, t_sigczrev *,x, int,n); - float lastre = x->lastre; - float lastim = x->lastim; - for (int i = 0; i < n; i++) { - float nextre = *inre1++, nextim = *inim1++; - float coefre = *inre2++, coefim = *inim2++; - /* transfer function is (A bar) - Z^-1, for the same frequency response as 1 - AZ^-1 from czero_tilde. */ - *outre++ = lastre - nextre * coefre - nextim * coefim; - *outim++ = lastim - nextre * coefim + nextim * coefre; - lastre = nextre; - lastim = nextim; - } - x->lastre = lastre; - x->lastim = lastim; - return w+9; -} - -static void sigcpole_dsp(t_sigcpole *x, t_signal **sp) { - dsp_add(sigcpole_perform,8,sp[0]->v,sp[1]->v,sp[2]->v,sp[3]->v,sp[4]->v,sp[5]->v,x,sp[0]->n);} -static void sigczero_dsp(t_sigczero *x, t_signal **sp) { - dsp_add(sigczero_perform,8,sp[0]->v,sp[1]->v,sp[2]->v,sp[3]->v,sp[4]->v,sp[5]->v,x,sp[0]->n);} -static void sigczrev_dsp(t_sigczrev *x, t_signal **sp) { - dsp_add(sigczrev_perform,8,sp[0]->v,sp[1]->v,sp[2]->v,sp[3]->v,sp[4]->v,sp[5]->v,x,sp[0]->n);} - -static void sigcpole_clear(t_sigcpole *x) {x->lastre = x->lastim = 0;} -static void sigczero_clear(t_sigczero *x) {x->lastre = x->lastim = 0;} -static void sigczrev_clear(t_sigczrev *x) {x->lastre = x->lastim = 0;} -static void sigcpole_set(t_sigcpole *x, t_float re, t_float im) {x->lastre = re; x->lastim = im;} -static void sigczero_set(t_sigczero *x, t_float re, t_float im) {x->lastre = re; x->lastim = im;} -static void sigczrev_set(t_sigczrev *x, t_float re, t_float im) {x->lastre = re; x->lastim = im;} - -void sigc_setup() { - sigcpole_class = class_new2("cpole~", sigcpole_new,0,sizeof(t_sigcpole),0,"FF"); - sigczero_class = class_new2("czero~", sigczero_new,0,sizeof(t_sigczero),0,"FF"); - sigczrev_class = class_new2("czero_rev~",sigczrev_new,0,sizeof(t_sigczrev),0,"FF"); - CLASS_MAINSIGNALIN(sigcpole_class, t_sigcpole, a); - CLASS_MAINSIGNALIN(sigczero_class, t_sigczero, a); - CLASS_MAINSIGNALIN(sigczrev_class, t_sigczrev, a); - class_addmethod2(sigcpole_class, sigcpole_set, "set","FF"); - class_addmethod2(sigczero_class, sigczero_set, "set","FF"); - class_addmethod2(sigczrev_class, sigczrev_set, "set","FF"); - class_addmethod2(sigcpole_class, sigcpole_clear,"clear",""); - class_addmethod2(sigczero_class, sigczero_clear, "clear",""); - class_addmethod2(sigczrev_class, sigczrev_clear, "clear",""); - class_addmethod2(sigcpole_class, sigcpole_dsp, "dsp",""); - class_addmethod2(sigczero_class, sigczero_dsp, "dsp",""); - class_addmethod2(sigczrev_class, sigczrev_dsp, "dsp",""); -} - -/* ----------------------------- send~ ----------------------------- */ -static t_class *sigsend_class; -struct t_sigsend : t_object { - t_symbol *sym; - int n; - float *vec; - float a; -}; -static void *sigsend_new(t_symbol *s) { - t_sigsend *x = (t_sigsend *)pd_new(sigsend_class); - pd_bind(x, s); - x->sym = s; - x->n = DEFSENDVS; - x->vec = (float *)getalignedbytes(DEFSENDVS * sizeof(float)); - memset((char *)(x->vec), 0, DEFSENDVS * sizeof(float)); - x->a = 0; - return x; -} -static t_int *sigsend_perform(t_int *w) {testcopyvec( (t_float *)w[2],(t_float *)w[1],w[3]); return w+4;} -static t_int *sigsend_perfsimd(t_int *w) {testcopyvec_simd((t_float *)w[2],(t_float *)w[1],w[3]); return w+4;} // T.Grill -static void sigsend_dsp(t_sigsend *x, t_signal **sp) { - const int n = x->n; - if(n != sp[0]->n) {error("sigsend %s: unexpected vector size", x->sym->name); return;} - if(SIMD_CHECK1(n,sp[0]->v)) /* x->vec is aligned in any case */ - dsp_add(sigsend_perfsimd, 3, sp[0]->v, x->vec, n); - else dsp_add(sigsend_perform, 3, sp[0]->v, x->vec, n); -} -static void sigsend_free(t_sigsend *x) { - pd_unbind(x, x->sym); - freealignedbytes(x->vec,x->n* sizeof(float)); -} -static void sigsend_setup() { - sigsend_class = class_new2("send~",sigsend_new,sigsend_free,sizeof(t_sigsend),0,"S"); - class_addcreator2("s~",sigsend_new,"S"); - CLASS_MAINSIGNALIN(sigsend_class, t_sigsend, a); - class_addmethod2(sigsend_class, sigsend_dsp,"dsp",""); -} - -/* ----------------------------- receive~ ----------------------------- */ -static t_class *sigreceive_class; -struct t_sigreceive : t_object { - t_symbol *sym; - t_float *wherefrom; - int n; -}; -static void *sigreceive_new(t_symbol *s) { - t_sigreceive *x = (t_sigreceive *)pd_new(sigreceive_class); - x->n = DEFSENDVS; /* LATER find our vector size correctly */ - x->sym = s; - x->wherefrom = 0; - outlet_new(x, &s_signal); - return x; -} -static t_int *sigreceive_perform(t_int *w) { - PERFORM3ARGS(t_sigreceive *,x, t_float *,out, int,n); - t_float *in = x->wherefrom; - if (in) { - while (n--) *out++ = *in++; - } else { - while (n--) *out++ = 0; - } - return w+4; -} -/* tb: vectorized receive function */ -static t_int *sigreceive_perf8(t_int *w) { - PERFORM3ARGS(t_sigreceive *,x, t_float *,out, int,n); - t_float *in = x->wherefrom; - if (in) copyvec_8(out,in,n); - else zerovec_8(out, n); - return w+4; -} -/* T.Grill - SIMD version */ -static t_int *sigreceive_perfsimd(t_int *w) { - PERFORM3ARGS(t_sigreceive *,x, t_float *,out, int,n); - t_float *in = x->wherefrom; - if(in) copyvec_simd(out,in,n); - else zerovec_simd(out, n); - return w+4; -} -static void sigreceive_set(t_sigreceive *x, t_symbol *s) { - t_sigsend *sender = (t_sigsend *)pd_findbyclass((x->sym = s), - sigsend_class); - if (sender) { - if (sender->n == x->n) - x->wherefrom = sender->vec; - else { - error("receive~ %s: vector size mismatch", x->sym->name); - x->wherefrom = 0; - } - } else { - error("receive~ %s: no matching send", x->sym->name); - x->wherefrom = 0; - } -} -static void sigreceive_dsp(t_sigreceive *x, t_signal **sp) { - const int n = x->n; - if (sp[0]->n != n) {error("receive~ %s: vector size mismatch", x->sym->name); return;} - sigreceive_set(x, x->sym); - /* x->wherefrom is aligned because we aligned the sender memory buffer */ - if(n&7) dsp_add(sigreceive_perform, 3, x, sp[0]->v, n); - else if(SIMD_CHECK1(n,sp[0]->v)) dsp_add(sigreceive_perfsimd, 3, x, sp[0]->v, n); - else dsp_add(sigreceive_perf8, 3, x, sp[0]->v, n); -} -static void sigreceive_setup() { - sigreceive_class = class_new2("receive~",sigreceive_new,0,sizeof(t_sigreceive),0,"S"); - class_addcreator2("r~",sigreceive_new,"S"); - class_addmethod2(sigreceive_class, sigreceive_set, "set","s"); - class_addmethod2(sigreceive_class, sigreceive_dsp, "dsp",""); - class_sethelpsymbol(sigreceive_class, gensym("send~")); -} - -/* ----------------------------- catch~ ----------------------------- */ -static t_class *sigcatch_class; -struct t_sigcatch : t_object { - t_symbol *sym; - int n; - float *vec; -}; -static void *sigcatch_new(t_symbol *s) { - t_sigcatch *x = (t_sigcatch *)pd_new(sigcatch_class); - pd_bind(x, s); - x->sym = s; - x->n = DEFSENDVS; - x->vec = (float *)getalignedbytes(DEFSENDVS * sizeof(float)); - memset((char *)(x->vec), 0, DEFSENDVS * sizeof(float)); - outlet_new(x, &s_signal); - return x; -} -static t_int *sigcatch_perform(t_int *w) { - PERFORM3ARGS(t_float *,in, t_float *,out, int,n); - while (n--) *out++ = *in, *in++ = 0; - return w+4; -} -/* tb: vectorized catch function */ -static t_int *sigcatch_perf8(t_int *w) { - PERFORM3ARGS(t_float *,in, t_float *,out, int,n); - copyvec_8(out,in,n); - zerovec_8( in,n); - return w+4; -} -/* T.Grill: SIMD catch function */ -static t_int *sigcatch_perfsimd(t_int *w) { - PERFORM3ARGS(t_float *,in, t_float *,out, int,n); - copyvec_simd(out,in,n); - zerovec_simd( in,n); - return w+4; -} -static void sigcatch_dsp(t_sigcatch *x, t_signal **sp) { - const int n = sp[0]->n; - if (x->n != n) {error("sigcatch %s: unexpected vector size", x->sym->name); return;} - if(n&7) dsp_add(sigcatch_perform, 3, x->vec, sp[0]->v, n); - else if(SIMD_CHECK2(n,x->vec,sp[0]->v)) dsp_add(sigcatch_perfsimd,3, x->vec, sp[0]->v, n); - else dsp_add(sigcatch_perf8, 3, x->vec, sp[0]->v, n); -} -static void sigcatch_free(t_sigcatch *x) { - pd_unbind(x, x->sym); - freealignedbytes(x->vec,x->n*sizeof(float)); -} -static void sigcatch_setup() { - sigcatch_class = class_new2("catch~",sigcatch_new,sigcatch_free,sizeof(t_sigcatch),CLASS_NOINLET,"S"); - class_addmethod2(sigcatch_class, sigcatch_dsp, "dsp",""); - class_sethelpsymbol(sigcatch_class, gensym("throw~")); -} - -/* ----------------------------- throw~ ----------------------------- */ -static t_class *sigthrow_class; -struct t_sigthrow : t_object { - t_symbol *sym; - t_float *whereto; - int n; - t_float a; -}; -static void *sigthrow_new(t_symbol *s) { - t_sigthrow *x = (t_sigthrow *)pd_new(sigthrow_class); - x->sym = s; - x->whereto = 0; - x->n = DEFSENDVS; - x->a = 0; - return x; -} -static t_int *sigthrow_perform(t_int *w) { - t_sigthrow *x = (t_sigthrow *)w[1]; - t_float *out = x->whereto; - if(out) testaddvec(out,(t_float *)w[2],w[3]); - return w+4; -} -/* T.Grill - SIMD version */ -static t_int *sigthrow_perfsimd(t_int *w) { - t_sigthrow *x = (t_sigthrow *)w[1]; - t_float *out = x->whereto; - if(out) testaddvec_simd(out,(t_float *)w[2],w[3]); - return w+4; -} -static void sigthrow_set(t_sigthrow *x, t_symbol *s) { - x->sym = s; - t_sigcatch *catcher = (t_sigcatch *)pd_findbyclass(s,sigcatch_class); - x->whereto = 0; - if (catcher) { - if (catcher->n == x->n) x->whereto = catcher->vec; - else error("throw~ %s: vector size mismatch", x->sym->name); - } else error("throw~ %s: no matching catch", x->sym->name); -} -static void sigthrow_dsp(t_sigthrow *x, t_signal **sp) { - const int n = x->n; - if (sp[0]->n != n) {error("throw~ %s: vector size mismatch", x->sym->name); return;} - sigthrow_set(x, x->sym); - if(SIMD_CHECK1(n,sp[0]->v)) /* the memory of the catcher is aligned in any case */ - dsp_add(sigthrow_perfsimd, 3, x, sp[0]->v, n); - else dsp_add(sigthrow_perform, 3, x, sp[0]->v, n); -} -static void sigthrow_setup() { - sigthrow_class = class_new2("throw~",sigthrow_new,0,sizeof(t_sigthrow),0,"S"); - class_addmethod2(sigthrow_class, sigthrow_set, "set","s"); - CLASS_MAINSIGNALIN(sigthrow_class, t_sigthrow, a); - class_addmethod2(sigthrow_class, sigthrow_dsp, "dsp",""); -} - -/* ------------------------- clip~ -------------------------- */ -static t_class *clip_class; -struct t_clip : t_object { - float a; - t_sample lo; - t_sample hi; -}; -static void *clip_new(t_floatarg lo, t_floatarg hi) { - t_clip *x = (t_clip *)pd_new(clip_class); - x->lo = lo; - x->hi = hi; - outlet_new(x, &s_signal); - floatinlet_new(x, &x->lo); - floatinlet_new(x, &x->hi); - x->a = 0; - return x; -} -/* T.Grill - changed function interface so that class pointer needn't be passed */ -t_int *clip_perform(t_int *w) { - PERFORM5ARGS(t_float *,in, t_float *,out, t_float *,lop, t_float *,hip, int,n); - t_float lo=*lop, hi=*hip; - while (n--) *out++ = clip(*in++,lo,hi); - return w+6; -} -static void clip_dsp(t_clip *x, t_signal **sp) { - if(SIMD_CHECK2(sp[0]->n,sp[0]->v,sp[1]->v)) - dsp_add(clip_perf_simd, 5, sp[0]->v, sp[1]->v, &x->lo, &x->hi, sp[0]->n); - else dsp_add(clip_perform, 5, sp[0]->v, sp[1]->v, &x->lo, &x->hi, sp[0]->n); -} -static void clip_setup() { - clip_class = class_new2("clip~",clip_new,0,sizeof(t_clip),0,"FF"); - CLASS_MAINSIGNALIN(clip_class, t_clip, a); - class_addmethod2(clip_class, clip_dsp, "dsp",""); -} - -/* sigrsqrt - reciprocal square root good to 8 mantissa bits */ -/* sigsqrt - square root good to 8 mantissa bits */ - -#define DUMTAB1SIZE 256 -#define DUMTAB2SIZE 1024 -static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; -static void init_rsqrt() { - for (int i = 0; i < DUMTAB1SIZE; i++) { - float f; - long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23; - *(int *)(&f) = l; - rsqrt_exptab[i] = 1./sqrt(f); - } - for (int i = 0; i < DUMTAB2SIZE; i++) { - float f = 1 + (1./DUMTAB2SIZE) * i; - rsqrt_mantissatab[i] = 1./sqrt(f); - } -} -/* these are used in externs like "bonk" */ -float q8_rsqrt(float f) { - long l = *(long *)(&f); - if (f < 0) return 0; - return rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]; -} -float q8_sqrt(float f) { - long l = *(long *)(&f); - if (f < 0) return 0; - return f * rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]; -} - -/* the old names are OK unless we're in IRIX N32 */ -#ifndef N32 -float qsqrt(float f) {return q8_sqrt(f);} -float qrsqrt(float f) {return q8_rsqrt(f);} -#endif -static t_class *sigrsqrt_class; struct t_sigrsqrt : t_object {float a;}; -static t_class * sigsqrt_class; struct t_sigsqrt : t_object {float a;}; -static void *sigrsqrt_new() { - t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class); - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static void *sigsqrt_new() { - t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class); - outlet_new(x, &s_signal); - x->a = 0; - return x; -} - -static t_int *sigrsqrt_perform(t_int *w) { - float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); - t_int n = *(t_int *)(w+3); - while (n--) { - float f = *in; - long l = *(long *)(in++); - if (f < 0) *out++ = 0; - else { - float g = rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]; - *out++ = 1.5 * g - 0.5 * g * g * g * f; - } - } - return w+4; -} -/* not static; also used in d_fft.c */ -t_int *sigsqrt_perform(t_int *w) { - float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); - t_int n = *(t_int *)(w+3); - while (n--) { - float f = *in; - long l = *(long *)(in++); - if (f < 0) *out++ = 0; - else { - float g = rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]; - *out++ = f * (1.5 * g - 0.5 * g * g * g * f); - } - } - return w+4; -} - -static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp) { - if(SIMD_CHECK2(sp[0]->n,sp[0]->v,sp[1]->v)) - dsp_add(sigrsqrt_perf_simd, 3, sp[0]->v, sp[1]->v, sp[0]->n); - else dsp_add(sigrsqrt_perform, 3, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp) { - if(SIMD_CHECK2(sp[0]->n,sp[0]->v,sp[1]->v)) - dsp_add(sigsqrt_perf_simd, 3, sp[0]->v, sp[1]->v, sp[0]->n); - else dsp_add(sigsqrt_perform, 3, sp[0]->v, sp[1]->v, sp[0]->n); -} - -void sigsqrt_setup() { - init_rsqrt(); - sigrsqrt_class = class_new2("rsqrt~",sigrsqrt_new,0,sizeof(t_sigrsqrt),0,""); - sigsqrt_class = class_new2( "sqrt~", sigsqrt_new,0, sizeof(t_sigsqrt),0,""); - CLASS_MAINSIGNALIN(sigrsqrt_class,t_sigrsqrt,a); - CLASS_MAINSIGNALIN( sigsqrt_class, t_sigsqrt,a); - class_addmethod2( sigsqrt_class, sigsqrt_dsp,"dsp",""); - class_addmethod2(sigrsqrt_class,sigrsqrt_dsp,"dsp",""); - class_addcreator2("q8_rsqrt~",sigrsqrt_new,""); - class_addcreator2("q8_sqrt~", sigsqrt_new,""); -} - -/* ------------------------------ wrap~ -------------------------- */ -struct t_sigwrap : t_object {float a;}; -t_class *sigwrap_class; -static void *sigwrap_new() { - t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class); - outlet_new(x, &s_signal); - x->a = 0; - return x; -} -static t_int *sigwrap_perform(t_int *w) { - float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); - t_int n = *(t_int *)(w+3); - while (n--) { - float f = *in++; - int k = (int)f; - if (f > 0) *out++ = f-k; - else *out++ = f - (k-1); - } - return w+4; -} -static void sigwrap_dsp(t_sigwrap *x, t_signal **sp) { - if(SIMD_CHECK2(sp[0]->n,sp[0]->v,sp[1]->v)) - dsp_add(sigwrap_perf_simd, 3, sp[0]->v, sp[1]->v, sp[0]->n); - else dsp_add(sigwrap_perform, 3, sp[0]->v, sp[1]->v, sp[0]->n); -} -void sigwrap_setup() { - sigwrap_class = class_new2("wrap~",sigwrap_new,0,sizeof(t_sigwrap),0,""); - CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, a); - class_addmethod2(sigwrap_class, sigwrap_dsp, "dsp",""); -} - -/* ------------------------------ mtof_tilde~ and such -------------------------- */ -struct t_func1 : t_object {float a;}; -t_class *mtof_tilde_class, *ftom_tilde_class; -t_class *dbtorms_tilde_class, *rmstodb_tilde_class; -t_class *dbtopow_tilde_class, *powtodb_tilde_class; - -#define FUNC1(NAME,EXPR) \ -static t_int *NAME##_perform(t_int *w) { \ - float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); \ - for (t_int n = *(t_int *)(w+3); n--; in++, out++) { float a = *in; *out = (EXPR); } \ - return w+4;} \ -static void *NAME##_new() {t_func1 *x = (t_func1 *)pd_new(NAME##_class); \ - outlet_new(x,&s_signal); x->a = 0; return x;} \ -static void NAME##_dsp(t_func1 *x, t_signal **sp) { \ - dsp_add(NAME##_perform, 3, sp[0]->v, sp[1]->v, sp[0]->n);} - - -FUNC1(mtof_tilde, a<=-1500 ? 0 : 8.17579891564 * exp(.0577622650 * min(a,1499.f))) -FUNC1(ftom_tilde, a>0 ? 17.3123405046 * log(.12231220585 * a) : -1500) -FUNC1(dbtorms_tilde, a<=0 ? 0 : exp((LOGTEN * 0.05) * (min(a,485.f)-100.))) -FUNC1(dbtopow_tilde, a<=0 ? 0 : max(100 + 20./LOGTEN * log(a),0.)) -FUNC1(rmstodb_tilde, a<=0 ? 0 : exp((LOGTEN * 0.1) * (min(a,870.f)-100.))) -FUNC1(powtodb_tilde, a<=0 ? 0 : max(100 + 10./LOGTEN * log(a),0.)) - -#define FUNC1DECL(NAME,SYM) \ - NAME##_class = class_new2(SYM,NAME##_new,0,sizeof(t_func1),0,""); \ - CLASS_MAINSIGNALIN(NAME##_class,t_func1,a); \ - class_addmethod2(NAME##_class, NAME##_dsp, "dsp",""); - -void mtof_tilde_setup() { - FUNC1DECL(mtof_tilde,"mtof~") - FUNC1DECL(ftom_tilde,"ftom~") - FUNC1DECL(dbtorms_tilde,"dbtorms~") - FUNC1DECL(dbtopow_tilde,"dbtopow~") - FUNC1DECL(rmstodb_tilde,"rmstodb~") - FUNC1DECL(powtodb_tilde,"powtodb~") - t_symbol *s = gensym("acoustics~.pd"); - class_sethelpsymbol(mtof_tilde_class, s); - class_sethelpsymbol(ftom_tilde_class, s); - class_sethelpsymbol(dbtorms_tilde_class, s); - class_sethelpsymbol(rmstodb_tilde_class, s); - class_sethelpsymbol(dbtopow_tilde_class, s); - class_sethelpsymbol(powtodb_tilde_class, s); -} - -static t_class *print_class; -struct t_print : t_object { - float a; - t_symbol *sym; - int count; -}; -static t_int *print_perform(t_int *w) { - PERFORM3ARGS(t_print *,x, t_float *,in, int,n); - if (x->count) { - post("%s:", x->sym->name); - if (n == 1) post("%8g", in[0]); - else if (n == 2) post("%8g %8g", in[0], in[1]); - else if (n == 4) post("%8g %8g %8g %8g", in[0], in[1], in[2], in[3]); - else while (n > 0) { - post("%-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g", - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]); - n -= 8; - in += 8; - } - x->count--; - } - return w+4; -} -static void print_dsp(t_print *x, t_signal **sp) {dsp_add(print_perform, 3, x, sp[0]->v, sp[0]->n);} -static void print_float(t_print *x, t_float f) {x->count = max(0,(int)f);} -static void print_bang(t_print *x) {x->count = 1;} -static void *print_new(t_symbol *s) { - t_print *x = (t_print *)pd_new(print_class); - x->sym = s->name[0] ? s : gensym("print~"); - x->count = 0; - x->a = 0; - return x; -} -static void print_setup() { - print_class = class_new2("print~",print_new,0,sizeof(t_print),0,"S"); - CLASS_MAINSIGNALIN(print_class, t_print, a); - class_addmethod2(print_class, print_dsp, "dsp",""); - class_addbang(print_class, print_bang); - class_addfloat(print_class, print_float); -} - -/* ------------------------ bang~ -------------------------- */ -static t_class *bang_tilde_class; -struct t_bang : t_object { - t_clock *clock; -}; -static t_int *bang_tilde_perform(t_int *w) { - PERFORM1ARGS(t_bang *,x); - clock_delay(x->clock, 0); - return w+2; -} -static void bang_tilde_dsp(t_bang *x, t_signal **sp) {dsp_add(bang_tilde_perform, 1, x);} -static void bang_tilde_tick(t_bang *x) {x->outlet->send();} -static void bang_tilde_free(t_bang *x) {clock_free(x->clock);} -static void *bang_tilde_new(t_symbol *s) { - t_bang *x = (t_bang *)pd_new(bang_tilde_class); - x->clock = clock_new(x, bang_tilde_tick); - outlet_new(x, &s_bang); - return x; -} -static void bang_tilde_setup() { - bang_tilde_class = class_new2("bang~",bang_tilde_new,bang_tilde_free,sizeof(t_bang),0,""); - class_addmethod2(bang_tilde_class, bang_tilde_dsp, "dsp",""); -} - -/* -------------------------- phasor~ ------------------------------ */ -static t_class *phasor_class; -/* in the style of R. Hoeldrich (ICMC 1995 Banff) */ -struct t_phasor : t_object { - double phase; - float conv; - float a; /* scalar frequency */ -}; -static void *phasor_new(t_floatarg f) { - t_phasor *x = (t_phasor *)pd_new(phasor_class); - x->a = f; - inlet_new(x, x, &s_float, gensym("ft1")); - x->phase = 0; - x->conv = 0; - outlet_new(x, &s_signal); - return x; -} -static t_int *phasor_perform(t_int *w) { - PERFORM4ARGS(t_phasor *,x, t_float *,in, t_float *,out, int,n); - double dphase = x->phase + UNITBIT32; - union tabfudge tf; - int normhipart; - float conv = x->conv; - tf.d = UNITBIT32; - normhipart = tf.i[HIOFFSET]; - tf.d = dphase; - while (n--) { - tf.i[HIOFFSET] = normhipart; - dphase += *in++ * conv; - *out++ = tf.d - UNITBIT32; - tf.d = dphase; - } - tf.i[HIOFFSET] = normhipart; - x->phase = tf.d - UNITBIT32; - return w+5; -} -static void phasor_dsp(t_phasor *x, t_signal **sp) { - x->conv = 1./sp[0]->sr; - dsp_add(phasor_perform, 4, x, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void phasor_ft1(t_phasor *x, t_float f) { - x->phase = f; -} -static void phasor_setup() { - phasor_class = class_new2("phasor~",phasor_new,0,sizeof(t_phasor),0,"F"); - CLASS_MAINSIGNALIN(phasor_class, t_phasor, a); - class_addmethod2(phasor_class, phasor_dsp, "dsp",""); - class_addmethod2(phasor_class, phasor_ft1,"ft1","f"); -} -/* </Hoeldrich-version> */ - -/* ------------------------ cos~ ----------------------------- */ -float *cos_table; -static t_class *cos_class; -struct t_cos : t_object { - float a; -}; -static void *cos_new() { - t_cos *x = (t_cos *)pd_new(cos_class); - outlet_new(x,&s_signal); - x->a = 0; - return x; -} -static t_int *cos_perform(t_int *w) { - PERFORM3ARGS(t_float *,in, t_float *,out, int,n); - float *tab = cos_table, *addr, f1, f2, frac; - double dphase; - int normhipart; - union tabfudge tf; - tf.d = UNITBIT32; - normhipart = tf.i[HIOFFSET]; - -#if 0 /* this is the readable version of the code. */ - while (n--) { - dphase = double(*in++ * float(COSTABSIZE)) + UNITBIT32; - tf.d = dphase; - addr = tab + (tf.i[HIOFFSET] & (COSTABSIZE-1)); - tf.i[HIOFFSET] = normhipart; - frac = tf.d - UNITBIT32; - f1 = addr[0]; - f2 = addr[1]; - *out++ = f1 + frac * (f2 - f1); - } -#else /* this is the same, unwrapped by hand. */ - dphase = double(*in++ * float(COSTABSIZE)) + UNITBIT32; - tf.d = dphase; - addr = tab + (tf.i[HIOFFSET] & (COSTABSIZE-1)); - tf.i[HIOFFSET] = normhipart; - while (--n) { - dphase = double(*in++ * float(COSTABSIZE)) + UNITBIT32; - frac = tf.d - UNITBIT32; - tf.d = dphase; - f1 = addr[0]; - f2 = addr[1]; - addr = tab + (tf.i[HIOFFSET] & (COSTABSIZE-1)); - *out++ = f1 + frac * (f2 - f1); - tf.i[HIOFFSET] = normhipart; - } - frac = tf.d - UNITBIT32; - f1 = addr[0]; - f2 = addr[1]; - *out++ = f1 + frac * (f2 - f1); -#endif - return w+4; -} -static void cos_dsp(t_cos *x, t_signal **sp) { - dsp_add(cos_perform, 3, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void cos_maketable() { - float phsinc = (2. * 3.14159) / COSTABSIZE; - union tabfudge tf; - if (cos_table) return; - cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1)); - float phase=0; - float *fp = cos_table; - for (int i = COSTABSIZE + 1; i--; fp++, phase += phsinc) *fp = cos(phase); - /* here we check at startup whether the byte alignment - is as we declared it. If not, the code has to be recompiled the other way. */ - tf.d = UNITBIT32 + 0.5; - if ((unsigned)tf.i[LOWOFFSET] != 0x80000000) bug("cos~: unexpected machine alignment"); -} -static void cos_setup() { - cos_class = class_new2("cos~",cos_new,0,sizeof(t_cos),0,"F"); - CLASS_MAINSIGNALIN(cos_class, t_cos, a); - class_addmethod2(cos_class, cos_dsp, "dsp",""); - cos_maketable(); -} - -/* ------------------------ osc~ ----------------------------- */ -static t_class *osc_class; -struct t_osc : t_object { - double phase; - float conv; - float a; /* frequency if scalar */ -}; -static void *osc_new(t_floatarg f) { - t_osc *x = (t_osc *)pd_new(osc_class); - x->a = f; - outlet_new(x,&s_signal); - inlet_new(x, x, &s_float, gensym("ft1")); - inlet_settip(x->inlet,gensym("phase")); - x->phase = 0; - x->conv = 0; - return x; -} -static t_int *osc_perform(t_int *w) { - PERFORM4ARGS(t_osc *,x, t_float *,in, t_float *,out, int,n); - float *tab = cos_table, *addr, f1, f2, frac; - double dphase = x->phase + UNITBIT32; - int normhipart; - union tabfudge tf; - float conv = x->conv; - tf.d = UNITBIT32; - normhipart = tf.i[HIOFFSET]; - tf.d = dphase; - dphase += *in++ * conv; - addr = tab + (tf.i[HIOFFSET] & (COSTABSIZE-1)); - tf.i[HIOFFSET] = normhipart; - frac = tf.d - UNITBIT32; - while (--n) { - tf.d = dphase; - f1 = addr[0]; - dphase += *in++ * conv; - f2 = addr[1]; - addr = tab + (tf.i[HIOFFSET] & (COSTABSIZE-1)); - tf.i[HIOFFSET] = normhipart; - *out++ = f1 + frac * (f2 - f1); - frac = tf.d - UNITBIT32; - } - f1 = addr[0]; - f2 = addr[1]; - *out++ = f1 + frac * (f2 - f1); - tf.d = UNITBIT32 * COSTABSIZE; - normhipart = tf.i[HIOFFSET]; - tf.d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32); - tf.i[HIOFFSET] = normhipart; - x->phase = tf.d - UNITBIT32 * COSTABSIZE; - return w+5; -} -static void osc_dsp(t_osc *x, t_signal **sp) { - x->conv = COSTABSIZE/sp[0]->sr; - dsp_add(osc_perform, 4, x, sp[0]->v, sp[1]->v, sp[0]->n); -} -static void osc_ft1(t_osc *x, t_float f) {x->phase = COSTABSIZE * f;} -static void osc_setup() { - osc_class = class_new2("osc~",osc_new,0,sizeof(t_osc),0,"F"); - CLASS_MAINSIGNALIN(osc_class, t_osc, a); - class_addmethod2(osc_class, osc_dsp, "dsp",""); - class_addmethod2(osc_class, osc_ft1, "ft1","f"); - class_settip(osc_class,gensym("frequency")); - cos_maketable(); -} - -/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */ -struct t_vcfctl { - float re; - float im; - float q; - float isr; -}; -struct t_sigvcf : t_object { - t_vcfctl cspace; - t_vcfctl *ctl; - float a; -}; -t_class *sigvcf_class; -static void *sigvcf_new(t_floatarg q) { - t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class); - inlet_new(x, x, &s_signal, &s_signal); - inlet_new(x, x, &s_float, gensym("ft1")); - outlet_new(x, &s_signal); - outlet_new(x, &s_signal); - x->ctl = &x->cspace; - x->cspace.re = 0; - x->cspace.im = 0; - x->cspace.q = q; - x->cspace.isr = 0; - x->a = 0; - return x; -} -static void sigvcf_ft1(t_sigvcf *x, t_floatarg f) { - x->ctl->q = (f > 0 ? f : 0.f); -} -static t_int *sigvcf_perform(t_int *w) { - PERFORM6ARGS(float *,in1, float *,in2, float *,out1, float *,out2, t_vcfctl *,c, int,n); - float re = c->re, re2; - float im = c->im; - float q = c->q; - float qinv = (q > 0? 1.0f/q : 0); - float ampcorrect = 2.0f - 2.0f / (q + 2.0f); - float isr = c->isr; - float coefr, coefi; - float *tab = cos_table, *addr, f1, f2, frac; - double dphase; - int normhipart, tabindex; - union tabfudge tf; - tf.d = UNITBIT32; - normhipart = tf.i[HIOFFSET]; - for (int i = 0; i < n; i++) { - float cf, cfindx, r, oneminusr; - cf = *in2++ * isr; - if (cf < 0) cf = 0; - cfindx = cf * (float)(COSTABSIZE/6.28318f); - r = (qinv > 0 ? 1 - cf * qinv : 0); - if (r < 0) r = 0; - oneminusr = 1.0f - r; - dphase = ((double)(cfindx)) + UNITBIT32; - tf.d = dphase; - tabindex = tf.i[HIOFFSET] & (COSTABSIZE-1); - addr = tab + tabindex; - tf.i[HIOFFSET] = normhipart; - frac = tf.d - UNITBIT32; - f1 = addr[0]; f2 = addr[1]; coefr = r * (f1 + frac * (f2 - f1)); addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1)); - f1 = addr[0]; f2 = addr[1]; coefi = r * (f1 + frac * (f2 - f1)); - f1 = *in1++; - re2 = re; - *out1++ = re = ampcorrect * oneminusr * f1 + coefr * re2 - coefi * im; - *out2++ = im = coefi * re2 + coefr * im; - } - if (PD_BIGORSMALL(re)) re = 0; - if (PD_BIGORSMALL(im)) im = 0; - c->re = re; - c->im = im; - return w+7; -} -static void sigvcf_dsp(t_sigvcf *x, t_signal **sp) { - x->ctl->isr = 6.28318f/sp[0]->sr; - dsp_add(sigvcf_perform, 6, sp[0]->v, sp[1]->v, sp[2]->v, sp[3]->v, x->ctl, sp[0]->n); - -} -void sigvcf_setup() { - sigvcf_class = class_new2("vcf~",sigvcf_new,0,sizeof(t_sigvcf),0,"F"); - CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, a); - class_addmethod2(sigvcf_class, sigvcf_dsp, "dsp",""); - class_addmethod2(sigvcf_class, sigvcf_ft1, "ft1","f"); -} - -/* -------------------------- noise~ ------------------------------ */ -static t_class *noise_class; -struct t_noise : t_object { - int val; -}; -static void *noise_new() { - t_noise *x = (t_noise *)pd_new(noise_class); - static int init = 307; - x->val = (init *= 1319); - outlet_new(x, &s_signal); - return x; -} -static t_int *noise_perform(t_int *w) { - PERFORM3ARGS(t_float *,out, int *,vp, int,n); - int val = *vp; - while (n--) { - *out++ = ((float)((val & 0x7fffffff) - 0x40000000)) * (float)(1.0 / 0x40000000); - val = val * 435898247 + 382842987; - } - *vp = val; - return w+4; -} -static void noise_dsp(t_noise *x, t_signal **sp) { - dsp_add(noise_perform, 3, sp[0]->v, &x->val, sp[0]->n); -} -static void noise_setup() { - noise_class = class_new2("noise~",noise_new,0,sizeof(t_noise),0,""); - class_addmethod2(noise_class, noise_dsp, "dsp",""); -} -void builtins_dsp_setup() { - plus_setup(); minus_setup(); - times_setup(); over_setup(); - max_setup(); min_setup(); - lt_setup(); gt_setup(); - le_setup(); ge_setup(); - eq_setup(); ne_setup(); - //abs_setup(); - - tab_tilde_setup(); - tabosc4_tilde_setup(); - tabsend_setup(); - tabreceive_setup(); - tabread_setup(); - tabread4_setup(); - tabwrite_setup(); - - sig_tilde_setup(); - line_tilde_setup(); snapshot_tilde_setup(); - vline_tilde_setup(); vsnapshot_tilde_setup(); - env_tilde_setup(); - threshold_tilde_setup(); - - dac_setup(); - adc_setup(); - - sigdelwrite_setup(); - sigdelread_setup(); - sigvd_setup(); - - sigframp_setup(); -#ifdef HAVE_LIBFFTW3F - sigfftw_setup(); /* added by Tim Blechmann to support fftw */ -#else - sigfft_setup(); -#endif /* HAVE_LIBFFTW3F */ - - sighip_setup(); - siglop_setup(); - sigbp_setup(); - sigbiquad_setup(); - sigsamphold_setup(); - sigr_setup(); - sigc_setup(); - - sigsend_setup(); - sigreceive_setup(); - sigcatch_setup(); - sigthrow_setup(); - - clip_setup(); - sigsqrt_setup(); - sigwrap_setup(); - mtof_tilde_setup(); - print_setup(); - bang_tilde_setup(); - - phasor_setup(); - cos_setup(); - osc_setup(); - sigvcf_setup(); - noise_setup(); -} diff --git a/desiredata/src/config.h.in b/desiredata/src/config.h.in deleted file mode 100644 index 33d56bc3..00000000 --- a/desiredata/src/config.h.in +++ /dev/null @@ -1,5 +0,0 @@ - -#undef HAVE_ALLOCA -#undef HAVE_ALLOCA_H -#undef HAVE_ASPRINTF -#undef HAVE_VASPRINTF diff --git a/desiredata/src/configure b/desiredata/src/configure deleted file mode 100755 index 16cfc6ae..00000000 --- a/desiredata/src/configure +++ /dev/null @@ -1,8086 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63. -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell bug-autoconf@gnu.org about your system, - echo including any error possibly output before this message. - echo This can help us improve future autoconf versions. - echo Configuration will now proceed without shell functions. -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 </dev/null 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="kernel.c" -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_subst_vars='LTLIBOBJS -LIBOBJS -ALLOCA -EGREP -GREP -CPP -SET_MAKE -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -OBJEXT -EXEEXT -ac_ct_CC -LDFLAGS -CFLAGS -CC -STRIP -WSTRIP -EXE -WLIB -WATCHDOG -LDSOFLAGS -LIBSUFFIX -EXTERNTARGET -STRIPFLAG -MIDISRC -AUDIOSRC -USE_DEBUG_CFLAGS -EXT -MORECFLAGS -CPPFLAGS -fftw -portmidi -portaudio -jack -alsa -oss -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_alsa -enable_jack -enable_portaudio -enable_portmidi -enable_debug -enable_static -enable_fftw -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 - { (exit 1); exit 1; }; } - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { $as_echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { $as_echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 - { (exit 1); exit 1; }; } ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { $as_echo "$as_me: error: working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-oss audio via OSS - --enable-alsa audio via ALSA - --enable-jack audio via JACK - --enable-portaudio audio via PortAudio - --enable-portmidi MIDI via PortMidi - --enable-debug debugging support - --enable-static link statically - --enable-fftw use FFTW package - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -configure -generated by GNU Autoconf 2.63 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.63. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test -r "$ac_site_file"; then - { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -oss=yes - -alsa=yes - -jack=yes - -portaudio=yes - -portmidi=yes - -fftw=yes - - - - -USE_DEBUG_CFLAGS=no - - - - - - - - - - - - - -ac_config_headers="$ac_config_headers config.h:config.h.in" - - -# Check whether --enable-alsa was given. -if test "${enable_alsa+set}" = set; then - enableval=$enable_alsa; alsa=$enableval -fi - -# Check whether --enable-alsa was given. -if test "${enable_alsa+set}" = set; then - enableval=$enable_alsa; alsa=$enableval -fi - -# Check whether --enable-jack was given. -if test "${enable_jack+set}" = set; then - enableval=$enable_jack; jack=$enableval -fi - -# Check whether --enable-portaudio was given. -if test "${enable_portaudio+set}" = set; then - enableval=$enable_portaudio; portaudio=$enableval -fi - -# Check whether --enable-portmidi was given. -if test "${enable_portmidi+set}" = set; then - enableval=$enable_portmidi; portmidi=$enableval -fi - -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then - enableval=$enable_debug; USE_DEBUG_CFLAGS=$enableval -fi - -# Check whether --enable-static was given. -if test "${enable_static+set}" = set; then - enableval=$enable_static; static=$enableval -fi - -# Check whether --enable-fftw was given. -if test "${enable_fftw+set}" = set; then - enableval=$enable_fftw; fftw=$enableval -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:$LINENO: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:$LINENO: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:$LINENO: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:$LINENO: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } - -# Provide some information about the compiler. -$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi - -{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -if test -z "$ac_file"; then - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; }; } -fi - -ac_exeext=$ac_cv_exeext - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } - fi - fi -fi -{ $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -rm -f conftest$ac_cv_exeext -{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_compiler_gnu=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_c89=$ac_arg -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:$LINENO: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:$LINENO: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - -done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:$LINENO: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:$LINENO: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -{ $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if test "${ac_cv_c_const+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset cs; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_c_const=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_const=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const /**/ -_ACEOF - -fi - - -{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -{ $as_echo "$as_me:$LINENO: checking for pid_t" >&5 -$as_echo_n "checking for pid_t... " >&6; } -if test "${ac_cv_type_pid_t+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_type_pid_t=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if (sizeof (pid_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if (sizeof ((pid_t))) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_pid_t=yes -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 -$as_echo "$ac_cv_type_pid_t" >&6; } -if test "x$ac_cv_type_pid_t" = x""yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -{ $as_echo "$as_me:$LINENO: checking for size_t" >&5 -$as_echo_n "checking for size_t... " >&6; } -if test "${ac_cv_type_size_t+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_type_size_t=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if (sizeof (size_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if (sizeof ((size_t))) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_size_t=yes -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -$as_echo "$ac_cv_type_size_t" >&6; } -if test "x$ac_cv_type_size_t" = x""yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -{ $as_echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if test "${ac_cv_header_time+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <sys/types.h> -#include <sys/time.h> -#include <time.h> - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_time=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_time=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -cat >>confdefs.h <<\_ACEOF -#define TIME_WITH_SYS_TIME 1 -_ACEOF - -fi - - -{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - - - - - - - - -for ac_header in fcntl.h limits.h malloc.h sys/ioctl.h sys/time.h unistd.h bstring.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 -$as_echo_n "checking $ac_header usability... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 -$as_echo_n "checking $ac_header presence... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - - ;; -esac -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - -fi -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -if test $ac_cv_c_compiler_gnu = yes; then - { $as_echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 -$as_echo_n "checking whether $CC needs -traditional... " >&6; } -if test "${ac_cv_prog_gcc_traditional+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_pattern="Autoconf.*'x'" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <sgtty.h> -Autoconf TIOCGETP -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then - ac_cv_prog_gcc_traditional=yes -else - ac_cv_prog_gcc_traditional=no -fi -rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <termio.h> -Autoconf TCGETA -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - - fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 -$as_echo "$ac_cv_prog_gcc_traditional" >&6; } - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - -{ $as_echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -$as_echo_n "checking return type of signal handlers... " >&6; } -if test "${ac_cv_type_signal+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <sys/types.h> -#include <signal.h> - -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_signal=int -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_signal=void -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -$as_echo "$ac_cv_type_signal" >&6; } - -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal -_ACEOF - - - -for ac_func in vprintf -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -{ $as_echo "$as_me:$LINENO: checking for _doprnt" >&5 -$as_echo_n "checking for _doprnt... " >&6; } -if test "${ac_cv_func__doprnt+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define _doprnt innocuous__doprnt - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char _doprnt (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef _doprnt - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char _doprnt (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub__doprnt || defined __stub____doprnt -choke me -#endif - -int -main () -{ -return _doprnt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_func__doprnt=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func__doprnt=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 -$as_echo "$ac_cv_func__doprnt" >&6; } -if test "x$ac_cv_func__doprnt" = x""yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_DOPRNT 1 -_ACEOF - -fi - -fi -done - - - - - - -for ac_func in gettimeofday select socket strerror -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works -# for constant arguments. Useless! -{ $as_echo "$as_me:$LINENO: checking for working alloca.h" >&5 -$as_echo_n "checking for working alloca.h... " >&6; } -if test "${ac_cv_working_alloca_h+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <alloca.h> -int -main () -{ -char *p = (char *) alloca (2 * sizeof (int)); - if (p) return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_working_alloca_h=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_working_alloca_h=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 -$as_echo "$ac_cv_working_alloca_h" >&6; } -if test $ac_cv_working_alloca_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ALLOCA_H 1 -_ACEOF - -fi - -{ $as_echo "$as_me:$LINENO: checking for alloca" >&5 -$as_echo_n "checking for alloca... " >&6; } -if test "${ac_cv_func_alloca_works+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# ifdef HAVE_ALLOCA_H -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -int -main () -{ -char *p = (char *) alloca (1); - if (p) return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_func_alloca_works=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_alloca_works=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 -$as_echo "$ac_cv_func_alloca_works" >&6; } - -if test $ac_cv_func_alloca_works = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ALLOCA 1 -_ACEOF - -else - # The SVR3 libPW and SVR4 libucb both contain incompatible functions -# that cause trouble. Some versions do not even contain alloca or -# contain a buggy version. If you still want to use their alloca, -# use ar to extract alloca.o from them instead of compiling alloca.c. - -ALLOCA=\${LIBOBJDIR}alloca.$ac_objext - -cat >>confdefs.h <<\_ACEOF -#define C_ALLOCA 1 -_ACEOF - - -{ $as_echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 -$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } -if test "${ac_cv_os_cray+set}" = set; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#if defined CRAY && ! defined CRAY2 -webecray -#else -wenotbecray -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "webecray" >/dev/null 2>&1; then - ac_cv_os_cray=yes -else - ac_cv_os_cray=no -fi -rm -f conftest* - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 -$as_echo "$ac_cv_os_cray" >&6; } -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; do - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - -cat >>confdefs.h <<_ACEOF -#define CRAY_STACKSEG_END $ac_func -_ACEOF - - break -fi - - done -fi - -{ $as_echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 -$as_echo_n "checking stack direction for C alloca... " >&6; } -if test "${ac_cv_c_stack_direction+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_c_stack_direction=0 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -find_stack_direction () -{ - static char *addr = 0; - auto char dummy; - if (addr == 0) - { - addr = &dummy; - return find_stack_direction (); - } - else - return (&dummy > addr) ? 1 : -1; -} - -int -main () -{ - return find_stack_direction () < 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_stack_direction=1 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_c_stack_direction=-1 -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 -$as_echo "$ac_cv_c_stack_direction" >&6; } - -cat >>confdefs.h <<_ACEOF -#define STACK_DIRECTION $ac_cv_c_stack_direction -_ACEOF - - -fi - - - -for ac_func in asprintf -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -for ac_func in vasprintf -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -# audio APIs may accumulate, but there must be only one MIDI API (??) -AUDIOSRC="" -MIDISRC="s_midi_none.c" - -WLIB="" -STRIP="meuhhhhh" - -if test "$USE_OS" = ""; then - USE_OS=$(uname -s) -fi - -if test $USE_OS = Linux; then - LDFLAGS="-Wl,--export-dynamic " - EXT=pd_linux - LIBSUFFIX=.so - CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD" - MORECFLAGS="-fno-strict-aliasing" - STRIPFLAG=-s - STRIP="echo" - LDSOFLAGS="-shared" - WATCHDOG=pd-watchdog - EXE="" - WSTRIP="" -fi - -if test $USE_OS = Darwin; then - LDFLAGS="" - EXT=pd_darwin - LIBSUFFIX=.dylib - CPPFLAGS="-DMACOSX -DUNISTD -I/usr/X11R6/include -DPA_USE_COREAUDIO" - CPPFLAGS=$CPPFLAGS" -DDL_OPEN" # 0.40 - MORECFLAGS="" - STRIPFLAG="" -# LDSOFLAGS="-dylib -bundle -flat_namespace -undefined suppress" -# LDSOFLAGS="-dylib -flat_namespace" -# Charles Turner told me to use this: - LDSOFLAGS="-dynamiclib -Wl,-single_module" - EXTERNTARGET=pd_darwin -### this comes from pd 0.40 -# if test `uname -r` = 7.9.0; then -# CPPFLAGS=$CPPFLAGS" -DMACOSX3" -# EXTERNTARGET=d_ppc -# else -# CPPFLAGS=$CPPFLAGS" -isysroot /Developer/SDKs/MacOSX10.4u.sdk" -# MORECFLAGS=$MORECFLAGS" -arch i386 -arch ppc" -# EXTERNTARGET=d_fat -# LDFLAGS=$LDFLAGS" -arch i386 -arch ppc" -# fi - WATCHDOG=pd-watchdog - EXE="" - WSTRIP="" -fi - -if test $(echo $USE_OS | cut -f1 -d_) = CYGWIN; then - LDFLAGS="-Wl,--export-dynamic " - EXT=dll - LIBSUFFIX=.dll - CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD" - MORECFLAGS="-fno-strict-aliasing" - STRIPFLAG=-s - LDSOFLAGS="-shared" - EXE=.exe - WSTRIP="" -fi - -if test $(echo $USE_OS | cut -f1 -d_) = MINGW32; then - LDFLAGS="-lm -lpthreadGC2 -lwsock32 -lwinmm -lole32 -L../src -lpd" -# LDFLAGS="-lm /home/matju/pthreads-mingw/lib/libpthreadGC2.a -lwsock32 -lwinmm -lole32 -L../src -lpd" - EXT=dll - LIBSUFFIX=.dll - CPPFLAGS="-DMSW \ - -DPD_INTERNAL -DPD " - MORECFLAGS="-mms-bitfields" - STRIPFLAG=-s - LDSOFLAGS="-shared" - AUDIOSRC="s_audio_mmio.c" - MIDISRC="s_midi_mmio.c" - STRIP="strip --strip-unneeded -R .note -R .comment" - EXPORT="-Wl,--export-all-symbols -Wl,--out-implib=pd.a" - WLIB=$WLIB"$LDFLAGS $EXPORT; $STRIP libpd.dll" - EXE=.exe - WATCHDOG=pd.com - WSTRIP=$STRIP $DESTDIR$bindir/pd.exe -fi - -if test `uname -m` = x86_64; then - MORECFLAGS=$MORECFLAGS" -fPIC" -fi - -if test "$static" = yes; then LDFLAGS="$LDFLAGS -static"; fi - -{ $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_dl_dlopen=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then - LDFLAGS="$LDFLAGS -ldl" -else - echo "dynamic link support required" || exit 1 -fi - -{ $as_echo "$as_me:$LINENO: checking for sin in -lffm" >&5 -$as_echo_n "checking for sin in -lffm... " >&6; } -if test "${ac_cv_lib_ffm_sin+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lffm $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sin (); -int -main () -{ -return sin (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_ffm_sin=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_ffm_sin=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ffm_sin" >&5 -$as_echo "$ac_cv_lib_ffm_sin" >&6; } -if test "x$ac_cv_lib_ffm_sin" = x""yes; then - LDFLAGS="$LDFLAGS -lffm" -fi - -{ $as_echo "$as_me:$LINENO: checking for sin in -lm" >&5 -$as_echo_n "checking for sin in -lm... " >&6; } -if test "${ac_cv_lib_m_sin+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sin (); -int -main () -{ -return sin (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_m_sin=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_m_sin=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_m_sin" >&5 -$as_echo "$ac_cv_lib_m_sin" >&6; } -if test "x$ac_cv_lib_m_sin" = x""yes; then - LDFLAGS="$LDFLAGS -lm" -else - echo "math library required" || exit 1 -fi - -{ $as_echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_create (); -int -main () -{ -return pthread_create (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_pthread_pthread_create=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_pthread_pthread_create=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then - LDFLAGS="$LDFLAGS -lpthread" -else - echo "pthreads required" || exit 1 -fi - - -if test x$oss = xyes; then - if test "${ac_cv_header_linux_soundcard_h+set}" = set; then - { $as_echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5 -$as_echo_n "checking for linux/soundcard.h... " >&6; } -if test "${ac_cv_header_linux_soundcard_h+set}" = set; then - $as_echo_n "(cached) " >&6 -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5 -$as_echo "$ac_cv_header_linux_soundcard_h" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:$LINENO: checking linux/soundcard.h usability" >&5 -$as_echo_n "checking linux/soundcard.h usability... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <linux/soundcard.h> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:$LINENO: checking linux/soundcard.h presence" >&5 -$as_echo_n "checking linux/soundcard.h presence... " >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <linux/soundcard.h> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: present but cannot be compiled" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&2;} - { $as_echo "$as_me:$LINENO: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&5 -$as_echo "$as_me: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&2;} - - ;; -esac -{ $as_echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5 -$as_echo_n "checking for linux/soundcard.h... " >&6; } -if test "${ac_cv_header_linux_soundcard_h+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_header_linux_soundcard_h=$ac_header_preproc -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5 -$as_echo "$ac_cv_header_linux_soundcard_h" >&6; } - -fi -if test "x$ac_cv_header_linux_soundcard_h" = x""yes; then - oss="yes" -else - oss="no" -fi - - -fi - -if test x$alsa = xyes; then - { $as_echo "$as_me:$LINENO: checking for snd_pcm_info in -lasound" >&5 -$as_echo_n "checking for snd_pcm_info in -lasound... " >&6; } -if test "${ac_cv_lib_asound_snd_pcm_info+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lasound $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char snd_pcm_info (); -int -main () -{ -return snd_pcm_info (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_asound_snd_pcm_info=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_asound_snd_pcm_info=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_pcm_info" >&5 -$as_echo "$ac_cv_lib_asound_snd_pcm_info" >&6; } -if test "x$ac_cv_lib_asound_snd_pcm_info" = x""yes; then - LDFLAGS="$LDFLAGS -lasound" ; alsa="yes" -else - alsa="no" -fi - -fi - -if test x$jack = xyes; then - { $as_echo "$as_me:$LINENO: checking for shm_open in -lrt" >&5 -$as_echo_n "checking for shm_open in -lrt... " >&6; } -if test "${ac_cv_lib_rt_shm_open+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shm_open (); -int -main () -{ -return shm_open (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_rt_shm_open=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_rt_shm_open=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_rt_shm_open" >&5 -$as_echo "$ac_cv_lib_rt_shm_open" >&6; } -if test "x$ac_cv_lib_rt_shm_open" = x""yes; then - LIBS="$LIBS -lrt" -fi - - { $as_echo "$as_me:$LINENO: checking for jack_set_xrun_callback in -ljack" >&5 -$as_echo_n "checking for jack_set_xrun_callback in -ljack... " >&6; } -if test "${ac_cv_lib_jack_jack_set_xrun_callback+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ljack $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char jack_set_xrun_callback (); -int -main () -{ -return jack_set_xrun_callback (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_jack_jack_set_xrun_callback=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_jack_jack_set_xrun_callback=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_jack_jack_set_xrun_callback" >&5 -$as_echo "$ac_cv_lib_jack_jack_set_xrun_callback" >&6; } -if test "x$ac_cv_lib_jack_jack_set_xrun_callback" = x""yes; then - jack=xrun -else - jack=no -fi - - { $as_echo "$as_me:$LINENO: checking for jack_set_error_function in -ljack" >&5 -$as_echo_n "checking for jack_set_error_function in -ljack... " >&6; } -if test "${ac_cv_lib_jack_jack_set_error_function+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ljack $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char jack_set_error_function (); -int -main () -{ -return jack_set_error_function (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_jack_jack_set_error_function=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_jack_jack_set_error_function=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_jack_jack_set_error_function" >&5 -$as_echo "$ac_cv_lib_jack_jack_set_error_function" >&6; } -if test "x$ac_cv_lib_jack_jack_set_error_function" = x""yes; then - jack=yes -else - jack=no -fi - -fi - -if test x$portaudio = xyes; then - { $as_echo "$as_me:$LINENO: checking for Pa_GetDeviceCount in -lportaudio" >&5 -$as_echo_n "checking for Pa_GetDeviceCount in -lportaudio... " >&6; } -if test "${ac_cv_lib_portaudio_Pa_GetDeviceCount+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lportaudio $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char Pa_GetDeviceCount (); -int -main () -{ -return Pa_GetDeviceCount (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_portaudio_Pa_GetDeviceCount=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_portaudio_Pa_GetDeviceCount=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_portaudio_Pa_GetDeviceCount" >&5 -$as_echo "$ac_cv_lib_portaudio_Pa_GetDeviceCount" >&6; } -if test "x$ac_cv_lib_portaudio_Pa_GetDeviceCount" = x""yes; then - LDFLAGS=$LDFLAGS" -lportaudio" ; portaudio=yes -else - portaudio=no -fi - -fi - -if test x$portmidi = xyes; then - { $as_echo "$as_me:$LINENO: checking for Pt_Started in -lporttime" >&5 -$as_echo_n "checking for Pt_Started in -lporttime... " >&6; } -if test "${ac_cv_lib_porttime_Pt_Started___+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lporttime $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char Pt_Started (); -int -main () -{ -return Pt_Started (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_porttime_Pt_Started___=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_porttime_Pt_Started___=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_porttime_Pt_Started___" >&5 -$as_echo "$ac_cv_lib_porttime_Pt_Started___" >&6; } -if test "x$ac_cv_lib_porttime_Pt_Started___" = x""yes; then - LDFLAGS=$LDFLAGS" -lporttime" -fi - - { $as_echo "$as_me:$LINENO: checking for Pm_Initialize in -lportmidi" >&5 -$as_echo_n "checking for Pm_Initialize in -lportmidi... " >&6; } -if test "${ac_cv_lib_portmidi_Pm_Initialize+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lportmidi $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char Pm_Initialize (); -int -main () -{ -return Pm_Initialize (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_portmidi_Pm_Initialize=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_portmidi_Pm_Initialize=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_portmidi_Pm_Initialize" >&5 -$as_echo "$ac_cv_lib_portmidi_Pm_Initialize" >&6; } -if test "x$ac_cv_lib_portmidi_Pm_Initialize" = x""yes; then - LDFLAGS=$LDFLAGS" -lportmidi" ; portmidi=yes -else - portmidi=no -fi - -fi - -if test x$USE_DEBUG_CFLAGS = xyes; then - MORECFLAGS=$MORECFLAGS" -O1 -g" -else - MORECFLAGS=$MORECFLAGS" -O3 -funroll-loops -fomit-frame-pointer" -fi - -if test x$oss = xyes; then - AUDIOSRC=$AUDIOSRC" s_audio_oss.c" - MIDISRC="s_midi_oss.c" - CPPFLAGS=$CPPFLAGS" -DUSEAPI_OSS" -fi - -if test x$alsa = xyes; then - # the alsa midi is weird, it needs to have another MIDI module at once, so i put it in "audio" instead. - AUDIOSRC=$AUDIOSRC" s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c" - CPPFLAGS=$CPPFLAGS" -DPA_USE_ALSA -DUSEAPI_ALSA" - LDFLAGS=$LDFLAGS" -lasound" -fi - -if test x$jack = xyes; then - AUDIOSRC=$AUDIOSRC" s_audio_jack.c" - if test x$jack != xno; then - if test `uname -s` = Linux; then - if test x$jack = "xyes"; then LDFLAGS=$LDFLAGS" -lrt -ljack"; fi - if test x$jack = "xrun"; then LDFLAGS=$LDFLAGS" -lrt -ljack"; fi - fi - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -weak_framework Jackmp" # 0.40 - else - LIBS="$LIBS -ljack" - fi - CPPFLAGS=$CPPFLAGS" -DUSEAPI_JACK" - fi - if test x$jack = "xrun"; then CPPFLAGS=$CPPFLAGS" -DJACK_XRUN"; fi -fi - -if test x$portaudio = xyes; then - CPPFLAGS=$CPPFLAGS" -DUSEAPI_PORTAUDIO -DPA19" - AUDIOSRC=$AUDIOSRC" s_audio_portaudio.c" - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework Carbon" - fi -fi - -if test x$portmidi = xyes; then - MIDISRC="s_midi_pm.c" - MIDIFLAGS="-DUSEAPI_PORTMIDI" - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -framework CoreMIDI" - fi -fi - -CPPFLAGS=$CPPFLAGS" $MIDIFLAGS" - -if test x$fftw = "xyes"; then - { $as_echo "$as_me:$LINENO: checking for fftwf_forget_wisdom in -lfftw3f" >&5 -$as_echo_n "checking for fftwf_forget_wisdom in -lfftw3f... " >&6; } -if test "${ac_cv_lib_fftw3f_fftwf_forget_wisdom_+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lfftw3f $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char fftwf_forget_wisdom (); -int -main () -{ -return fftwf_forget_wisdom (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_fftw3f_fftwf_forget_wisdom_=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_fftw3f_fftwf_forget_wisdom_=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_fftw3f_fftwf_forget_wisdom_" >&5 -$as_echo "$ac_cv_lib_fftw3f_fftwf_forget_wisdom_" >&6; } -if test "x$ac_cv_lib_fftw3f_fftwf_forget_wisdom_" = x""yes; then - LDFLAGS=$LDFLAGS" -lfftw3f" -else - fftw=no -fi - -fi - - - { $as_echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if test "${ac_cv_c_bigendian+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - - # Check for potential -arch flags. It is not universal unless - # there are some -arch flags. Note that *ppc* also matches - # ppc64. This check is also rather less than ideal. - case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in #( - *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;; - esac -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - # It does; now see whether it defined to BIG_ENDIAN or not. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_c_bigendian=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_bigendian=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_c_bigendian=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_bigendian=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then - # Try to guess by grepping values from an object file. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_bigendian=no -else - $as_echo "$as_me: program exited with status $ac_status" >&5 -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_c_bigendian=yes -fi -rm -rf conftest.dSYM -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - bigendian=yes;; #( - no) - bigendian=no ;; #( - universal) - -cat >>confdefs.h <<\_ACEOF -#define AC_APPLE_UNIVERSAL_BUILD 1 -_ACEOF - - ;; #( - *) - bigendian=maybe ;; - esac - -if test x$bigendian = "xyes"; then - CPPFLAGS=$CPPFLAGS" -DBIGENDIAN" -fi - -ac_config_files="$ac_config_files makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - - -: ${CONFIG_STATUS=./config.status} -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.63. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTION]... [FILE]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to <bug-autoconf@gnu.org>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.63, - with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - { $as_echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { $as_echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.h.in" ;; - "makefile") CONFIG_FILES="$CONFIG_FILES makefile" ;; - - *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - $as_echo "$as_me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr='
' -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\).*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\).*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 -$as_echo "$as_me: error: could not setup config files machinery" >&2;} - { (exit 1); exit 1; }; } -_ACEOF - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then - break - elif $ac_last_try; then - { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 -$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 -$as_echo "$as_me: error: could not setup config headers machinery" >&2;} - { (exit 1); exit 1; }; } -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 -$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - ac_file_inputs="$ac_file_inputs '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; - esac \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ - || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 -$as_echo "$as_me: error: could not create $ac_file" >&2;} - { (exit 1); exit 1; }; } - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 -$as_echo "$as_me: error: could not create -" >&2;} - { (exit 1); exit 1; }; } - fi - ;; - - - esac - -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - diff --git a/desiredata/src/configure.in b/desiredata/src/configure.in deleted file mode 100644 index 79c5c45b..00000000 --- a/desiredata/src/configure.in +++ /dev/null @@ -1,258 +0,0 @@ -# NOTE!!! -# ./configure is not a source file (not written by someone), it's generated from -# ./configure.in, but it's still put in the CVS and releases so that people don't -# have to have autoconf installed. - -AC_INIT -AC_CONFIG_SRCDIR([kernel.c]) -AC_SUBST(oss, yes) -AC_SUBST(alsa, yes) -AC_SUBST(jack, yes) -AC_SUBST(portaudio, yes) -AC_SUBST(portmidi, yes) -AC_SUBST(fftw, yes) -AC_SUBST(CPPFLAGS) -AC_SUBST(MORECFLAGS) -AC_SUBST(EXT) -AC_SUBST(USE_DEBUG_CFLAGS, no) -AC_SUBST(AUDIOSRC) -AC_SUBST(MIDISRC) -AC_SUBST(STRIPFLAG) -AC_SUBST(EXTERNTARGET) -AC_SUBST(LIBSUFFIX) -AC_SUBST(LDSOFLAGS) -AC_SUBST(WATCHDOG) -AC_SUBST(WLIB) -AC_SUBST(EXE) -AC_SUBST(WSTRIP) -AC_SUBST(STRIP) - -AC_CONFIG_HEADERS([config.h:config.h.in]) - -dnl Checks for features. -AC_ARG_ENABLE(alsa, [ --enable-oss audio via OSS], alsa=$enableval) -AC_ARG_ENABLE(alsa, [ --enable-alsa audio via ALSA], alsa=$enableval) -AC_ARG_ENABLE(jack, [ --enable-jack audio via JACK], jack=$enableval) -AC_ARG_ENABLE(portaudio,[ --enable-portaudio audio via PortAudio], portaudio=$enableval) -AC_ARG_ENABLE(portmidi, [ --enable-portmidi MIDI via PortMidi], portmidi=$enableval) -AC_ARG_ENABLE(debug, [ --enable-debug debugging support], USE_DEBUG_CFLAGS=$enableval) -AC_ARG_ENABLE(static, [ --enable-static link statically], static=$enableval) -AC_ARG_ENABLE(fftw, [ --enable-fftw use FFTW package], fftw=$enableval) - -dnl Checks for programs. -AC_PROG_CC -AC_PROG_INSTALL -AC_PROG_MAKE_SET -AC_PROG_CPP - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_HEADER_TIME - -dnl Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h sys/time.h unistd.h bstring.h) - -dnl Checks for library functions. -AC_PROG_GCC_TRADITIONAL -AC_TYPE_SIGNAL -AC_FUNC_VPRINTF -AC_CHECK_FUNCS(gettimeofday select socket strerror) -AC_FUNC_ALLOCA - -dnl added for win32 (for patko) -AC_CHECK_FUNCS(asprintf) -AC_CHECK_FUNCS(vasprintf) - -# audio APIs may accumulate, but there must be only one MIDI API (??) -AUDIOSRC="" -MIDISRC="s_midi_none.c" - -WLIB="" -STRIP="meuhhhhh" - -if test "$USE_OS" = ""; then - USE_OS=$(uname -s) -fi - -if test $USE_OS = Linux; then - LDFLAGS="-Wl,--export-dynamic " - EXT=pd_linux - LIBSUFFIX=.so - CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD" - MORECFLAGS="-fno-strict-aliasing" - STRIPFLAG=-s - STRIP="echo" - LDSOFLAGS="-shared" - WATCHDOG=pd-watchdog - EXE="" - WSTRIP="" -fi - -if test $USE_OS = Darwin; then - LDFLAGS="" - EXT=pd_darwin - LIBSUFFIX=.dylib - CPPFLAGS="-DMACOSX -DUNISTD -I/usr/X11R6/include -DPA_USE_COREAUDIO" - CPPFLAGS=$CPPFLAGS" -DDL_OPEN" # 0.40 - MORECFLAGS="" - STRIPFLAG="" -# LDSOFLAGS="-dylib -bundle -flat_namespace -undefined suppress" -# LDSOFLAGS="-dylib -flat_namespace" -# Charles Turner told me to use this: - LDSOFLAGS="-dynamiclib -Wl,-single_module" - EXTERNTARGET=pd_darwin -### this comes from pd 0.40 -# if test `uname -r` = 7.9.0; then -# CPPFLAGS=$CPPFLAGS" -DMACOSX3" -# EXTERNTARGET=d_ppc -# else -# CPPFLAGS=$CPPFLAGS" -isysroot /Developer/SDKs/MacOSX10.4u.sdk" -# MORECFLAGS=$MORECFLAGS" -arch i386 -arch ppc" -# EXTERNTARGET=d_fat -# LDFLAGS=$LDFLAGS" -arch i386 -arch ppc" -# fi - WATCHDOG=pd-watchdog - EXE="" - WSTRIP="" -fi - -if test $(echo $USE_OS | cut -f1 -d_) = CYGWIN; then - LDFLAGS="-Wl,--export-dynamic " - EXT=dll - LIBSUFFIX=.dll - CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD" - MORECFLAGS="-fno-strict-aliasing" - STRIPFLAG=-s - LDSOFLAGS="-shared" - EXE=.exe - WSTRIP="" -fi - -if test $(echo $USE_OS | cut -f1 -d_) = MINGW32; then - LDFLAGS="-lm -lpthreadGC2 -lwsock32 -lwinmm -lole32" -# LDFLAGS="-lm /home/matju/pthreads-mingw/lib/libpthreadGC2.a -lwsock32 -lwinmm -lole32" - EXT=dll - LIBSUFFIX=.dll - CPPFLAGS="-DMSW -DPD_INTERNAL -DPD " - MORECFLAGS="-mms-bitfields" - STRIPFLAG=-s - LDSOFLAGS="-shared" - AUDIOSRC="s_audio_mmio.c" - MIDISRC="s_midi_mmio.c" - STRIP="strip --strip-unneeded -R .note -R .comment" - EXPORT="-Wl,--export-all-symbols -Wl,--out-implib=pd.a" - WLIB=$WLIB"$LDFLAGS $EXPORT; $STRIP libpd.dll" - EXE=.exe - WATCHDOG=pd.com - WSTRIP=$STRIP $DESTDIR$bindir/pd.exe -fi - -if test `uname -m` = x86_64; then - MORECFLAGS=$MORECFLAGS" -fPIC" -fi - -if test "$static" = yes; then LDFLAGS="$LDFLAGS -static"; fi - -dnl Checking for `dlopen' function in -ldl: -AC_CHECK_LIB(dl, dlopen,LDFLAGS="$LDFLAGS -ldl", echo "dynamic link support required" || exit 1) -dnl Checking for `sin' function in -lffm (ffm is the fast math library on the alpha) -AC_CHECK_LIB(ffm, sin,LDFLAGS="$LDFLAGS -lffm") -dnl Checking for `sin' function in -lm: -AC_CHECK_LIB(m, sin,LDFLAGS="$LDFLAGS -lm", echo "math library required" || exit 1) -dnl Checking for `pthread_create' function in -pthread -AC_CHECK_LIB(pthread, pthread_create,LDFLAGS="$LDFLAGS -lpthread", echo "pthreads required" || exit 1) - -if test x$oss = xyes; then - AC_CHECK_HEADER(linux/soundcard.h,oss="yes",oss="no") -fi - -dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. -if test x$alsa = xyes; then - AC_CHECK_LIB(asound,snd_pcm_info,LDFLAGS="$LDFLAGS -lasound" ; alsa="yes",alsa="no") -fi - -if test x$jack = xyes; then - AC_CHECK_LIB(rt,shm_open,LIBS="$LIBS -lrt") - AC_CHECK_LIB(jack,jack_set_xrun_callback,jack=xrun,jack=no) - AC_CHECK_LIB(jack,jack_set_error_function,jack=yes,jack=no) -fi - -dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. -if test x$portaudio = xyes; then - AC_CHECK_LIB(portaudio,Pa_GetDeviceCount,LDFLAGS=$LDFLAGS" -lportaudio" ; portaudio=yes,portaudio=no) -fi - -if test x$portmidi = xyes; then - AC_CHECK_LIB(porttime,Pt_Started ,LDFLAGS=$LDFLAGS" -lporttime") - AC_CHECK_LIB(portmidi,Pm_Initialize,LDFLAGS=$LDFLAGS" -lportmidi" ; portmidi=yes,portmidi=no) -fi - -if test x$USE_DEBUG_CFLAGS = xyes; then - MORECFLAGS=$MORECFLAGS" -O1 -g" -else - MORECFLAGS=$MORECFLAGS" -O3 -funroll-loops -fomit-frame-pointer" -fi - -if test x$oss = xyes; then - AUDIOSRC=$AUDIOSRC" s_audio_oss.c" - MIDISRC="s_midi_oss.c" - CPPFLAGS=$CPPFLAGS" -DUSEAPI_OSS" -fi - -if test x$alsa = xyes; then - # the alsa midi is weird, it needs to have another MIDI module at once, so i put it in "audio" instead. - AUDIOSRC=$AUDIOSRC" s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c" - CPPFLAGS=$CPPFLAGS" -DPA_USE_ALSA -DUSEAPI_ALSA" - LDFLAGS=$LDFLAGS" -lasound" -fi - -if test x$jack = xyes; then - AUDIOSRC=$AUDIOSRC" s_audio_jack.c" - if test x$jack != xno; then - if test `uname -s` = Linux; then - if test x$jack = "xyes"; then LDFLAGS=$LDFLAGS" -lrt -ljack"; fi - if test x$jack = "xrun"; then LDFLAGS=$LDFLAGS" -lrt -ljack"; fi - fi - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -weak_framework Jackmp" # 0.40 - else - LIBS="$LIBS -ljack" - fi - CPPFLAGS=$CPPFLAGS" -DUSEAPI_JACK" - fi - if test x$jack = "xrun"; then CPPFLAGS=$CPPFLAGS" -DJACK_XRUN"; fi -fi - -if test x$portaudio = xyes; then - CPPFLAGS=$CPPFLAGS" -DUSEAPI_PORTAUDIO -DPA19" - AUDIOSRC=$AUDIOSRC" s_audio_portaudio.c" - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework Carbon" - fi -fi - -if test x$portmidi = xyes; then - MIDISRC="s_midi_pm.c" - MIDIFLAGS="-DUSEAPI_PORTMIDI" - if test `uname -s` = Darwin; then - LDFLAGS=$LDFLAGS" -framework CoreMIDI" - fi -fi - -CPPFLAGS=$CPPFLAGS" $MIDIFLAGS" - -if test x$fftw = "xyes"; then - AC_CHECK_LIB(fftw3f, fftwf_forget_wisdom ,LDFLAGS=$LDFLAGS" -lfftw3f",fftw=no) -fi - -AC_C_BIGENDIAN(bigendian=yes,bigendian=no,bigendian=maybe) -if test x$bigendian = "xyes"; then - CPPFLAGS=$CPPFLAGS" -DBIGENDIAN" -fi - -AC_CONFIG_FILES([makefile]) -AC_OUTPUT - diff --git a/desiredata/src/d_fftroutine.c b/desiredata/src/d_fftroutine.c deleted file mode 100644 index 02f73287..00000000 --- a/desiredata/src/d_fftroutine.c +++ /dev/null @@ -1,999 +0,0 @@ -/*****************************************************************************/ -/* */ -/* Fast Fourier Transform */ -/* Network Abstraction, Definitions */ -/* Kevin Peterson, MIT Media Lab, EMS */ -/* UROP - Fall '86 */ -/* REV: 6/12/87(KHP) - To incorporate link list of different sized networks */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* added debug option 5/91 brown@nadia */ -/* change sign at AAA */ -/* */ -/* Fast Fourier Transform */ -/* FFT Network Interaction and Support Modules */ -/* Kevin Peterson, MIT Media Lab, EMS */ -/* UROP - Fall '86 */ -/* REV: 6/12/87(KHP) - Generalized to one procedure call with typed I/O */ -/* */ -/*****************************************************************************/ - -/* Overview: - - My realization of the FFT involves a representation of a network of - "butterfly" elements that takes a set of 'N' sound samples as input and - computes the discrete Fourier transform. This network consists of a - series of stages (log2 N), each stage consisting of N/2 parallel butterfly - elements. Consecutive stages are connected by specific, predetermined flow - paths, (see Oppenheim, Schafer for details) and each butterfly element has - an associated multiplicative coefficient. - - FFT NETWORK: - ----------- - ____ _ ____ _ ____ _ ____ _ ____ - o--| |o-| |-o| |o-| |-o| |o-| |-o| |o-| |-o| |--o - |reg1| | | |W^r1| | | |reg1| | | |W^r1| | | |reg1| - | | | | | | | | | | | | | | | | | | ..... - | | | | | | | | | | | | | | | | | | - o--|____|o-| |-o|____|o-| |-o|____|o-| |-o|____|o-| |-o|____|--o - | | | | | | | | - | | | | | | | | - ____ | | ____ | | ____ | | ____ | | ____ - o--| |o-| |-o| |o-| |-o| |o-| |-o| |o-| |-o| |--o - |reg2| | | |W^r2| | | |reg2| | | |W^r2| | | |reg2| - | | | | | | | | | | | | | | | | | | ..... - | | | | | | | | | | | | | | | | | | - o--|____|o-| |-o|____|o-| |-o|____|o-| |-o|____|o-| |-o|____|--o - | | | | | | | | - | | | | | | | | - : : : : : : : : : - : : : : : : : : : - : : : : : : : : : - : : : : : : : : : - : : : : : : : : : - - ____ | | ____ | | ____ | | ____ | | ____ - o--| |o-| |-o| |o-| |-o| |o-| |-o| |o-| |-o| |--o - |reg | | | |W^r | | | |reg | | | |W^r | | | |reg | - | N/2| | | | N/2| | | | N/2| | | | N/2| | | | N/2| ..... - | | | | | | | | | | | | | | | | | | - o--|____|o-|_|-o|____|o-|_|-o|____|o-|_|-o|____|o-|_|-o|____|--o - - ^ ^ ^ ^ - Initial | Bttrfly | Rd/Wrt | Bttrfly | Rd/Wrt - Buffer | | Register | | Register - |____________|____________|____________| - | - | - Interconnect - Paths - - The use of "in-place" computation permits one to use only one set of - registers realized by an array of complex number structures. To describe - the coefficients for each butterfly I am using a two dimensional array - (stage, butterfly) of complex numbers. The predetermined stage connections - will be described in a two dimensional array of indicies. These indicies - will be used to determine the order of reading at each stage of the - computation. -*/ - - -/*****************************************************************************/ -/* INCLUDE FILES */ -/*****************************************************************************/ - -#include <stdio.h> -#include <math.h> -#include <stdlib.h> - - /* the following is needed only to declare pd_fft() as exportable in MSW */ -#include "m_pd.h" - -/* some basic definitions */ -#ifndef BOOL -#define BOOL int -#define TRUE 1 -#define FALSE 0 -#endif - -#define SAMPLE float /* data type used in calculation */ - -#define SHORT_SIZE sizeof(short) -#define INT_SIZE sizeof(int) -#define FLOAT_SIZE sizeof(float) -#define SAMPLE_SIZE sizeof(SAMPLE) -#define PNTR_SIZE sizeof(char *) - -#define PI 3.1415927 -#define TWO_PI 6.2831854 - -/* type definitions for I/O buffers */ -#define REAL 0 /* real only */ -#define IMAG 2 /* imaginary only */ -#define RECT 8 /* real and imaginary */ -#define MAG 16 /* magnitude only */ -#define PHASE 32 /* phase only */ -#define POLAR 64 /* magnitude and phase*/ - -/* scale definitions for I/O buffers */ -#define LINEAR 0 -#define DB 1 /* 20log10 */ - -/* transform direction definition */ -#define FORWARD 1 /* Forward FFT */ -#define INVERSE 2 /* Inverse FFT */ - -/* window type definitions */ -#define HANNING 1 -#define RECTANGULAR 0 - - - -/* network structure definition */ - -typedef struct Tfft_net { - int n; - int stages; - int bps; - int direction; - int window_type; - int *load_index; - SAMPLE *window, *inv_window; - SAMPLE *regr; - SAMPLE *regi; - SAMPLE **indexpr; - SAMPLE **indexpi; - SAMPLE **indexqr; - SAMPLE **indexqi; - SAMPLE *coeffr, *inv_coeffr; - SAMPLE *coeffi, *inv_coeffi; - struct Tfft_net *next; -} FFT_NET; - - -void cfft(int trnsfrm_dir, int npnt, int window, - float *source_buf, int source_form, int source_scale, - float *result_buf, int result_form, int result_scale, int debug); - - -/*****************************************************************************/ -/* GLOBAL DECLARATIONS */ -/*****************************************************************************/ - -static FFT_NET *firstnet; - -/* prototypes */ - -void net_alloc(FFT_NET *fft_net); -void net_dealloc(FFT_NET *fft_net); -int power_of_two(int n); -void create_hanning(SAMPLE *window, int n, SAMPLE scale); -void create_rectangular(SAMPLE *window, int n, SAMPLE scale); -void short_to_float(short *short_buf, float *float_buf, int n); -void load_registers(FFT_NET *fft_net, float *buf, int buf_form, - int buf_scale, int trnsfrm_dir); -void compute_fft(FFT_NET *fft_net); -void store_registers(FFT_NET *fft_net, float *buf, int buf_form, - int buf_scale, int debug); -void build_fft_network(FFT_NET *fft_net, int n, int window_type); - -/*****************************************************************************/ -/* GENERALIZED FAST FOURIER TRANSFORM MODULE */ -/*****************************************************************************/ - -void cfft(int trnsfrm_dir, int npnt, int window, - float *source_buf, int source_form, int source_scale, - float *result_buf, int result_form, int result_scale, int debug) - -/* modifies: result_buf - effects: Computes npnt FFT specified by form, scale, and dir parameters. - Source samples (single precision float) are taken from soure_buf and - the transfrmd representation is stored in result_buf (single precision - float). The parameters are defined as follows: - - trnsfrm_dir = FORWARD | INVERSE - npnt = 2^k for some any positive integer k - window = HANNING | RECTANGULAR - (RECT = real and imag parts, POLAR = magnitude and phase) - source_form = REAL | IMAG | RECT | POLAR - result_form = REAL | IMAG | RECT | MAG | PHASE | POLAR - xxxxxx_scale= LINEAR | DB ( 20log10 |mag| ) - - The input/output buffers are stored in a form appropriate to the type. - For example: REAL => {real, real, real ...}, - MAG => {mag, mag, mag, ... }, - RECT => {real, imag, real, imag, ... }, - POLAR => {mag, phase, mag, phase, ... }. - - To look at the magnitude (in db) of a 1024 point FFT of a real time - signal we have: - - fft(FORWARD, 1024, RECTANGULAR, input, REAL, LINEAR, output, MAG, DB) - - All possible input and output combinations are possible given the - choice of type and scale parameters. -*/ - -{ - FFT_NET *thisnet = (FFT_NET *)0; - FFT_NET *lastnet = (FFT_NET *)0; - - /* A linked list of fft networks of different sizes is maintained to - avoid building with every call. The network is built on the first - call but reused for subsequent calls requesting the same size - transformation. - */ - - thisnet=firstnet; - while (thisnet) { - if (!(thisnet->n == npnt) || !(thisnet->window_type == window)) { - /* current net doesn't match size or window type */ - lastnet=thisnet; - thisnet=thisnet->next; - continue; /* keep looking */ - } - - else { /* network matches desired size */ - load_registers(thisnet, source_buf, source_form, source_scale, - trnsfrm_dir); - compute_fft(thisnet); /* do transformation */ - store_registers(thisnet, result_buf, result_form, result_scale,debug); - return; - } - } - - /* none of existing networks match required size*/ - - if (lastnet) { /* add new network to end of list */ - thisnet = (FFT_NET *)malloc(sizeof(FFT_NET)); /* allocate */ - thisnet->next = 0; - lastnet->next = thisnet; /* add to end of list */ - } - else { /* first network to be created */ - thisnet=firstnet=(FFT_NET *)malloc(sizeof(FFT_NET)); /* alloc. */ - thisnet->next = 0; - } - - /* build new network and compute transformation */ - build_fft_network(thisnet, npnt, window); - load_registers(thisnet, source_buf, source_form, source_scale, - trnsfrm_dir); - compute_fft(thisnet); - store_registers(thisnet, result_buf, result_form, result_scale,debug); - return; -} - -void fft_clear(void) - -/* effects: Deallocates all preserved FFT networks. Should be used when - finished with all computations. -*/ - -{ - FFT_NET *thisnet, *nextnet; - - if (firstnet) { - thisnet=firstnet; - do { - nextnet = thisnet->next; - net_dealloc(thisnet); - free((char *)thisnet); - } while ((thisnet = nextnet)); - } -} - - -/*****************************************************************************/ -/* NETWORK CONSTRUCTION */ -/*****************************************************************************/ - -void build_fft_network(FFT_NET *fft_net, int n, int window_type) - - -/* modifies:fft_net - effects: Constructs the fft network as described in fft.h. Butterfly - coefficients, read/write indicies, bit reversed load indicies, - and array allocations are computed. -*/ - -{ - int cntr, i, j, s; - int stages, bps; - int **p, **q, *pp, *qp; - SAMPLE two_pi_div_n = TWO_PI / n; - - - /* network definition */ - fft_net->n = n; - fft_net->bps = bps = n/2; - for (i = 0, j = n; j > 1; j >>= 1, i++) {} - fft_net->stages = stages = i; - fft_net->direction = FORWARD; - fft_net->window_type = window_type; - fft_net->next = (FFT_NET *)0; - - /* allocate registers, index, coefficient arrays */ - net_alloc(fft_net); - - - /* create appropriate windows */ - if (window_type==HANNING) { - create_hanning(fft_net->window, n, 1.); - create_hanning(fft_net->inv_window, n, 1./n); - } - else { - create_rectangular(fft_net->window, n, 1.); - create_rectangular(fft_net->inv_window, n, 1./n); - } - - - /* calculate butterfly coefficients */ { - - int num_diff_coeffs, power_inc, power; - SAMPLE *coeffpr = fft_net->coeffr; - SAMPLE *coeffpi = fft_net->coeffi; - SAMPLE *inv_coeffpr = fft_net->inv_coeffr; - SAMPLE *inv_coeffpi = fft_net->inv_coeffi; - - /* stage one coeffs are 1 + 0j */ - for (i = 0; i < bps; i++) { - *coeffpr = *inv_coeffpr = 1.; - *coeffpi = *inv_coeffpi = 0.; - coeffpr++; inv_coeffpr++; - coeffpi++; inv_coeffpi++; - } - - /* stage 2 to last stage coeffs need calculation */ - /* (1<<r <=> 2^r */ - for (s = 2; s <= stages; s++) { - - num_diff_coeffs = n / (1 << (stages - s + 1)); - power_inc = 1 << (stages -s); - cntr = 0; - - for (i = bps/num_diff_coeffs; i > 0; i--) { - - power = 0; - - for (j = num_diff_coeffs; j > 0; j--) { - *coeffpr = cos(two_pi_div_n*power); - *inv_coeffpr = cos(two_pi_div_n*power); -/* AAA change these signs */ *coeffpi = -sin(two_pi_div_n*power); -/* change back */ *inv_coeffpi = sin(two_pi_div_n*power); - power += power_inc; - coeffpr++; inv_coeffpr++; - coeffpi++; inv_coeffpi++; - } - } - } - } - - /* calculate network indicies: stage exchange indicies are - calculated and then used as offset values from the base - register locations. The final addresses are then stored in - fft_net. - */ { - - int index, inc; - SAMPLE **indexpr = fft_net->indexpr; - SAMPLE **indexpi = fft_net->indexpi; - SAMPLE **indexqr = fft_net->indexqr; - SAMPLE **indexqi = fft_net->indexqi; - SAMPLE *regr = fft_net->regr; - SAMPLE *regi = fft_net->regi; - - - /* allocate temporary 2d stage exchange index, 1d temp - load index */ - p = (int **)malloc(stages * PNTR_SIZE); - q = (int **)malloc(stages * PNTR_SIZE); - - for (s = 0; s < stages; s++) { - p[s] = (int *)malloc(bps * INT_SIZE); - q[s] = (int *)malloc(bps * INT_SIZE); - } - - /* calculate stage exchange indicies: */ - for (s = 0; s < stages; s++) { - pp = p[s]; - qp = q[s]; - inc = 1 << s; - cntr = 1 << (stages-s-1); - i = j = index = 0; - - do { - do { - qp[i] = index + inc; - pp[i++] = index++; - } while (++j < inc); - index = qp[i-1] + 1; - j = 0; - } while (--cntr); - } - - /* compute actual address values using indicies as offsets */ - for (s = 0; s < stages; s++) { - for (i = 0; i < bps; i++) { - *indexpr++ = regr + p[s][i]; - *indexpi++ = regi + p[s][i]; - *indexqr++ = regr + q[s][i]; - *indexqi++ = regi + q[s][i]; - } - } - } - - - /* calculate load indicies (bit reverse ordering) */ - /* bit reverse ordering achieved by passing normal - order indicies backwards through the network */ - - /* init to normal order indicies */ { - int *load_index,*load_indexp; - int *temp_indexp, *temp_index; - temp_index=temp_indexp=(int *)malloc(n * INT_SIZE); - - i = 0; j = n; - load_index = load_indexp = fft_net->load_index; - - while (j--) - *load_indexp++ = i++; - - /* pass indicies backwards through net */ - for (s = stages - 1; s > 0; s--) { - pp = p[s]; - qp = q[s]; - - for (i = 0; i < bps; i++) { - temp_index[pp[i]]=load_index[2*i]; - temp_index[qp[i]]=load_index[2*i+1]; - } - j = n; - load_indexp = load_index; - temp_indexp = temp_index; - while (j--) - *load_indexp++ = *temp_indexp++; - } - - /* free all temporary arrays */ - free((char *)temp_index); - for (s = 0; s < stages; s++) { - free((char *)p[s]);free((char *)q[s]); - } - free((char *)p);free((char *)q); - } -} - - - -/*****************************************************************************/ -/* REGISTER LOAD AND STORE */ -/*****************************************************************************/ - -void load_registers(FFT_NET *fft_net, float *buf, int buf_form, - int buf_scale, int trnsfrm_dir) - -/* effects: Multiplies the input buffer with the appropriate window and - stores the resulting values in the initial registers of the - network. Input buffer must contain values appropriate to form. - For RECT, the buffer contains real num. followed by imag num, - and for POLAR, it contains magnitude followed by phase. Pure - inputs are listed normally. Both LINEAR and DB scales are - interpreted. -*/ - -{ - int *load_index = fft_net->load_index; - SAMPLE *window; - int index, i = 0; - - if (trnsfrm_dir==FORWARD) window = fft_net->window; - else if (trnsfrm_dir==INVERSE) window = fft_net->inv_window; - else { - fprintf(stderr, "load_registers:illegal transform direction\n"); - exit(0); - } - fft_net->direction = trnsfrm_dir; - - switch(buf_scale) { - case LINEAR: { - - switch (buf_form) { - case REAL: { /* pure REAL */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)buf[index] * window[index]; - fft_net->regi[i]=0.; - i++; - } - } break; - - case IMAG: { /* pure IMAGinary */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=0; - fft_net->regi[i]=(SAMPLE)buf[index] * window[index]; - i++; - } - } break; - - case RECT: { /* both REAL and IMAGinary */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)buf[index*2] * window[index]; - fft_net->regi[i]=(SAMPLE)buf[index*2+1] * window[index]; - i++; - } - } break; - - case POLAR: { /* magnitude followed by phase */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)(buf[index*2] * cos(buf[index*2+1])) - * window[index]; - fft_net->regi[i]=(SAMPLE)(buf[index*2] * sin(buf[index*2+1])) - * window[index]; - i++; - } - } break; - - default: { - fprintf(stderr, "load_registers:illegal input form\n"); - exit(0); - } break; - } - } break; - - case DB: { - - switch (buf_form) { - case REAL: { /* log pure REAL */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)pow(10., (1./20.)*buf[index]) - * window[index]; /* window scaling after linearization */ - fft_net->regi[i]=0.; - i++; - } - } break; - - case IMAG: { /* log pure IMAGinary */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=0.; - fft_net->regi[i]=(SAMPLE)pow(10., (1./20.)*buf[index]) - * window[index]; - i++; - } - } break; - - case RECT: { /* log REAL and log IMAGinary */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)pow(10., (1./20.)*buf[index*2]) - * window[index]; - fft_net->regi[i]=(SAMPLE)pow(10., (1./20.)*buf[index*2+1]) - * window[index]; - i++; - } - } break; - - case POLAR: { /* log mag followed by phase */ - while (i < fft_net->n) { - index = load_index[i]; - fft_net->regr[i]=(SAMPLE)(pow(10., (1./20.)*buf[index*2]) - * cos(buf[index*2+1])) * window[index]; - fft_net->regi[i]=(SAMPLE)(pow(10., (1./20.)*buf[index*2]) - * sin(buf[index*2+1])) * window[index]; - i++; - } - } break; - - default: { - fprintf(stderr, "load_registers:illegal input form\n"); - exit(0); - } break; - } - } break; - - default: { - fprintf(stderr, "load_registers:illegal input scale\n"); - exit(0); - } break; - } -} - - -void store_registers(FFT_NET *fft_net, float *buf, int buf_form, - int buf_scale, int debug) - -/* modifies: buf - effects: Writes the final contents of the network registers into buf in - either linear or db scale, polar or rectangular form. If any of - the pure forms(REAL, IMAG, MAG, or PHASE) are used then only the - corresponding part of the registers is stored in buf. -*/ - -{ - int i; - SAMPLE real, imag; - int n; - - i = 0; - n = fft_net->n; - - switch (buf_scale) { - case LINEAR: { - - switch (buf_form) { - case REAL: { /* pure REAL */ - do { - *buf++ = (float)fft_net->regr[i]; - } while (++i < n); - } break; - - case IMAG: { /* pure IMAGinary */ - do { - *buf++ = (float)fft_net->regi[i]; - } while (++i < n); - } break; - - case RECT: { /* both REAL and IMAGinary */ - do { - *buf++ = (float)fft_net->regr[i]; - *buf++ = (float)fft_net->regi[i]; - } while (++i < n); - } break; - - case MAG: { /* magnitude only */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - *buf++ = (float)sqrt(real*real+imag*imag); - } while (++i < n); - } break; - - case PHASE: { /* phase only */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - if (real > .00001) - *buf++ = (float)atan2(imag, real); - else { /* deal with bad case */ - if (imag > 0){ *buf++ = PI / 2.; - if(debug) fprintf(stderr,"real=0 and imag > 0\n");} - else if (imag < 0){ *buf++ = -PI / 2.; - if(debug) fprintf(stderr,"real=0 and imag < 0\n");} - else { *buf++ = 0; - if(debug) fprintf(stderr,"real=0 and imag=0\n");} - } - } while (++i < n); - } break; - - case POLAR: { /* magnitude and phase */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - *buf++ = (float)sqrt(real*real+imag*imag); - if (real) /* a hack to avoid div by zero */ - *buf++ = (float)atan2(imag, real); - else { /* deal with bad case */ - if (imag > 0) *buf++ = PI / 2.; - else if (imag < 0) *buf++ = -PI / 2.; - else *buf++ = 0; - } - } while (++i < n); - } break; - - default: { - fprintf(stderr, "store_registers:illegal output form\n"); - exit(0); - } break; - } - } break; - - case DB: { - - switch (buf_form) { - case REAL: { /* real only */ - do { - *buf++ = (float)20.*log10(fft_net->regr[i]); - } while (++i < n); - } break; - - case IMAG: { /* imag only */ - do { - *buf++ = (float)20.*log10(fft_net->regi[i]); - } while (++i < n); - } break; - - case RECT: { /* real and imag */ - do { - *buf++ = (float)20.*log10(fft_net->regr[i]); - *buf++ = (float)20.*log10(fft_net->regi[i]); - } while (++i < n); - } break; - - case MAG: { /* magnitude only */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - *buf++ = (float)20.*log10(sqrt(real*real+imag*imag)); - } while (++i < n); - } break; - - case PHASE: { /* phase only */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - if (real) - *buf++ = (float)atan2(imag, real); - else { /* deal with bad case */ - if (imag > 0) *buf++ = PI / 2.; - else if (imag < 0) *buf++ = -PI / 2.; - else *buf++ = 0; - } - } while (++i < n); - } break; - - case POLAR: { /* magnitude and phase */ - do { - real = fft_net->regr[i]; - imag = fft_net->regi[i]; - *buf++ = (float)20.*log10(sqrt(real*real+imag*imag)); - if (real) - *buf++ = (float)atan2(imag, real); - else { /* deal with bad case */ - if (imag > 0) *buf++ = PI / 2.; - else if (imag < 0) *buf++ = -PI / 2.; - else *buf++ = 0; - } - } while (++i < n); - } break; - - default: { - fprintf(stderr, "store_registers:illegal output form\n"); - exit(0); - } break; - } - } break; - - default: { - fprintf(stderr, "store_registers:illegal output scale\n"); - exit(0); - } break; - } -} - - - -/*****************************************************************************/ -/* COMPUTE TRANSFORMATION */ -/*****************************************************************************/ - -void compute_fft(FFT_NET *fft_net) - - -/* modifies: fft_net - effects: Passes the values (already loaded) in the registers through - the network, multiplying with appropriate coefficients at each - stage. The fft result will be in the registers at the end of - the computation. The direction of the transformation is indicated - by the network flag 'direction'. The form of the computation is: - - X(pn) = X(p) + C*X(q) - X(qn) = X(p) - C*X(q) - - where X(pn,qn) represents the output of the registers at each stage. - The calculations are actually done in place. Register pointers are - used to speed up the calculations. - - Register and coefficient addresses involved in the calculations - are stored sequentially and are accessed as such. fft_net->indexp, - indexq contain pointers to the relevant addresses, and fft_net->coeffs, - inv_coeffs points to the appropriate coefficients at each stage of the - computation. -*/ - -{ - SAMPLE **xpr, **xpi, **xqr, **xqi, *cr, *ci; - int i; - SAMPLE tpr, tpi, tqr, tqi; - int bps = fft_net->bps; - int cnt = bps * (fft_net->stages - 1); - - /* predetermined register addresses and coefficients */ - xpr = fft_net->indexpr; - xpi = fft_net->indexpi; - xqr = fft_net->indexqr; - xqi = fft_net->indexqi; - - if (fft_net->direction==FORWARD) { /* FORWARD FFT coefficients */ - cr = fft_net->coeffr; - ci = fft_net->coeffi; - } - else { /* INVERSE FFT coefficients */ - cr = fft_net->inv_coeffr; - ci = fft_net->inv_coeffi; - } - - /* stage one coefficients are 1 + 0j so C*X(q)=X(q) */ - /* bps mults can be avoided */ - - for (i = 0; i < bps; i++) { - - /* add X(p) and X(q) */ - tpr = **xpr + **xqr; - tpi = **xpi + **xqi; - tqr = **xpr - **xqr; - tqi = **xpi - **xqi; - - /* exchange register with temp */ - **xpr = tpr; - **xpi = tpi; - **xqr = tqr; - **xqi = tqi; - - /* next set of register for calculations: */ - xpr++; xpi++; xqr++; xqi++; cr++; ci++; - - } - - for (i = 0; i < cnt; i++) { - - /* mult X(q) by coeff C */ - tqr = **xqr * *cr - **xqi * *ci; - tqi = **xqr * *ci + **xqi * *cr; - - /* exchange register with temp */ - **xqr = tqr; - **xqi = tqi; - - /* add X(p) and X(q) */ - tpr = **xpr + **xqr; - tpi = **xpi + **xqi; - tqr = **xpr - **xqr; - tqi = **xpi - **xqi; - - /* exchange register with temp */ - **xpr = tpr; - **xpi = tpi; - **xqr = tqr; - **xqi = tqi; - /* next set of register for calculations: */ - xpr++; xpi++; xqr++; xqi++; cr++; ci++; - } -} - - -/****************************************************************************/ -/* SUPPORT MODULES */ -/****************************************************************************/ - -void net_alloc(FFT_NET *fft_net) - - -/* effects: Allocates appropriate two dimensional arrays and assigns - correct internal pointers. -*/ - -{ - - int stages, bps, n; - - n = fft_net->n; - stages = fft_net->stages; - bps = fft_net->bps; - - - /* two dimensional arrays with elements stored sequentially */ - - fft_net->load_index = (int *)malloc(n * INT_SIZE); - fft_net->regr = (SAMPLE *)malloc(n * SAMPLE_SIZE); - fft_net->regi = (SAMPLE *)malloc(n * SAMPLE_SIZE); - fft_net->coeffr = (SAMPLE *)malloc(stages*bps*SAMPLE_SIZE); - fft_net->coeffi = (SAMPLE *)malloc(stages*bps*SAMPLE_SIZE); - fft_net->inv_coeffr = (SAMPLE *)malloc(stages*bps*SAMPLE_SIZE); - fft_net->inv_coeffi = (SAMPLE *)malloc(stages*bps*SAMPLE_SIZE); - fft_net->indexpr = (SAMPLE **)malloc(stages * bps * PNTR_SIZE); - fft_net->indexpi = (SAMPLE **)malloc(stages * bps * PNTR_SIZE); - fft_net->indexqr = (SAMPLE **)malloc(stages * bps * PNTR_SIZE); - fft_net->indexqi = (SAMPLE **)malloc(stages * bps * PNTR_SIZE); - - /* one dimensional load window */ - fft_net->window = (SAMPLE *)malloc(n * SAMPLE_SIZE); - fft_net->inv_window = (SAMPLE *)malloc(n * SAMPLE_SIZE); -} - -void net_dealloc(FFT_NET *fft_net) - - -/* effects: Deallocates given FFT network. -*/ - -{ - - free((char *)fft_net->load_index); - free((char *)fft_net->regr); - free((char *)fft_net->regi); - free((char *)fft_net->coeffr); - free((char *)fft_net->coeffi); - free((char *)fft_net->inv_coeffr); - free((char *)fft_net->inv_coeffi); - free((char *)fft_net->indexpr); - free((char *)fft_net->indexpi); - free((char *)fft_net->indexqr); - free((char *)fft_net->indexqi); - free((char *)fft_net->window); - free((char *)fft_net->inv_window); -} - - -BOOL power_of_two(int n) - -/* effects: Returns TRUE if n is a power of two, otherwise FALSE. -*/ - -{ - int i; - - for (i = n; i > 1; i >>= 1) - if (i & 1) return FALSE; /* more than one bit high */ - return TRUE; -} - - -void create_hanning(SAMPLE *window, int n, SAMPLE scale) - -/* effects: Fills the buffer window with a hanning window of the appropriate - size scaled by scale. -*/ - -{ - SAMPLE a, pi_div_n = PI/n; - int k; - - for (k=1; k <= n; k++) { - a = sin(k * pi_div_n); - *window++ = scale * a * a; - } -} - - -void create_rectangular(SAMPLE *window, int n, SAMPLE scale) - -/* effects: Fills the buffer window with a rectangular window of the - appropriate size of height scale. -*/ - -{ - while (n--) - *window++ = scale; -} - - -void short_to_float(short *short_buf, float *float_buf, int n) - -/* effects; Converts short_buf to floats and stores them in float_buf. -*/ - -{ - while (n--) { - *float_buf++ = (float)*short_buf++; - } -} - - -/* here's the meat: */ - -void pd_fft(float *buf, int npoints, int inverse) -{ - double renorm; - float *fp; - int i; - renorm = (inverse ? npoints : 1.); - cfft((inverse ? INVERSE : FORWARD), npoints, RECTANGULAR, - buf, RECT, LINEAR, buf, RECT, LINEAR, 0); - for (i = npoints << 1, fp = buf; i--; fp++) *fp *= renorm; -} diff --git a/desiredata/src/d_mayer_fft.c b/desiredata/src/d_mayer_fft.c deleted file mode 100644 index 563f02ba..00000000 --- a/desiredata/src/d_mayer_fft.c +++ /dev/null @@ -1,422 +0,0 @@ -/* -** FFT and FHT routines -** Copyright 1988, 1993; Ron Mayer -** -** mayer_fht(fz,n); -** Does a hartley transform of "n" points in the array "fz". -** mayer_fft(n,real,imag) -** Does a fourier transform of "n" points of the "real" and -** "imag" arrays. -** mayer_ifft(n,real,imag) -** Does an inverse fourier transform of "n" points of the "real" -** and "imag" arrays. -** mayer_realfft(n,real) -** Does a real-valued fourier transform of "n" points of the -** "real" array. The real part of the transform ends -** up in the first half of the array and the imaginary part of the -** transform ends up in the second half of the array. -** mayer_realifft(n,real) -** The inverse of the realfft() routine above. -** -** -** NOTE: This routine uses at least 2 patented algorithms, and may be -** under the restrictions of a bunch of different organizations. -** Although I wrote it completely myself, it is kind of a derivative -** of a routine I once authored and released under the GPL, so it -** may fall under the free software foundation's restrictions; -** it was worked on as a Stanford Univ project, so they claim -** some rights to it; it was further optimized at work here, so -** I think this company claims parts of it. The patents are -** held by R. Bracewell (the FHT algorithm) and O. Buneman (the -** trig generator), both at Stanford Univ. -** If it were up to me, I'd say go do whatever you want with it; -** but it would be polite to give credit to the following people -** if you use this anywhere: -** Euler - probable inventor of the fourier transform. -** Gauss - probable inventor of the FFT. -** Hartley - probable inventor of the hartley transform. -** Buneman - for a really cool trig generator -** Mayer(me) - for authoring this particular version and -** including all the optimizations in one package. -** Thanks, -** Ron Mayer; mayer@acuson.com -** -*/ - -/* This is a slightly modified version of Mayer's contribution; write -* msp@ucsd.edu for the original code. Kudos to Mayer for a fine piece -* of work. -msp -*/ - -#ifdef MSW -#pragma warning( disable : 4305 ) /* uncast const double to float */ -#pragma warning( disable : 4244 ) /* uncast double to float */ -#pragma warning( disable : 4101 ) /* unused local variables */ -#endif - -/* the following is needed only to declare pd_fft() as exportable in MSW */ -#include "m_pd.h" - -#define REAL float -#define GOOD_TRIG - -#ifdef GOOD_TRIG -#else -#define FAST_TRIG -#endif - -#if defined(GOOD_TRIG) -#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);} -#define TRIG_VARS \ - int t_lam=0; -#define TRIG_INIT(k,c,s) \ - { \ - int i; \ - for (i=2 ; i<=k ; i++) \ - {coswrk[i]=costab[i];sinwrk[i]=sintab[i];} \ - t_lam = 0; \ - c = 1; \ - s = 0; \ - } -#define TRIG_NEXT(k,c,s) \ - { \ - int i,j; \ - (t_lam)++; \ - for (i=0 ; !((1<<i)&t_lam) ; i++); \ - i = k-i; \ - s = sinwrk[i]; \ - c = coswrk[i]; \ - if (i>1) \ - { \ - for (j=k-i+2 ; (1<<j)&t_lam ; j++); \ - j = k - j; \ - sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \ - coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \ - } \ - } -#define TRIG_RESET(k,c,s) -#endif - -#if defined(FAST_TRIG) -#define TRIG_VARS \ - REAL t_c,t_s; -#define TRIG_INIT(k,c,s) \ - { \ - t_c = costab[k]; \ - t_s = sintab[k]; \ - c = 1; \ - s = 0; \ - } -#define TRIG_NEXT(k,c,s) \ - { \ - REAL t = c; \ - c = t*t_c - s*t_s; \ - s = t*t_s + s*t_c; \ - } -#define TRIG_RESET(k,c,s) -#endif - -static REAL halsec[20]= - { - 0, - 0, - .54119610014619698439972320536638942006107206337801, - .50979557910415916894193980398784391368261849190893, - .50241928618815570551167011928012092247859337193963, - .50060299823519630134550410676638239611758632599591, - .50015063602065098821477101271097658495974913010340, - .50003765191554772296778139077905492847503165398345, - .50000941253588775676512870469186533538523133757983, - .50000235310628608051401267171204408939326297376426, - .50000058827484117879868526730916804925780637276181, - .50000014706860214875463798283871198206179118093251, - .50000003676714377807315864400643020315103490883972, - .50000000919178552207366560348853455333939112569380, - .50000000229794635411562887767906868558991922348920, - .50000000057448658687873302235147272458812263401372 - }; -static REAL costab[20]= - { - .00000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768847, - .92387953251128675612818318939678828682241662586364, - .98078528040323044912618223613423903697393373089333, - .99518472667219688624483695310947992157547486872985, - .99879545620517239271477160475910069444320361470461, - .99969881869620422011576564966617219685006108125772, - .99992470183914454092164649119638322435060646880221, - .99998117528260114265699043772856771617391725094433, - .99999529380957617151158012570011989955298763362218, - .99999882345170190992902571017152601904826792288976, - .99999970586288221916022821773876567711626389934930, - .99999992646571785114473148070738785694820115568892, - .99999998161642929380834691540290971450507605124278, - .99999999540410731289097193313960614895889430318945, - .99999999885102682756267330779455410840053741619428 - }; -static REAL sintab[20]= - { - 1.0000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768846, - .38268343236508977172845998403039886676134456248561, - .19509032201612826784828486847702224092769161775195, - .09801714032956060199419556388864184586113667316749, - .04906767432741801425495497694268265831474536302574, - .02454122852291228803173452945928292506546611923944, - .01227153828571992607940826195100321214037231959176, - .00613588464915447535964023459037258091705788631738, - .00306795676296597627014536549091984251894461021344, - .00153398018628476561230369715026407907995486457522, - .00076699031874270452693856835794857664314091945205, - .00038349518757139558907246168118138126339502603495, - .00019174759731070330743990956198900093346887403385, - .00009587379909597734587051721097647635118706561284, - .00004793689960306688454900399049465887274686668768 - }; -static REAL coswrk[20]= - { - .00000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768847, - .92387953251128675612818318939678828682241662586364, - .98078528040323044912618223613423903697393373089333, - .99518472667219688624483695310947992157547486872985, - .99879545620517239271477160475910069444320361470461, - .99969881869620422011576564966617219685006108125772, - .99992470183914454092164649119638322435060646880221, - .99998117528260114265699043772856771617391725094433, - .99999529380957617151158012570011989955298763362218, - .99999882345170190992902571017152601904826792288976, - .99999970586288221916022821773876567711626389934930, - .99999992646571785114473148070738785694820115568892, - .99999998161642929380834691540290971450507605124278, - .99999999540410731289097193313960614895889430318945, - .99999999885102682756267330779455410840053741619428 - }; -static REAL sinwrk[20]= - { - 1.0000000000000000000000000000000000000000000000000, - .70710678118654752440084436210484903928483593768846, - .38268343236508977172845998403039886676134456248561, - .19509032201612826784828486847702224092769161775195, - .09801714032956060199419556388864184586113667316749, - .04906767432741801425495497694268265831474536302574, - .02454122852291228803173452945928292506546611923944, - .01227153828571992607940826195100321214037231959176, - .00613588464915447535964023459037258091705788631738, - .00306795676296597627014536549091984251894461021344, - .00153398018628476561230369715026407907995486457522, - .00076699031874270452693856835794857664314091945205, - .00038349518757139558907246168118138126339502603495, - .00019174759731070330743990956198900093346887403385, - .00009587379909597734587051721097647635118706561284, - .00004793689960306688454900399049465887274686668768 - }; - - -#define SQRT2_2 0.70710678118654752440084436210484 -#define SQRT2 2*0.70710678118654752440084436210484 - -void mayer_fht(REAL *fz, int n) -{ -/* REAL a,b; -REAL c1,s1,s2,c2,s3,c3,s4,c4; - REAL f0,g0,f1,g1,f2,g2,f3,g3; */ - int k,k1,k2,k3,k4,kx; - REAL *fi,*fn,*gi; - TRIG_VARS; - - for (k1=1,k2=0;k1<n;k1++) - { - REAL aa; - for (k=n>>1; (!((k2^=k)&k)); k>>=1) {} - if (k1>k2) - { - aa=fz[k1];fz[k1]=fz[k2];fz[k2]=aa; - } - } - for ( k=0 ; (1<<k)<n ; k++ ) {} - k &= 1; - if (k==0) - { - for (fi=fz,fn=fz+n;fi<fn;fi+=4) - { - REAL f0,f1,f2,f3; - f1 = fi[0 ]-fi[1 ]; - f0 = fi[0 ]+fi[1 ]; - f3 = fi[2 ]-fi[3 ]; - f2 = fi[2 ]+fi[3 ]; - fi[2 ] = (f0-f2); - fi[0 ] = (f0+f2); - fi[3 ] = (f1-f3); - fi[1 ] = (f1+f3); - } - } - else - { - for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8) - { - REAL bs1,bc1,bs2,bc2,bs3,bc3,bs4,bc4, - bg0,bf0,bf1,bg1,bf2,bg2,bf3,bg3; - bc1 = fi[0 ] - gi[0 ]; - bs1 = fi[0 ] + gi[0 ]; - bc2 = fi[2 ] - gi[2 ]; - bs2 = fi[2 ] + gi[2 ]; - bc3 = fi[4 ] - gi[4 ]; - bs3 = fi[4 ] + gi[4 ]; - bc4 = fi[6 ] - gi[6 ]; - bs4 = fi[6 ] + gi[6 ]; - bf1 = (bs1 - bs2); - bf0 = (bs1 + bs2); - bg1 = (bc1 - bc2); - bg0 = (bc1 + bc2); - bf3 = (bs3 - bs4); - bf2 = (bs3 + bs4); - bg3 = SQRT2*bc4; - bg2 = SQRT2*bc3; - fi[4 ] = bf0 - bf2; - fi[0 ] = bf0 + bf2; - fi[6 ] = bf1 - bf3; - fi[2 ] = bf1 + bf3; - gi[4 ] = bg0 - bg2; - gi[0 ] = bg0 + bg2; - gi[6 ] = bg1 - bg3; - gi[2 ] = bg1 + bg3; - } - } - if (n<16) return; - - do - { - REAL s1,c1; - int ii; - k += 2; - k1 = 1 << k; - k2 = k1 << 1; - k4 = k2 << 1; - k3 = k2 + k1; - kx = k1 >> 1; - fi = fz; - gi = fi + kx; - fn = fz + n; - do - { - REAL g0,f0,f1,g1,f2,g2,f3,g3; - f1 = fi[0 ] - fi[k1]; - f0 = fi[0 ] + fi[k1]; - f3 = fi[k2] - fi[k3]; - f2 = fi[k2] + fi[k3]; - fi[k2] = f0 - f2; - fi[0 ] = f0 + f2; - fi[k3] = f1 - f3; - fi[k1] = f1 + f3; - g1 = gi[0 ] - gi[k1]; - g0 = gi[0 ] + gi[k1]; - g3 = SQRT2 * gi[k3]; - g2 = SQRT2 * gi[k2]; - gi[k2] = g0 - g2; - gi[0 ] = g0 + g2; - gi[k3] = g1 - g3; - gi[k1] = g1 + g3; - gi += k4; - fi += k4; - } while (fi<fn); - TRIG_INIT(k,c1,s1); - for (ii=1;ii<kx;ii++) - { - REAL c2,s2; - TRIG_NEXT(k,c1,s1); - c2 = c1*c1 - s1*s1; - s2 = 2*(c1*s1); - fn = fz + n; - fi = fz +ii; - gi = fz +k1-ii; - do - { - REAL a,b,g0,f0,f1,g1,f2,g2,f3,g3; - b = s2*fi[k1] - c2*gi[k1]; - a = c2*fi[k1] + s2*gi[k1]; - f1 = fi[0 ] - a; - f0 = fi[0 ] + a; - g1 = gi[0 ] - b; - g0 = gi[0 ] + b; - b = s2*fi[k3] - c2*gi[k3]; - a = c2*fi[k3] + s2*gi[k3]; - f3 = fi[k2] - a; - f2 = fi[k2] + a; - g3 = gi[k2] - b; - g2 = gi[k2] + b; - b = s1*f2 - c1*g3; - a = c1*f2 + s1*g3; - fi[k2] = f0 - a; - fi[0 ] = f0 + a; - gi[k3] = g1 - b; - gi[k1] = g1 + b; - b = c1*g2 - s1*f3; - a = s1*g2 + c1*f3; - gi[k2] = g0 - a; - gi[0 ] = g0 + a; - fi[k3] = f1 - b; - fi[k1] = f1 + b; - gi += k4; - fi += k4; - } while (fi<fn); - } - TRIG_RESET(k,c1,s1); - } while (k4<n); -} - -void mayer_fft(int n, REAL *real, REAL *imag) -{ - REAL a,b,c,d; - REAL q,r,s,t; - int i,j,k; - for (i=1,j=n-1,k=n/2;i<k;i++,j--) { - a = real[i]; b = real[j]; q=a+b; r=a-b; - c = imag[i]; d = imag[j]; s=c+d; t=c-d; - real[i] = (q+t)*.5; real[j] = (q-t)*.5; - imag[i] = (s-r)*.5; imag[j] = (s+r)*.5; - } - mayer_fht(real,n); - mayer_fht(imag,n); -} - -void mayer_ifft(int n, REAL *real, REAL *imag) -{ - REAL a,b,c,d; - REAL q,r,s,t; - int i,j,k; - mayer_fht(real,n); - mayer_fht(imag,n); - for (i=1,j=n-1,k=n/2;i<k;i++,j--) { - a = real[i]; b = real[j]; q=a+b; r=a-b; - c = imag[i]; d = imag[j]; s=c+d; t=c-d; - imag[i] = (s+r)*0.5; imag[j] = (s-r)*0.5; - real[i] = (q-t)*0.5; real[j] = (q+t)*0.5; - } -} - -void mayer_realfft(int n, REAL *real) -{ - REAL a,b; - int i,j,k; - mayer_fht(real,n); - for (i=1,j=n-1,k=n/2;i<k;i++,j--) { - a = real[i]; - b = real[j]; - real[j] = (a-b)*0.5; - real[i] = (a+b)*0.5; - } -} - -void mayer_realifft(int n, REAL *real) -{ - REAL a,b; - int i,j,k; - for (i=1,j=n-1,k=n/2;i<k;i++,j--) { - a = real[i]; - b = real[j]; - real[j] = (a-b); - real[i] = (a+b); - } - mayer_fht(real,n); -} diff --git a/desiredata/src/d_soundfile.c b/desiredata/src/d_soundfile.c deleted file mode 100644 index d4162115..00000000 --- a/desiredata/src/d_soundfile.c +++ /dev/null @@ -1,2059 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* this file contains, first, a collection of soundfile access routines, a -sort of soundfile library. Second, the "soundfiler" object is defined which -uses the routines to read or write soundfiles, synchronously, from garrays. -These operations are not to be done in "real time" as they may have to wait -for disk accesses (even the write routine.) Finally, the realtime objects -readsf~ and writesf~ are defined which confine disk operations to a separate -thread so that they can be used in real time. The readsf~ and writesf~ -objects use Posix-like threads. */ - -/* threaded soundfiler by Tim Blechmann */ -// #define THREADED_SF - -#ifndef MSW -#include <unistd.h> -#include <fcntl.h> -#endif -#include <pthread.h> -#ifdef MSW -#include <io.h> -#endif -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#define a_symbol a_w.w_symbol -#define a_float a_w.w_float - -#define MAXSFCHANS 256 - -#ifdef _LARGEFILE64_SOURCE -# define open open64 -# define lseek lseek64 -#endif - -#if 0 -static bool debug=0; -#endif - -#define EAT_ARG(ATYPE,VAR) if (argc<1 || argv->a_type != ATYPE) goto usage; else {VAR = *argv++; argc--;} - -/***************** soundfile header structures ************************/ - -typedef unsigned short uint16; -typedef unsigned int uint32; /* long isn't 32-bit on amd64 */ - -#define FORMAT_WAVE 0 -#define FORMAT_AIFF 1 -#define FORMAT_NEXT 2 - -/* the NeXTStep sound header structure; can be big or little endian */ - -struct t_nextstep { - char fileid[4]; /* magic number '.snd' if file is big-endian */ - uint32 onset; /* byte offset of first sample */ - uint32 length; /* length of sound in bytes */ - uint32 format; /* format; see below */ - uint32 sr; /* sample rate */ - uint32 nchans; /* number of channels */ - char info[4]; /* comment */ -}; - -#define NS_FORMAT_LINEAR_16 3 -#define NS_FORMAT_LINEAR_24 4 -#define NS_FORMAT_FLOAT 6 -#define SCALE (1./(1024. * 1024. * 1024. * 2.)) - -/* the WAVE header. All Wave files are little endian. We assume - the "fmt" chunk comes first which is usually the case but perhaps not - always; same for AIFF and the "COMM" chunk. */ - -struct t_wave { - char fileid[4]; /* chunk id 'RIFF' */ - uint32 chunksize; /* chunk size */ - char waveid[4]; /* wave chunk id 'WAVE' */ - char fmtid[4]; /* format chunk id 'fmt ' */ - uint32 fmtchunksize; /* format chunk size */ - uint16 fmttag; /* format tag (WAV_INT etc) */ - uint16 nchannels; /* number of channels */ - uint32 samplespersec; /* sample rate in hz */ - uint32 navgbytespersec; /* average bytes per second */ - uint16 nblockalign; /* number of bytes per frame */ - uint16 nbitspersample; /* number of bits in a sample */ - char datachunkid[4]; /* data chunk id 'data' */ - uint32 datachunksize; /* length of data chunk */ -}; - -struct t_fmt { /* format chunk */ - uint16 fmttag; /* format tag, 1 for PCM */ - uint16 nchannels; /* number of channels */ - uint32 samplespersec; /* sample rate in hz */ - uint32 navgbytespersec; /* average bytes per second */ - uint16 nblockalign; /* number of bytes per frame */ - uint16 nbitspersample; /* number of bits in a sample */ -}; - -struct t_wavechunk { /* ... and the last two items */ - char id[4]; /* data chunk id, e.g., 'data' or 'fmt ' */ - uint32 size; /* length of data chunk */ -}; - -#define WAV_INT 1 -#define WAV_FLOAT 3 - -typedef unsigned char byte; - -/* the AIFF header. I'm assuming AIFC is compatible but don't really know that. */ - -struct t_datachunk { - char id[4]; // data chunk id 'SSND' - uint32 size; // length of data chunk - uint32 offset; // additional offset in bytes - uint32 block; // block size -}; - -struct t_comm { - uint16 nchannels; // number of channels - uint16 nframeshi; // # of sample frames (hi) - uint16 nframeslo; // # of sample frames (lo) - uint16 bitspersamp; // bits per sample - byte samprate[10];// sample rate, 80-bit float! -}; - -/* this version is more convenient for writing them out: */ -struct t_aiff { - char fileid[4]; // chunk id 'FORM' - uint32 chunksize; // chunk size - char aiffid[4]; // aiff chunk id 'AIFF' - char fmtid[4]; // format chunk id 'COMM' - uint32 fmtchunksize; // format chunk size, 18 - uint16 nchannels; // number of channels - uint16 nframeshi; // # of sample frames (hi) - uint16 nframeslo; // # of sample frames (lo) - uint16 bitspersamp; // bits per sample - byte samprate[10]; // sample rate, 80-bit float! -}; - -struct t_param { - int bytespersample; - int bigendian; - int nchannels; - long bytelimit; - int bytesperchannel() {return bytespersample * nchannels;} -}; - -#define AIFFHDRSIZE 38 /* probably not what sizeof() gives */ -#define AIFFPLUS (AIFFHDRSIZE + 16) /* header size including SSND chunk hdr */ -#define WHDR1 sizeof(t_nextstep) -#define WHDR2 (sizeof(t_wave) > WHDR1 ? sizeof (t_wave) : WHDR1) -#define WRITEHDRSIZE (AIFFPLUS > WHDR2 ? AIFFPLUS : WHDR2) -#define READHDRSIZE (16 > WHDR2 + 2 ? 16 : WHDR2 + 2) - -#ifdef MSW -#include <fcntl.h> -#define BINCREATE (_O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY) -#else -#define BINCREATE (O_WRONLY | O_CREAT | O_TRUNC) -#endif - -/* this routine returns 1 if the high order byte comes at the lower -address on our architecture (big-endianness.). It's 1 for Motorola, 0 for Intel: */ - -extern int garray_ambigendian(); - -/* byte swappers */ - -static uint32 swap4(uint32 n, int doit) { - if (doit) return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); - else return n; -} - -static uint16 swap2(uint32 n, int doit) { - if (doit) return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); - else return n; -} - -static void swapstring(char *foo, int doit) { - if (doit) { - char a = foo[0], b = foo[1], c = foo[2], d = foo[3]; - foo[0] = d; foo[1] = c; foo[2] = b; foo[3] = a; - } -} - -/******************** soundfile access routines **********************/ -/* This routine opens a file, looks for either a nextstep or "wave" header, -* seeks to end of it, and fills in bytes per sample and number of channels. -* Only 2- and 3-byte fixed-point samples and 4-byte floating point samples -* are supported. If "headersize" is nonzero, the -* caller should supply the number of channels, endinanness, and bytes per -* sample; the header is ignored. Otherwise, the routine tries to read the -* header and fill in the properties. -*/ - -int open_soundfile_via_fd(int fd, int headersize, t_param *p, long skipframes) { - int swap, sysrtn; - errno = 0; - t_param q; - q.bytelimit = 0x7fffffff; - if (headersize >= 0) { /* header detection overridden */ - q = *p; - } else { - char buf[MAXPDSTRING]; - int bytesread = read(fd, buf, READHDRSIZE); - int format; - if (bytesread < 4) goto badheader; - if (!strncmp(buf, ".snd", 4)) {format = FORMAT_NEXT; q.bigendian = 1;} - else if (!strncmp(buf, "dns.", 4)) {format = FORMAT_NEXT; q.bigendian = 0;} - else if (!strncmp(buf, "RIFF", 4)) { - if (bytesread < 12 || strncmp(buf + 8, "WAVE", 4)) goto badheader; - format = FORMAT_WAVE; q.bigendian = 0; - } - else if (!strncmp(buf, "FORM", 4)) { - if (bytesread < 12 || strncmp(buf + 8, "AIFF", 4)) goto badheader; - format = FORMAT_AIFF; q.bigendian = 1; - } else goto badheader; - swap = (q.bigendian != garray_ambigendian()); - if (format == FORMAT_NEXT) { /* nextstep header */ - if (bytesread < (int)sizeof(t_nextstep)) goto badheader; - q.nchannels = swap4(((t_nextstep *)buf)->nchans, swap); - format = swap4(((t_nextstep *)buf)->format, swap); - headersize = swap4(((t_nextstep *)buf)->onset, swap); - if (format == NS_FORMAT_LINEAR_16) q.bytespersample = 2; - else if (format == NS_FORMAT_LINEAR_24) q.bytespersample = 3; - else if (format == NS_FORMAT_FLOAT) q.bytespersample = 4; - else goto badheader; - q.bytelimit = 0x7fffffff; - } else if (format == FORMAT_WAVE) { /* wave header */ - /* This is awful. You have to skip over chunks, - except that if one happens to be a "fmt" chunk, you want to - find out the format from that one. The case where the - "fmt" chunk comes after the audio isn't handled. */ - headersize = 12; - if (bytesread < 20) goto badheader; - /* First we guess a number of channels, etc., in case there's - no "fmt" chunk to follow. */ - q.nchannels = 1; - q.bytespersample = 2; - /* copy the first chunk header to beginnning of buffer. */ - memcpy(buf, buf + headersize, sizeof(t_wavechunk)); - /* read chunks in loop until we get to the data chunk */ - while (strncmp(((t_wavechunk *)buf)->id, "data", 4)) { - long chunksize = swap4(((t_wavechunk *)buf)->size, swap), seekto = headersize + chunksize + 8, seekout; - if (!strncmp(((t_wavechunk *)buf)->id, "fmt ", 4)) { - long commblockonset = headersize + 8; - seekout = lseek(fd, commblockonset, SEEK_SET); - if (seekout != commblockonset) goto badheader; - if (read(fd, buf, sizeof(t_fmt)) < (int) sizeof(t_fmt)) goto badheader; - q.nchannels = swap2(((t_fmt *)buf)->nchannels, swap); - format = swap2(((t_fmt *)buf)->nbitspersample, swap); - if (format == 16) q.bytespersample = 2; - else if (format == 24) q.bytespersample = 3; - else if (format == 32) q.bytespersample = 4; - else goto badheader; - } - seekout = lseek(fd, seekto, SEEK_SET); - if (seekout != seekto) goto badheader; - if (read(fd, buf, sizeof(t_wavechunk)) < (int) sizeof(t_wavechunk)) goto badheader; - headersize = seekto; - } - q.bytelimit = swap4(((t_wavechunk *)buf)->size, swap); - headersize += 8; - } else { - /* AIFF. same as WAVE; actually predates it. Disgusting. */ - headersize = 12; - if (bytesread < 20) goto badheader; - /* First we guess a number of channels, etc., in case there's no COMM block to follow. */ - q.nchannels = 1; - q.bytespersample = 2; - /* copy the first chunk header to beginnning of buffer. */ - memcpy(buf, buf + headersize, sizeof(t_datachunk)); - /* read chunks in loop until we get to the data chunk */ - while (strncmp(((t_datachunk *)buf)->id, "SSND", 4)) { - long chunksize = swap4(((t_datachunk *)buf)->size, swap), seekto = headersize + chunksize + 8, seekout; - if (!strncmp(((t_datachunk *)buf)->id, "COMM", 4)) { - long commblockonset = headersize + 8; - seekout = lseek(fd, commblockonset, SEEK_SET); - if (seekout != commblockonset) goto badheader; - if (read(fd, buf, sizeof(t_comm)) < (int) sizeof(t_comm)) goto badheader; - q.nchannels = swap2(((t_comm *)buf)->nchannels, swap); - format = swap2(((t_comm *)buf)->bitspersamp, swap); - if (format == 16) q.bytespersample = 2; - else if (format == 24) q.bytespersample = 3; - else goto badheader; - } - seekout = lseek(fd, seekto, SEEK_SET); - if (seekout != seekto) goto badheader; - if (read(fd, buf, sizeof(t_datachunk)) < (int) sizeof(t_datachunk)) goto badheader; - headersize = seekto; - } - q.bytelimit = swap4(((t_datachunk *)buf)->size, swap); - headersize += 8; - } - } - /* seek past header and any sample frames to skip */ - sysrtn = lseek(fd, q.bytesperchannel() * skipframes + headersize, 0); - if (sysrtn != q.bytesperchannel() * skipframes + headersize) return -1; - q.bytelimit -= q.bytesperchannel() * skipframes; - if (q.bytelimit < 0) q.bytelimit = 0; - *p = q; - return fd; -badheader: - /* the header wasn't recognized. We're threadable here so let's not print out the error... */ - errno = EIO; - return -1; -} - -/* open a soundfile, using open_via_path(). This is used by readsf~ in - a not-perfectly-threadsafe way. LATER replace with a thread-hardened version of open_soundfile_via_canvas() */ -static int open_soundfile(const char *dirname, const char *filename, int headersize, t_param *p, long skipframes) { - char *buf, *bufptr; - int fd = open_via_path2(dirname, filename, "", &buf, &bufptr, 1); - if (fd < 0) return -1; - free(buf); - return open_soundfile_via_fd(fd, headersize, p, skipframes); -} - -/* open a soundfile, using open_via_canvas(). This is used by readsf~ in - a not-perfectly-threadsafe way. LATER replace with a thread-hardened version of open_soundfile_via_canvas() */ -static int open_soundfile_via_canvas(t_canvas *canvas, const char *filename, int headersize, t_param *p, long skipframes) { - char *buf, *bufptr; - int fd = canvas_open2(canvas, filename, "", &buf, &bufptr, 1); - if (fd < 0) return -1; - free(buf); - return open_soundfile_via_fd(fd, headersize, p, skipframes); -} - -static void soundfile_xferin(int sfchannels, int nvecs, float **vecs, - long itemsread, unsigned char *buf, int nitems, int bytespersample, int bigendian) { - unsigned char *sp, *sp2; - int nchannels = (sfchannels < nvecs ? sfchannels : nvecs); - int bytesperframe = bytespersample * sfchannels; - sp = buf; - for (int i=0; i < nchannels; i++, sp += bytespersample) { - int j; - sp2=sp; - float *fp=vecs[i] + itemsread; - #define LOOP for (j=0; j<nitems; j++, sp2 += bytesperframe, fp++) - if (bytespersample == 2) { - if (bigendian) LOOP {*fp = SCALE * ((sp2[0]<<24) | (sp2[1]<<16));} - else LOOP {*fp = SCALE * ((sp2[1]<<24) | (sp2[0]<<16));} - } else if (bytespersample == 3) { - if (bigendian) LOOP {*fp = SCALE * ((sp2[0]<<24) | (sp2[1]<<16) | (sp2[2]<<8));} - else LOOP {*fp = SCALE * ((sp2[2]<<24) | (sp2[1]<<16) | (sp2[0]<<8));} - } else if (bytespersample == 4) { - if (bigendian) LOOP {*(long *)fp = (sp2[0]<<24) | (sp2[1]<<16) | (sp2[2]<<8) | sp2[3];} - else LOOP {*(long *)fp = (sp2[3]<<24) | (sp2[2]<<16) | (sp2[1]<<8) | sp2[0];} - } - #undef LOOP - } - /* zero out other outputs */ - for (int i=sfchannels; i < nvecs; i++) { - float *fp=vecs[i]; - for (int j=nitems; j--; ) *fp++ = 0; - } -} - -/* soundfiler_write ... - usage: write [flags] filename table ... - flags: -nframes <frames> -skip <frames> -bytes <bytes per sample> -normalize -nextstep -wave -big -little - the routine which actually does the work should LATER also be called from garray_write16. - Parse arguments for writing. The "obj" argument is only for flagging - errors. For streaming to a file the "normalize", "onset" and "nframes" - arguments shouldn't be set but the calling routine flags this. */ -static int soundfiler_writeargparse(void *obj, int *p_argc, t_atom **p_argv, t_symbol **p_filesym, -int *p_filetype, int *p_bytespersamp, int *p_swap, int *p_bigendian, -int *p_normalize, long *p_onset, long *p_nframes, float *p_rate) { - int argc = *p_argc; - t_atom *argv = *p_argv; - int bytespersample = 2, bigendian = 0, endianness = -1, swap, filetype = -1, normalize = 0; - long onset = 0, nframes = 0x7fffffff; - t_symbol *filesym; - float rate = -1; - while (argc > 0 && argv->a_type == A_SYMBOL && *argv->a_symbol->name == '-') { - char *flag = argv->a_symbol->name + 1; - argc--; argv++; - if (!strcmp(flag, "skip")) { - EAT_ARG(A_FLOAT,onset); if (onset<0) goto usage; - } else if (!strcmp(flag, "nframes")) { - EAT_ARG(A_FLOAT,nframes); if (nframes<0) goto usage; - } else if (!strcmp(flag, "bytes")) { - EAT_ARG(A_FLOAT,bytespersample); if (bytespersample<2 || bytespersample>4) goto usage; - } else if (!strcmp(flag, "normalize")) {normalize = 1; - } else if (!strcmp(flag, "wave")) {filetype = FORMAT_WAVE; - } else if (!strcmp(flag, "nextstep")) {filetype = FORMAT_NEXT; - } else if (!strcmp(flag, "aiff")) {filetype = FORMAT_AIFF; - } else if (!strcmp(flag, "big")) {endianness = 1; - } else if (!strcmp(flag, "little")) {endianness = 0; - } else if (!strcmp(flag, "r") || !strcmp(flag, "rate")) { - EAT_ARG(A_FLOAT,rate); if (rate<0) goto usage; - } else goto usage; - } - if (!argc || argv->a_type != A_SYMBOL) goto usage; - filesym = argv->a_symbol; - /* check if format not specified and fill in */ - if (filetype < 0) { - const char *s = filesym->name + strlen(filesym->name); - if (strlen(filesym->name) >= 5 && !strcasecmp(s-4, ".aif" )) filetype = FORMAT_AIFF; - if (strlen(filesym->name) >= 6 && !strcasecmp(s-5, ".aiff")) filetype = FORMAT_AIFF; - if (strlen(filesym->name) >= 5 && !strcasecmp(s-4, ".snd" )) filetype = FORMAT_NEXT; - if (strlen(filesym->name) >= 4 && !strcasecmp(s-3, ".au" )) filetype = FORMAT_NEXT; - if (filetype < 0) filetype = FORMAT_WAVE; - } - /* don't handle AIFF floating point samples */ - if (bytespersample == 4) { - if (filetype == FORMAT_AIFF) { - error("AIFF floating-point file format unavailable"); - goto usage; - } - } - /* for WAVE force little endian; for nextstep use machine native */ - if (filetype == FORMAT_WAVE) { - bigendian = 0; - if (endianness == 1) error("WAVE file forced to little endian"); - } else if (filetype == FORMAT_AIFF) { - bigendian = 1; - if (endianness == 0) error("AIFF file forced to big endian"); - } else if (endianness == -1) { - bigendian = garray_ambigendian(); - } else bigendian = endianness; - swap = (bigendian != garray_ambigendian()); - argc--; argv++; - *p_argc = argc; - *p_argv = argv; - *p_filesym = filesym; - *p_filetype = filetype; - *p_bytespersamp = bytespersample; - *p_swap = swap; - *p_normalize = normalize; - *p_onset = onset; - *p_nframes = nframes; - *p_bigendian = bigendian; - *p_rate = rate; - return 0; -usage: - return -1; -} - -static bool strcaseends(const char *a, const char *b) {return strcasecmp(a+strlen(a)-strlen(b),b)==0;} - -static int create_soundfile(t_canvas *canvas, const char *filename, int filetype, int nframes, int bytespersample, -int bigendian, int nchannels, int swap, float samplerate) { - char filenamebuf[strlen(filename)+10]; - char headerbuf[WRITEHDRSIZE]; - int fd, headersize = 0; - strcpy(filenamebuf, filename); - if (filetype == FORMAT_NEXT) { - t_nextstep *nexthdr = (t_nextstep *)headerbuf; - if (!strcaseends(filenamebuf,".snd")) strcat(filenamebuf, ".snd"); - if (bigendian) strncpy(nexthdr->fileid, bigendian?".snd":"dns.", 4); - nexthdr->onset = swap4(sizeof(*nexthdr), swap); - nexthdr->length = 0; - nexthdr->format = swap4(bytespersample == 3 ? NS_FORMAT_LINEAR_24 : bytespersample == 4 ? NS_FORMAT_FLOAT : NS_FORMAT_LINEAR_16, swap); - nexthdr->sr = swap4((size_t)samplerate, swap); - nexthdr->nchans = swap4((size_t)nchannels, swap); - strcpy(nexthdr->info, "Pd "); - swapstring(nexthdr->info, swap); - headersize = sizeof(t_nextstep); - } else if (filetype == FORMAT_AIFF) { - long datasize = nframes * nchannels * bytespersample; - long longtmp; - static unsigned char dogdoo[] = {0x40, 0x0e, 0xac, 0x44, 0, 0, 0, 0, 0, 0, 'S', 'S', 'N', 'D'}; - t_aiff *aiffhdr = (t_aiff *)headerbuf; - if (!strcaseends(filenamebuf,".aif") && !strcaseends(filenamebuf,".aiff")) strcat(filenamebuf, ".aif"); - strncpy(aiffhdr->fileid, "FORM", 4); - aiffhdr->chunksize = swap4(datasize + sizeof(*aiffhdr) + 4, swap); - strncpy(aiffhdr->aiffid, "AIFF", 4); - strncpy(aiffhdr->fmtid, "COMM", 4); - aiffhdr->fmtchunksize = swap4(18, swap); - aiffhdr->nchannels = swap2(nchannels, swap); - longtmp = swap4(nframes, swap); - memcpy(&aiffhdr->nframeshi, &longtmp, 4); - aiffhdr->bitspersamp = swap2(8 * bytespersample, swap); - memcpy(aiffhdr->samprate, dogdoo, sizeof(dogdoo)); - longtmp = swap4(datasize, swap); - memcpy(aiffhdr->samprate + sizeof(dogdoo), &longtmp, 4); - memset(aiffhdr->samprate + sizeof(dogdoo) + 4, 0, 8); - headersize = AIFFPLUS; - /* fix by matju for hfeli, 2007.07.04, but really, dogdoo should be removed */ - while (samplerate >= 0x10000) {aiffhdr->samprate[1]++; samplerate/=2;} - aiffhdr->samprate[2] = (long)samplerate>>8; - aiffhdr->samprate[3] = (long)samplerate; - } else { /* WAVE format */ - long datasize = nframes * nchannels * bytespersample; - if (!strcaseends(filenamebuf,".wav")) strcat(filenamebuf, ".wav"); - t_wave *wavehdr = (t_wave *)headerbuf; - strncpy(wavehdr->fileid, "RIFF", 4); - wavehdr->chunksize = swap4(datasize + sizeof(*wavehdr) - 8, swap); - strncpy(wavehdr->waveid, "WAVE", 4); - strncpy(wavehdr->fmtid, "fmt ", 4); - wavehdr->fmtchunksize = swap4(16, swap); - wavehdr->fmttag = swap2((bytespersample == 4 ? WAV_FLOAT : WAV_INT), swap); - wavehdr->nchannels = swap2(nchannels, swap); - wavehdr->samplespersec = swap4(size_t(samplerate), swap); - wavehdr->navgbytespersec = swap4((int)(samplerate * nchannels * bytespersample), swap); - wavehdr->nblockalign = swap2(nchannels * bytespersample, swap); - wavehdr->nbitspersample = swap2(8 * bytespersample, swap); - strncpy(wavehdr->datachunkid, "data", 4); - wavehdr->datachunksize = swap4(datasize, swap); - headersize = sizeof(t_wave); - } - char *buf2 = canvas_makefilename(canvas, filenamebuf,0,0); - sys_bashfilename(buf2,buf2); - if ((fd = open(buf2, BINCREATE, 0666)) < 0) {free(buf2); return -1;} - if (write(fd, headerbuf, headersize) < headersize) { - close (fd); - return -1; - } - return fd; -} - -static void soundfile_finishwrite(void *obj, char *filename, int fd, -int filetype, long nframes, long itemswritten, int bytesperframe, int swap) { - if (itemswritten < nframes) { - if (nframes < 0x7fffffff) - error("soundfiler_write: %ld out of %ld bytes written", itemswritten, nframes); - /* try to fix size fields in header */ - if (filetype == FORMAT_WAVE) { - long datasize = itemswritten * bytesperframe, v; - if (lseek(fd, ((char *)(&((t_wave *)0)->chunksize)) - (char *)0, SEEK_SET) == 0) goto baddonewrite; - v = swap4(datasize + sizeof(t_wave) - 8, swap); - if (write(fd, (char *)&v, 4) < 4) goto baddonewrite; - if (lseek(fd, ((char *)(&((t_wave *)0)->datachunksize)) - (char *)0, SEEK_SET) == 0) goto baddonewrite; - v = swap4(datasize, swap); - if (write(fd, (char *)&v, 4) < 4) goto baddonewrite; - } - if (filetype == FORMAT_AIFF) { - long v; - if (lseek(fd, ((char *)(&((t_aiff *)0)->nframeshi)) - (char *)0, SEEK_SET) == 0) goto baddonewrite; - v = swap4(itemswritten, swap); - if (write(fd, (char *)&v,4) < 4) goto baddonewrite; - if (lseek(fd, ((char *)(&((t_aiff *)0)->chunksize)) - (char *)0, SEEK_SET) == 0) goto baddonewrite; - v = swap4(itemswritten*bytesperframe+AIFFHDRSIZE, swap); - if (write(fd, (char *)&v,4) < 4) goto baddonewrite; - if (lseek(fd, (AIFFHDRSIZE+4), SEEK_SET) == 0) goto baddonewrite; - v = swap4(itemswritten*bytesperframe, swap); - if (write(fd, (char *)&v,4) < 4) goto baddonewrite; - } - if (filetype == FORMAT_NEXT) { - /* do it the lazy way: just set the size field to 'unknown size'*/ - uint32 nextsize = 0xffffffff; - if (lseek(fd, 8, SEEK_SET) == 0) goto baddonewrite; - if (write(fd, &nextsize, 4) < 4) goto baddonewrite; - } - } - return; -baddonewrite: - error("%s: %s", filename, strerror(errno)); -} - -static void soundfile_xferout(int nchannels, float **vecs, unsigned char *buf, int nitems, long onset, int bytespersample, -int bigendian, float normalfactor) { - unsigned char *sp=buf, *sp2; - float *fp; - int bytesperframe = bytespersample * nchannels; - #define LOOP for (int j=0; j<nitems; j++, sp2 += bytesperframe, fp++) - for (int i = 0; i < nchannels; i++, sp += bytespersample) { - sp2 = sp; fp = vecs[i] + onset; - if (bytespersample == 2) { - float ff = normalfactor * 32768.; - if (bigendian) LOOP { - int xx = clip(int(32768. + *fp * ff) - 0x8000,-0x7fff,+0x7fff); - sp2[0] = xx>>8; sp2[1] = xx; - } else LOOP { - int xx = clip(int(32768. + *fp * ff) - 0x8000,-0x7fff,+0x7fff); - sp2[1] = xx>>8; sp2[0] = xx; - } - } else if (bytespersample == 3) { - float ff = normalfactor * 8388608.; - if (bigendian) LOOP { - int xx = clip(int(8388608. + *fp * ff) - 0x800000,-0x7fffff,+0x7fffff); - sp2[0] = xx>>16; sp2[1] = xx>>8; sp2[2] = xx; - } else LOOP { - int xx = clip(int(8388608. + *fp * ff) - 0x800000,-0x7fffff,+0x7fffff); - sp2[2] = xx>>16; sp2[1] = xx>>8; sp2[0] = xx; - } - } else if (bytespersample == 4) { - if (bigendian) LOOP { - float f2 = *fp * normalfactor; long xx = *(long *)&f2; - sp2[0] = xx >> 24; sp2[1] = xx >> 16; sp2[2] = xx >> 8; sp2[3] = xx; - } else LOOP { - float f2 = *fp * normalfactor; long xx = *(long *)&f2; - sp2[3] = xx >> 24; sp2[2] = xx >> 16; sp2[1] = xx >> 8; sp2[0] = xx; - } - } - } - #undef LOOP -} - -/* ------- soundfiler - reads and writes soundfiles to/from "garrays" ---- */ - -#define DEFMAXSIZE (16*1024*1024*4) /* default maximum 16 million floats per channel */ -#define SAMPBUFSIZE 1024 - -static t_class *soundfiler_class; - -struct t_soundfiler : t_object {t_canvas *canvas;}; - -#ifdef THREADED_SF -#include <sched.h> -#if (_POSIX_MEMLOCK - 0) >= 200112L -#include <sys/mman.h> -#else -#define munlockall() /* ignore */ -#define mlockall() /* ignore */ -#endif /* _POSIX_MEMLOCK */ - -static pthread_t sf_thread_id; /* id of soundfiler thread */ - -struct t_sfprocess { - void (*process)(t_soundfiler *,t_symbol *, int, t_atom *); /* function to call */ - t_soundfiler *x; - int argc; - t_atom *argv; - struct t_sfprocess *next; /* next object in queue */ - pthread_mutex_t mutex; -}; - -/* this is the queue for all soundfiler objects */ -struct t_sfqueue { - t_sfprocess *begin; - t_sfprocess *end; - pthread_mutex_t mutex; - pthread_cond_t cond; -}; - -static t_sfqueue *soundfiler_queue; - -/* we fill the queue */ -void soundfiler_queue_add(void (* process) (t_soundfiler *,t_symbol *,int,t_atom *), void * x, int argc, t_atom * argv) { - /* preparing entry */ - t_sfprocess * last_entry = (t_sfprocess*)getbytes(sizeof(t_sfprocess)); - if (debug) post("adding process to queue"); - pthread_mutex_init(&(last_entry->mutex), NULL); - pthread_mutex_lock(&(last_entry->mutex)); - last_entry->process = process; - last_entry->x = (t_soundfiler *)x; - last_entry->argc = argc; - last_entry->argv = (t_atom *)copybytes(argv, argc * sizeof(t_atom)); - last_entry->next = NULL; - pthread_mutex_unlock(&(last_entry->mutex)); - /* add new entry to queue */ - pthread_mutex_lock(&(soundfiler_queue->mutex)); - if (soundfiler_queue->begin==NULL) { - soundfiler_queue->begin=last_entry; - soundfiler_queue->end=last_entry; - } else { - pthread_mutex_lock(&(soundfiler_queue->end->mutex)); - soundfiler_queue->end->next=last_entry; - pthread_mutex_unlock(&(soundfiler_queue->end->mutex)); - soundfiler_queue->end=last_entry; - } - if ( soundfiler_queue->begin == soundfiler_queue->end ) { - if (debug) post("signaling"); - pthread_mutex_unlock(&(soundfiler_queue->mutex)); - /* and signal the helper thread */ - pthread_cond_signal(&(soundfiler_queue->cond)); - } else { - if (debug) post("not signaling"); - pthread_mutex_unlock(&(soundfiler_queue->mutex)); - } - return; -} - -/* global soundfiler thread ... sleeping until signaled */ -void soundfiler_thread() { - t_sfprocess *me; - t_sfprocess *next; - if (debug) post("soundfiler_thread ID: %d", pthread_self()); - while (1) { - if (debug) post("Soundfiler sleeping"); - pthread_cond_wait(&soundfiler_queue->cond, &soundfiler_queue->mutex); - if (debug) post("Soundfiler awake"); - /* work on the queue */ - while (soundfiler_queue->begin!=NULL) { - post("soundfiler: locked queue"); - /* locking process */ - pthread_mutex_lock(&(soundfiler_queue->begin->mutex)); - me = soundfiler_queue->begin; - pthread_mutex_unlock(&(me->mutex)); - pthread_mutex_unlock(&(soundfiler_queue->mutex)); - if (debug) post("soundfiler: mutex unlocked, running process"); - /* running the specific function */ - me->process(me->x, NULL, me->argc, me->argv); - if (debug) post("soundfiler: process done, locking mutex"); - pthread_mutex_lock(&(soundfiler_queue->mutex)); - pthread_mutex_lock(&(me->mutex)); - free(me->argv); - /* the process struct */ - next=me->next; - soundfiler_queue->begin=next; - free(me); - } - soundfiler_queue->end=NULL; - } -} - -extern int sys_hipriority; /* real-time flag, true if priority boosted */ - -/* create soundfiler thread */ -void sys_start_sfthread() { - pthread_attr_t sf_attr; - struct sched_param sf_param; - int status; - // initialize queue - soundfiler_queue = (t_sfqueue *)getbytes(sizeof(t_sfqueue)); - pthread_mutex_init(&soundfiler_queue->mutex,NULL); - pthread_cond_init(&soundfiler_queue->cond,NULL); - soundfiler_queue->begin=soundfiler_queue->end=NULL; -/* pthread_mutex_unlock(&(soundfiler_queue->mutex)); */ - // initialize thread - pthread_attr_init(&sf_attr); - sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); - pthread_attr_setschedparam(&sf_attr,&sf_param); -/* pthread_attr_setinheritsched(&sf_attr,PTHREAD_EXPLICIT_SCHED); */ -#ifdef UNIX - if (sys_hipriority == 1 && getuid() == 0) { - sf_param.sched_priority=sched_get_priority_min(SCHED_RR); - pthread_attr_setschedpolicy(&sf_attr,SCHED_RR); - } else { -/* pthread_attr_setschedpolicy(&sf_attr,SCHED_OTHER); */ -/* sf_param.sched_priority=sched_get_priority_min(SCHED_OTHER); */ - } -#endif /* UNIX */ - //start thread - status = pthread_create(&sf_thread_id, &sf_attr, (void *(*)(void *)) soundfiler_thread,NULL); - if (status != 0) error("Couldn't create soundfiler thread: %d",status); - else post("global soundfiler thread launched, priority: %d", sf_param.sched_priority); -} - -static void soundfiler_t_write( t_soundfiler *x, t_symbol *s, int argc, t_atom *argv); -static void soundfiler_t_write_addq(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - soundfiler_queue_add(soundfiler_t_write,(void *)x,argc, argv); -} -static void soundfiler_t_read( t_soundfiler *x, t_symbol *s, int argc, t_atom *argv); -static void soundfiler_t_read_addq(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - soundfiler_queue_add(soundfiler_t_read,(void *)x,argc, argv); -} - -/* soundfiler_read - usage: read [flags] filename table ... - flags: -skip <frames> ... frames to skip in file - -nframes <frames> -onset <frames> ... onset in table to read into (NOT DONE YET) - -raw <headersize channels bytes endian> -resize -maxsize <max-size> - TB: adapted for threaded use */ -static t_int soundfiler_read_update_garray(t_int *w); -static t_int soundfiler_read_update_graphics(t_int *w); -static t_int soundfiler_read_output(t_int *w); -static void soundfiler_t_read(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - t_param p; - int headersize = -1; - p.nchannels = 0; p.bytespersample = 0; p.bigendian = 0; - int resize = 0, i, j; - long skipframes = 0, nframes = 0, finalsize = 0, maxsize = DEFMAXSIZE, itemsread = 0; - p.bytelimit = 0x7fffffff; - int fd = -1; - char endianness, *filename; - t_garray *garrays[MAXSFCHANS]; - t_float *vecs[MAXSFCHANS]; /* the old array */ - t_float *nvecs[MAXSFCHANS]; /* the new array */ - int vecsize[MAXSFCHANS]; /* the old array size */ - char sampbuf[SAMPBUFSIZE]; - int bufframes, nitems; - FILE *fp; - pthread_cond_t resume_after_callback = PTHREAD_COND_INITIALIZER; - pthread_mutex_t resume_after_callback_mutex = PTHREAD_MUTEX_INITIALIZER; /* dummy */ - t_int* outargs; - while (argc > 0 && argv->a_type == A_SYMBOL && *argv->a_symbol->name == '-') { - char *flag = argv->a_symbol->name + 1; - argc--; argv++; - if (!strcmp(flag, "skip")) { - EAT_ARG(A_FLOAT,skipframes); if (skipframes<0) goto usage; - } else if (!strcmp(flag, "nframes")) { - EAT_ARG(A_FLOAT,nframes); if (nframes<0) goto usage; - } else if (!strcmp(flag, "raw")) { - EAT_ARG(A_FLOAT,headersize); if (headersize<0) goto usage; - EAT_ARG(A_FLOAT,p.nchannels); if (p.nchannels<1) goto usage; - EAT_ARG(A_FLOAT,p.bytespersample); if (p.bytespersample<2 || p.bytespersample>4) goto usage; - EAT_ARG(A_SYMBOL,endianness); if (endianness!='b' && endianness!='l' && endianness!='n') goto usage; - if (endianness == 'b') p.bigendian = 1; - else if (endianness == 'l') p.bigendian = 0; - else p.bigendian = garray_ambigendian(); - } else if (!strcmp(flag, "resize")) { - resize = 1; - } else if (!strcmp(flag, "maxsize")) { - EAT_ARG(A_FLOAT,maxsize); if (maxsize<0) goto usage; - resize = 1; /* maxsize implies resize. */ - } else goto usage; - } - if (argc < 2 || argc > MAXSFCHANS + 1 || argv[0].a_type != A_SYMBOL) goto usage; - filename = argv[0].a_symbol->name; - argc--; argv++; - for (int i=0; i<argc; i++) { - if (argv[i].a_type != A_SYMBOL) goto usage; - garrays[i] = (t_garray *)pd_findbyclass(argv[i].a_symbol, garray_class); - if (!garrays[i]) { - error("%s: no such table", argv[i].a_symbol->name); - goto done; - } else if (!garray_getfloatarray(garrays[i], &vecsize[i], &vecs[i])) - error("%s: bad template for tabwrite", argv[i].a_symbol->name); - if (finalsize && finalsize != vecsize[i] && !resize) { - post("soundfiler_read: arrays have different lengths; resizing..."); - resize = 1; - } - finalsize = vecsize[i]; - } - fd = open_soundfile(canvas_getdir(x->canvas)->name, filename, headersize, &p, skipframes); - if (fd < 0) { - error("soundfiler_read: %s: %s", filename, (errno == EIO ? "unknown or bad header format" : strerror(errno))); - goto done; - } - if (resize) { - /* figure out what to resize to */ - long poswas, eofis, framesinfile; - poswas = lseek(fd, 0, SEEK_CUR); - eofis = lseek(fd, 0, SEEK_END); - if (poswas < 0 || eofis < 0) {error("lseek failed"); goto done;} - lseek(fd, poswas, SEEK_SET); - framesinfile = (eofis - poswas) / p.bytesperchannel(); - if (framesinfile > maxsize) { - error("soundfiler_read: truncated to %d elements", maxsize); - framesinfile = maxsize; - } - framesinfile = min(framesinfile, p.bytelimit / p.bytesperchannel()); - finalsize = framesinfile; - } - if (!finalsize) finalsize = 0x7fffffff; - finalsize = min(finalsize, p.bytelimit / p.bytesperchannel()); - fp = fdopen(fd, "rb"); - bufframes = SAMPBUFSIZE / p.bytesperchannel(); - if (debug) { - post("buffers: %d", argc); - post("channels: %d", p.nchannels); - } - munlockall(); - /* allocate memory for new array */ - if (resize) - for (int i=0; i<argc; i++) { - nvecs[i] = (float *)getalignedbytes(finalsize * sizeof(t_float)); - /* if we are out of memory, free it again and quit */ - if (nvecs[i]==0) { - error("resize failed"); - /* if the resizing fails, we'll have to free all arrays again */ - for (j=0; j!=i;++j) freealignedbytes (nvecs[i],finalsize * sizeof(t_float)); - goto done; - } - } - else - for (int i=0; i<argc; i++) { - nvecs[i] = (float *)getalignedbytes(vecsize[i] * sizeof(t_float)); - /* if we are out of memory, free it again and quit */ - if (nvecs[i]==0) { - error("resize failed"); - /* if the resizing fails, we'll have to free all arrays again */ - for (j=0; j!=i;++j) freealignedbytes (nvecs[i],vecsize[i] * sizeof(t_float)); - goto done; - } - } - if(i > p.nchannels) memset(nvecs[i],0,vecsize[i] * sizeof(t_float)); - if (debug) post("transfer soundfile"); - for (itemsread = 0; itemsread < finalsize; ) { - int thisread = finalsize - itemsread; - thisread = (thisread > bufframes ? bufframes : thisread); - nitems = fread(sampbuf, p.bytesperchannel(), thisread, fp); - if (nitems <= 0) break; - soundfile_xferin(p.nchannels, argc, nvecs, itemsread, (unsigned char *)sampbuf, nitems, p.bytespersample, p.bigendian); - itemsread += nitems; - } - if (debug) post("zeroing remaining elements"); - /* zero out remaining elements of vectors */ - for (int i=0; i<argc; i++) for (int j=itemsread; j<finalsize; j++) nvecs[i][j] = 0; - /* set idle callback to switch pointers */ - if (debug) post("locked"); - for (int i=0; i<argc; i++) { - t_int *w = (t_int*)getbytes(4*sizeof(t_int)); - w[0] = (t_int)(garrays[i]); - w[1] = (t_int)nvecs[i]; - w[2] = (t_int)finalsize; - w[3] = (t_int)(&resume_after_callback); - sys_callback(&soundfiler_read_update_garray, w, 4); - pthread_cond_wait(&resume_after_callback, &resume_after_callback_mutex); - } - if (debug) post("unlocked, doing graphics updates"); - /* do all graphics updates. run this in the main thread via callback */ - for (int i=0; i<argc; i++) { - t_int *w = (t_int*)getbytes(2*sizeof(t_int)); - w[0] = (t_int)(garrays[i]); - w[1] = (t_int)finalsize; - sys_callback(&soundfiler_read_update_graphics, w, 2); - } - /* free the old arrays */ - for (int i=0; i<argc; i++) freealignedbytes(vecs[i], vecsize[i] * sizeof(t_float)); - fclose(fp); - fd = -1; - goto done; -usage: - error("usage: read [flags] filename tablename..."); - post("flags: -skip <n> -nframes <n> -resize -maxsize <n> ..."); - post("-raw <headerbytes> <channels> <bytespersample> <endian (b, l, or n)>."); -done: - if (fd>=0) close(fd); - mlockall(MCL_FUTURE); - outargs = (t_int*)getbytes(2*sizeof(t_int)); - outargs[0] = (t_int)x->outlet; - outargs[1] = (t_int)itemsread; - sys_callback(&soundfiler_read_output, outargs, 2); -} - -/* idle callback for threadsafe synchronisation */ -static t_int soundfiler_read_update_garray(t_int *w) { - t_garray *garray = (t_garray*)w[0]; - t_int nvec = w[1]; - t_int finalsize = w[2]; - pthread_cond_t *conditional = (pthread_cond_t*) w[3]; - t_array *a = garray_getarray(garray); - a->vec = (char *) nvec; - a->n = finalsize; - if (garray->usedindsp) canvas_update_dsp(); - /* signal helper thread */ - pthread_cond_broadcast(conditional); - return 0; -} - -static t_int soundfiler_read_update_graphics(t_int *w) { - t_garray *garray = (t_garray*) w[0]; - t_canvas *gl; - int n = w[1]; - /* if this is the only array in the graph, reset the graph's coordinates */ - if (debug) post("redraw array %p", garray); - gl = garray->canvas; - if (gl->list == garray && !garray->next) { - vmess(gl, gensym("bounds"), "ffff", 0., gl->y1, double(n > 1 ? n-1 : 1), gl->y2); - /* close any dialogs that might have the wrong info now... */ - } else garray_redraw(garray); - return 0; -} - -static t_int soundfiler_read_output(t_int * w) { - t_outlet* outlet = (t_outlet*) w[0]; - float itemsread = (float) w[1]; - if (debug) post("bang %p", outlet); - outlet->send(itemsread); - return 0; -} - -/* this is broken out from soundfiler_write below so garray_write can call it too... not done yet though. */ -long soundfiler_t_dowrite(void *obj, t_canvas *canvas, int argc, t_atom *argv) { - int bytespersample, bigendian, swap, filetype, normalize, nchannels; - long onset, nframes, itemswritten = 0; - t_garray *garrays[MAXSFCHANS]; - t_float *vecs[MAXSFCHANS]; - char sampbuf[SAMPBUFSIZE]; - int bufframes; - int fd = -1; - float normfactor, biggest = 0, samplerate; - t_symbol *filesym; - if (soundfiler_writeargparse(obj, &argc, &argv, &filesym, &filetype, - &bytespersample, &swap, &bigendian, &normalize, &onset, &nframes, &samplerate)) - goto usage; - nchannels = argc; - if (nchannels < 1 || nchannels > MAXSFCHANS) goto usage; - if (samplerate < 0) samplerate = sys_getsr(); - for (int i=0; i<nchannels; i++) { - int vecsize; - if (argv[i].a_type != A_SYMBOL) goto usage; - if (!(garrays[i] = (t_garray *)pd_findbyclass(argv[i].a_symbol, garray_class))) { - error("%s: no such table", argv[i].a_symbol->name); - goto fail; - } - else if (!garray_getfloatarray(garrays[i], &vecsize, &vecs[i])) - error("%s: bad template for tabwrite", argv[i].a_symbol->name); - if (nframes > vecsize - onset) - nframes = vecsize - onset; - for (int j=0; j<vecsize; j++) { - if (+vecs[i][j] > biggest) biggest = +vecs[i][j]; - else if (-vecs[i][j] > biggest) biggest = -vecs[i][j]; - } - } - if (nframes <= 0) { - error("soundfiler_write: no samples at onset %ld", onset); - goto fail; - } - if ((fd = create_soundfile(canvas, filesym->name, filetype, nframes, bytespersample, bigendian, nchannels, swap, samplerate)) < 0) { - post("%s: %s", filesym->name, strerror(errno)); - goto fail; - } - if (!normalize) { - if ((bytespersample != 4) && (biggest > 1)) { - post("%s: normalizing max amplitude %f to 1", filesym->name, biggest); - normalize = 1; - } else post("%s: biggest amplitude = %f", filesym->name, biggest); - } - if (normalize) normfactor = (biggest > 0 ? 32767./(32768. * biggest) : 1); - else normfactor = 1; - bufframes = SAMPBUFSIZE / (nchannels * bytespersample); - for (itemswritten = 0; itemswritten < nframes; ) { - int thiswrite = nframes - itemswritten, nbytes; - thiswrite = (thiswrite > bufframes ? bufframes : thiswrite); - soundfile_xferout(argc, vecs, (unsigned char *)sampbuf, thiswrite, onset, bytespersample, bigendian, normfactor); - nbytes = write(fd, sampbuf, nchannels * bytespersample * thiswrite); - if (nbytes < nchannels * bytespersample * thiswrite) { - post("%s: %s", filesym->name, strerror(errno)); - if (nbytes > 0) itemswritten += nbytes / (nchannels * bytespersample); - break; - } - itemswritten += thiswrite; - onset += thiswrite; - } - if (fd >= 0) { - soundfile_finishwrite(obj, filesym->name, fd, filetype, nframes, itemswritten, nchannels * bytespersample, swap); - close (fd); - } - return itemswritten; -usage: - error("usage: write [flags] filename tablename..."); - post("flags: -skip <n> -nframes <n> -bytes <n> -wave -aiff -nextstep ..."); - post("-big -little -normalize"); - post("(defaults to a 16-bit wave file)."); -fail: - if (fd >= 0) close(fd); - return 0; -} - -static void soundfiler_t_write(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - long bozo = soundfiler_t_dowrite(x, x->canvas, argc, argv); - sys_lock(); - x->outlet->send(float(bozo)); - sys_lock(); -} - -static void soundfiler_t_resize(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv); -static void soundfiler_t_resize_addq(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - soundfiler_queue_add(soundfiler_t_resize,(void *)x,argc, argv); -} - -/* TB: soundfiler_t_resize ... usage: resize table size; adapted from garray_resize */ -static void soundfiler_t_resize(t_soundfiler *y, t_symbol *s, int argc, t_atom *argv) { - int was, elemsize; /* array contains was elements of size elemsize */ - t_float *vec; /* old array */ - t_canvas *gl; - int n; /* resize of n elements */ - char *nvec; /* new array */ - t_garray *x = (t_garray *)pd_findbyclass(argv[0].a_symbol, garray_class); - t_array *a = garray_getarray(x); - if (!x) {error("%s: no such table", argv[0].a_symbol->name); goto usage;} - vec = (t_float*) a->vec; - was = a->n; - if ((argv+1)->a_type == A_FLOAT) { - n = (int) (argv+1)->a_float; - } else goto usage; - if (n == was) return; - if (n < 1) n = 1; - elemsize = template_findbyname(a->templatesym)->t_n * sizeof(t_word); - munlockall(); - if (was > n) { - nvec = (char *)copyalignedbytes(a->vec, was * elemsize); - } else { - nvec = (char *)getalignedbytes(n * elemsize); - memcpy (nvec, a->vec, was * elemsize); - memset(nvec + was*elemsize, 0, (n - was) * elemsize); - } - if (!nvec) {error("array resize failed: out of memory"); mlockall(MCL_FUTURE); return;} - /* TB: we'll have to be sure that no one is accessing the array */ - sys_lock(); - a->vec = nvec; - a->n = n; - if (x->usedindsp) canvas_update_dsp(); - sys_unlock(); - /* if this is the only array in the graph, reset the graph's coordinates */ - gl = x->canvas; - if (gl->list == x && !x->next) { - vmess(gl, gensym("bounds"), "ffff", 0., gl->y1, (double)(n > 1 ? n-1 : 1), gl->y2); - /* close any dialogs that might have the wrong info now... */ - } else garray_redraw(x); - freealignedbytes (vec, was * elemsize); - mlockall(MCL_FUTURE); - sys_lock(); - y->outlet->send((float)atom_getintarg(1,argc,argv)); - sys_unlock(); - return; -usage: - error("usage: resize tablename size"); -} - -static void soundfiler_t_const(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv); -static void soundfiler_t_const_addq(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - soundfiler_queue_add(soundfiler_t_const,(void *)x,argc, argv); -} - -/* TB: soundfiler_t_const ... usage: const table value */ -static void soundfiler_t_const(t_soundfiler *y, t_symbol *s, int argc, t_atom *argv) { - int size, elemsize; /* array contains was elements of size elemsize */ - t_float *vec; /* old array */ - t_canvas *gl; - int val; /* value */ - char *nvec; /* new array */ - t_garray * x = (t_garray *)pd_findbyclass(argv[0].a_symbol, garray_class); - t_array *a = garray_getarray(x); - if (!x) {error("%s: no such table", argv[0].a_symbol->name); goto usage;} - vec = (t_float*) a->vec; - size = a->n; - if ((argv+1)->a_type == A_FLOAT) { - val = (int) (argv+1)->a_float; - } else goto usage; - elemsize = template_findbyname(a->templatesym)->t_n * sizeof(t_word); - /* allocating memory */ - munlockall(); - nvec = (char *)getalignedbytes(size * elemsize); - if (!nvec) { - error("array resize failed: out of memory"); - mlockall(MCL_FUTURE); - return; - } - /* setting array */ - for (int i=0; i!=size; ++i) nvec[i]=val; - /* TB: we'll have to be sure that no one is accessing the array */ - sys_lock(); - a->vec = nvec; - if (x->usedindsp) canvas_update_dsp(); - sys_unlock(); - /* if this is the only array in the graph, reset the graph's coordinates */ - gl = x->canvas; - if (gl->list == x && !x->next) { - vmess(gl, gensym("bounds"), "ffff", 0., gl->y1, (double)(size > 1 ? size-1 : 1), gl->y2); - /* close any dialogs that might have the wrong info now... */ - } else garray_redraw(x); - freealignedbytes (vec, size * elemsize); - mlockall(MCL_FUTURE); - sys_lock(); - y->outlet->send(size); - sys_unlock(); - return; - usage: - error("usage: const tablename value"); -} - -#endif /* THREADED_SF */ - -static t_soundfiler *soundfiler_new() { - t_soundfiler *x = (t_soundfiler *)pd_new(soundfiler_class); - x->canvas = canvas_getcurrent(); - outlet_new(x,&s_float); -#ifdef THREADED_SF - post("warning: threaded soundfiler is not synchronous"); -#endif /* THREADED_SF */ - return x; -} - -/* soundfiler_read ... - usage: read [flags] filename table ... - flags: -skip <frames> ... frames to skip in file - -nframes <frames> -onset <frames> ... onset in table to read into (NOT DONE YET) - -raw <headersize channels bytes endian> -resize -maxsize <max-size> */ -static void soundfiler_read(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - t_param p; - p.bytespersample = 0; - p.bigendian = 0; - p.nchannels = 0; - p.bytelimit = 0x7fffffff; - int headersize = -1, resize = 0; - long skipframes = 0, nframes = 0, finalsize = 0, maxsize = DEFMAXSIZE, itemsread = 0; - int fd = -1; - char endianness, *filename; - t_garray *garrays[MAXSFCHANS]; - t_float *vecs[MAXSFCHANS]; - char sampbuf[SAMPBUFSIZE]; - int bufframes, nitems; - FILE *fp; - while (argc > 0 && argv->a_type == A_SYMBOL && *argv->a_symbol->name == '-') { - char *flag = argv->a_symbol->name + 1; - argc--; argv++; - if (!strcmp(flag, "skip")) { - EAT_ARG(A_FLOAT,skipframes); if (skipframes<0) goto usage; - } else if (!strcmp(flag, "nframes")) { - EAT_ARG(A_FLOAT,nframes); if (nframes<0) goto usage; - } else if (!strcmp(flag, "raw")) { - EAT_ARG(A_FLOAT,headersize); if (headersize<0) goto usage; - EAT_ARG(A_FLOAT,p.nchannels); if (p.nchannels<1) goto usage; - EAT_ARG(A_FLOAT,p.bytespersample); if (p.bytespersample<2 || p.bytespersample>4) goto usage; - EAT_ARG(A_SYMBOL,endianness); if (endianness!='b' && endianness!='l' && endianness!='n') goto usage; - if (endianness == 'b') p.bigendian = 1; - else if (endianness == 'l') p.bigendian = 0; - else p.bigendian = garray_ambigendian(); - } else if (!strcmp(flag, "resize")) { - resize = 1; - } else if (!strcmp(flag, "maxsize")) { - EAT_ARG(A_FLOAT,maxsize); if (maxsize<0) goto usage; - resize = 1; /* maxsize implies resize. */ - } else goto usage; - } - if (argc < 2 || argc > MAXSFCHANS + 1 || argv[0].a_type != A_SYMBOL) goto usage; - filename = argv[0].a_symbol->name; - argc--; argv++; - for (int i=0; i<argc; i++) { - int vecsize; - if (argv[i].a_type != A_SYMBOL) goto usage; - garrays[i] = (t_garray *)pd_findbyclass(argv[i].a_symbol, garray_class); - if (!garrays[i]) { - error("%s: no such table", argv[i].a_symbol->name); - goto done; - } else if (!garray_getfloatarray(garrays[i], &vecsize, &vecs[i])) - error("%s: bad template for tabwrite", argv[i].a_symbol->name); - if (finalsize && finalsize != vecsize && !resize) { - post("soundfiler_read: arrays have different lengths; resizing..."); - resize = 1; - } - finalsize = vecsize; - } - fd = open_soundfile_via_canvas(x->canvas, filename, headersize, &p, skipframes); - if (fd < 0) { - error("soundfiler_read: %s: %s", filename, (errno == EIO ? "unknown or bad header format" : strerror(errno))); - goto done; - } - if (resize) { - /* figure out what to resize to */ - long poswas, eofis, framesinfile; - poswas = lseek(fd, 0, SEEK_CUR); - eofis = lseek(fd, 0, SEEK_END); - if (poswas < 0 || eofis < 0) {error("lseek failed"); goto done;} - lseek(fd, poswas, SEEK_SET); - framesinfile = (eofis - poswas) / (p.nchannels * p.bytespersample); - if (framesinfile > maxsize) {error("soundfiler_read: truncated to %ld elements", maxsize); framesinfile = maxsize;} - framesinfile = min(framesinfile, p.bytelimit / (p.nchannels * p.bytespersample)); - finalsize = framesinfile; - for (int i=0; i<argc; i++) { - int vecsize; - garray_resize(garrays[i], finalsize); - /* for sanity's sake let's clear the save-in-patch flag here */ - garray_setsaveit(garrays[i], 0); - garray_getfloatarray(garrays[i], &vecsize, &vecs[i]); - /* if the resize failed, garray_resize reported the error */ - if (vecsize != framesinfile) {error("resize failed"); goto done;} - } - } - if (!finalsize) finalsize = 0x7fffffff; - finalsize = min(finalsize, p.bytelimit / (p.nchannels * p.bytespersample)); - fp = fdopen(fd, "rb"); - bufframes = SAMPBUFSIZE / (p.nchannels * p.bytespersample); - for (itemsread = 0; itemsread < finalsize; ) { - int thisread = finalsize - itemsread; - thisread = min(thisread,bufframes); - nitems = fread(sampbuf, p.nchannels * p.bytespersample, thisread, fp); - if (nitems <= 0) break; - soundfile_xferin(p.nchannels, argc, vecs, itemsread, (unsigned char *)sampbuf, nitems, p.bytespersample, p.bigendian); - itemsread += nitems; - } - /* zero out remaining elements of vectors */ - for (int i=0; i<argc; i++) { - int vecsize; garray_getfloatarray(garrays[i], &vecsize, &vecs[i]); - for (int j=itemsread; j<vecsize; j++) vecs[i][j]=0; - } - /* zero out vectors in excess of number of channels */ - for (int i=p.nchannels; i<argc; i++) { - int vecsize; float *foo; garray_getfloatarray(garrays[i], &vecsize, &foo); - for (int j=0; j<vecsize; j++) foo[j]=0; - } - /* do all graphics updates */ - for (int i=0; i<argc; i++) garray_redraw(garrays[i]); - fclose(fp); - fd = -1; - goto done; -usage: - error("usage: read [flags] filename tablename..."); - post("flags: -skip <n> -nframes <n> -resize -maxsize <n> ..."); - post("-raw <headerbytes> <channels> <bytespersample> <endian (b, l, or n)>."); -done: - if (fd >= 0) close(fd); - x->outlet->send(float(itemsread)); -} - -/* this is broken out from soundfiler_write below so garray_write can - call it too... not done yet though. */ -long soundfiler_dowrite(void *obj, t_canvas *canvas, int argc, t_atom *argv) { - int bytespersample, bigendian, swap, filetype, normalize, nchannels; - long onset, nframes, itemswritten = 0; - t_garray *garrays[MAXSFCHANS]; - t_float *vecs[MAXSFCHANS]; - char sampbuf[SAMPBUFSIZE]; - int bufframes; - int fd = -1; - float normfactor, biggest = 0, samplerate; - t_symbol *filesym; - if (soundfiler_writeargparse(obj, &argc, &argv, &filesym, &filetype, - &bytespersample, &swap, &bigendian, &normalize, &onset, &nframes, - &samplerate)) - goto usage; - nchannels = argc; - if (nchannels < 1 || nchannels > MAXSFCHANS) goto usage; - if (samplerate < 0) samplerate = sys_getsr(); - for (int i=0; i<nchannels; i++) { - int vecsize; - if (argv[i].a_type != A_SYMBOL) goto usage; - if (!(garrays[i] = (t_garray *)pd_findbyclass(argv[i].a_symbol, garray_class))) { - error("%s: no such table", argv[i].a_symbol->name); - goto fail; - } - else if (!garray_getfloatarray(garrays[i], &vecsize, &vecs[i])) - error("%s: bad template for tabwrite", argv[i].a_symbol->name); - nframes = min(nframes, vecsize - onset); - for (int j=0; j<vecsize; j++) { - if (+vecs[i][j] > biggest) biggest = +vecs[i][j]; - else if (-vecs[i][j] > biggest) biggest = -vecs[i][j]; - } - } - if (nframes <= 0) { - error("soundfiler_write: no samples at onset %ld", onset); - goto fail; - } - if ((fd = create_soundfile(canvas, filesym->name, filetype, nframes, bytespersample, bigendian, nchannels, swap, samplerate)) < 0) { - post("%s: %s", filesym->name, strerror(errno)); - goto fail; - } - if (!normalize) { - if ((bytespersample != 4) && (biggest > 1)) { - post("%s: normalizing max amplitude %f to 1", filesym->name, biggest); - normalize = 1; - } else post("%s: biggest amplitude = %f", filesym->name, biggest); - } - if (normalize) normfactor = (biggest > 0 ? 32767./(32768. * biggest) : 1); else normfactor = 1; - bufframes = SAMPBUFSIZE / (nchannels * bytespersample); - for (itemswritten = 0; itemswritten < nframes; ) { - int thiswrite = nframes - itemswritten, nbytes; - thiswrite = (thiswrite > bufframes ? bufframes : thiswrite); - soundfile_xferout(argc, vecs, (unsigned char *)sampbuf, thiswrite, onset, bytespersample, bigendian, normfactor); - nbytes = write(fd, sampbuf, nchannels * bytespersample * thiswrite); - if (nbytes < nchannels * bytespersample * thiswrite) { - post("%s: %s", filesym->name, strerror(errno)); - if (nbytes > 0) itemswritten += nbytes / (nchannels * bytespersample); - break; - } - itemswritten += thiswrite; - onset += thiswrite; - } - if (fd >= 0) { - soundfile_finishwrite(obj, filesym->name, fd, filetype, nframes, itemswritten, nchannels * bytespersample, swap); - close (fd); - } - return itemswritten; -usage: - error("usage: write [flags] filename tablename..."); - post("flags: -skip <n> -nframes <n> -bytes <n> -wave -aiff -nextstep ..."); - post("-big -little -normalize"); - post("(defaults to a 16-bit wave file)."); -fail: - if (fd >= 0) close(fd); - return 0; -} - -static void soundfiler_write(t_soundfiler *x, t_symbol *s, int argc, t_atom *argv) { - long bozo = soundfiler_dowrite(x, x->canvas, argc, argv); - x->outlet->send(bozo); -} - -static void soundfiler_setup() { - t_class *c = soundfiler_class = class_new2("soundfiler", (t_newmethod)soundfiler_new, 0, sizeof(t_soundfiler), 0, ""); -#ifdef THREADED_SF - class_addmethod2(c, soundfiler_t_read_addq, "read", "*"); -/* class_addmethod2(c, soundfiler_t_write_addq, "write", "*"); */ - class_addmethod2(c, soundfiler_t_resize_addq, "resize", "*"); - class_addmethod2(c, soundfiler_t_const_addq, "const", "*"); -#else - class_addmethod2(c, soundfiler_read, "read", "*"); -#endif /* THREADED_SF */ - class_addmethod2(c, soundfiler_write, "write", "*"); -} - -/************************* readsf object ******************************/ - -/* READSF uses the Posix threads package; for the moment we're Linux -only although this should be portable to the other platforms. - -Each instance of readsf~ owns a "child" thread for doing the unix (MSW?) file -reading. The parent thread signals the child each time: - (1) a file wants opening or closing; - (2) we've eaten another 1/16 of the shared buffer (so that the - child thread should check if it's time to read some more.) -The child signals the parent whenever a read has completed. Signalling -is done by setting "conditions" and putting data in mutex-controlled common -areas. -*/ - -#define MAXBYTESPERSAMPLE 4 -#define MAXVECSIZE 128 - -#define READSIZE 65536 -#define WRITESIZE 65536 -#define DEFBUFPERCHAN 262144 -#define MINBUFSIZE (4 * READSIZE) -#define MAXBUFSIZE 16777216 /* arbitrary; just don't want to hang malloc */ - -#define REQUEST_NOTHING 0 -#define REQUEST_OPEN 1 -#define REQUEST_CLOSE 2 -#define REQUEST_QUIT 3 -#define REQUEST_BUSY 4 - -#define STATE_IDLE 0 -#define STATE_STARTUP 1 -#define STATE_STREAM 2 - -static t_class *readsf_class; - -struct t_readsf : t_object { - t_canvas *canvas; - t_clock *clock; - char *buf; /* soundfile buffer */ - int bufsize; /* buffer size in bytes */ - int noutlets; /* number of audio outlets */ - t_sample *(outvec[MAXSFCHANS]); /* audio vectors */ - int vecsize; /* vector size for transfers */ - t_outlet *bangout; /* bang-on-done outlet */ - int state; /* opened, running, or idle */ - float insamplerate; /* sample rate of input signal if known */ - /* parameters to communicate with subthread */ - int requestcode; /* pending request from parent to I/O thread */ - char *filename; /* file to open (string is permanently allocated) */ - int fileerror; /* slot for "errno" return */ - int skipheaderbytes; /* size of header we'll skip */ - t_param p; - float samplerate; /* sample rate of soundfile */ - long onsetframes; /* number of sample frames to skip */ - int fd; /* filedesc */ - int fifosize; /* buffer size appropriately rounded down */ - int fifohead; /* index of next byte to get from file */ - int fifotail; /* index of next byte the ugen will read */ - int eof; /* true if fifohead has stopped changing */ - int sigcountdown; /* counter for signalling child for more data */ - int sigperiod; /* number of ticks per signal */ - int filetype; /* writesf~ only; type of file to create */ - int itemswritten; /* writesf~ only; items writen */ - int swap; /* writesf~ only; true if byte swapping */ - float f; /* writesf~ only; scalar for signal inlet */ - pthread_mutex_t mutex; - pthread_cond_t requestcondition; - pthread_cond_t answercondition; - pthread_t childthread; -}; - - -/************** the child thread which performs file I/O ***********/ - -#if 1 -#define sfread_cond_wait pthread_cond_wait -#define sfread_cond_signal pthread_cond_signal -#else -#include <sys/time.h> /* debugging version... */ -#include <sys/types.h> -static void readsf_fakewait(pthread_mutex_t *b) { - struct timeval timout; - timout.tv_sec = 0; - timout.tv_usec = 1000000; - pthread_mutex_unlock(b); - select(0, 0, 0, 0, &timout); - pthread_mutex_lock(b); -} - -#define sfread_cond_wait(a,b) readsf_fakewait(b) -#define sfread_cond_signal(a) -#endif - -static void *readsf_child_main(void *zz) { - t_readsf *x = (t_readsf *)zz; - pthread_mutex_lock(&x->mutex); - while (1) { - int fd, fifohead; - char *buf; - if (x->requestcode == REQUEST_NOTHING) { - sfread_cond_signal(&x->answercondition); - sfread_cond_wait(&x->requestcondition, &x->mutex); - } else if (x->requestcode == REQUEST_OPEN) { - int sysrtn, wantbytes; - /* copy file stuff out of the data structure so we can - relinquish the mutex while we're in open_soundfile(). */ - long onsetframes = x->onsetframes; - t_param p; - p.bytelimit = 0x7fffffff; - int skipheaderbytes = x->skipheaderbytes; - p.bytespersample = x->p.bytespersample; - p.bigendian = x->p.bigendian; - /* alter the request code so that an ensuing "open" will get noticed. */ - x->requestcode = REQUEST_BUSY; - x->fileerror = 0; - /* if there's already a file open, close it */ - if (x->fd >= 0) { - fd = x->fd; - pthread_mutex_unlock(&x->mutex); - close (fd); - pthread_mutex_lock(&x->mutex); - x->fd = -1; - if (x->requestcode != REQUEST_BUSY) goto lost; - } - /* open the soundfile with the mutex unlocked */ - pthread_mutex_unlock(&x->mutex); - fd = open_soundfile(canvas_getdir(x->canvas)->name, x->filename, skipheaderbytes, &p, onsetframes); - pthread_mutex_lock(&x->mutex); - /* copy back into the instance structure. */ - x->p = p; - x->fd = fd; - if (fd < 0) { - x->fileerror = errno; - x->eof = 1; - goto lost; - } - /* check if another request has been made; if so, field it */ - if (x->requestcode != REQUEST_BUSY) goto lost; - x->fifohead = 0; - /* set fifosize from bufsize. fifosize must be a multiple of the number of bytes eaten for each DSP - tick. We pessimistically assume MAXVECSIZE samples per tick since that could change. There could be a - problem here if the vector size increases while a soundfile is being played... */ - x->fifosize = x->bufsize - (x->bufsize % (x->p.bytesperchannel() * MAXVECSIZE)); - /* arrange for the "request" condition to be signalled 16 times per buffer */ - x->sigcountdown = x->sigperiod = x->fifosize / (16 * x->p.bytesperchannel() * x->vecsize); - /* in a loop, wait for the fifo to get hungry and feed it */ - while (x->requestcode == REQUEST_BUSY) { - int fifosize = x->fifosize; - if (x->eof) break; - if (x->fifohead >= x->fifotail) { - /* if the head is >= the tail, we can immediately read to the end of the fifo. Unless, that is, we - would read all the way to the end of the buffer and the "tail" is zero; this would fill the buffer completely - which isn't allowed because you can't tell a completely full buffer from an empty one. */ - if (x->fifotail || (fifosize - x->fifohead > READSIZE)) { - wantbytes = min(min(fifosize - x->fifohead, READSIZE),(int)x->p.bytelimit); - } else { - sfread_cond_signal(&x->answercondition); - sfread_cond_wait(&x->requestcondition, &x->mutex); - continue; - } - } else { - /* otherwise check if there are at least READSIZE bytes to read. If not, wait and loop back. */ - wantbytes = x->fifotail - x->fifohead - 1; - if (wantbytes < READSIZE) { - sfread_cond_signal(&x->answercondition); - sfread_cond_wait(&x->requestcondition, &x->mutex); - continue; - } else wantbytes = READSIZE; - wantbytes = min(wantbytes,(int)x->p.bytelimit); - } - fd = x->fd; - buf = x->buf; - fifohead = x->fifohead; - pthread_mutex_unlock(&x->mutex); - sysrtn = read(fd, buf + fifohead, wantbytes); - pthread_mutex_lock(&x->mutex); - if (x->requestcode != REQUEST_BUSY) break; - if (sysrtn < 0) {x->fileerror = errno; break;} - else if (sysrtn == 0) {x->eof = 1; break;} - else { - x->fifohead += sysrtn; - x->p.bytelimit -= sysrtn; - if (x->p.bytelimit <= 0) {x->eof = 1; break;} - if (x->fifohead == fifosize) x->fifohead = 0; - } - /* signal parent in case it's waiting for data */ - sfread_cond_signal(&x->answercondition); - } - lost: - if (x->requestcode == REQUEST_BUSY) x->requestcode = REQUEST_NOTHING; - /* fell out of read loop: close file if necessary, set EOF and signal once more */ - if (x->fd >= 0) { - fd = x->fd; - pthread_mutex_unlock(&x->mutex); - close (fd); - pthread_mutex_lock(&x->mutex); - x->fd = -1; - } - sfread_cond_signal(&x->answercondition); - } else if (x->requestcode == REQUEST_CLOSE || x->requestcode == REQUEST_QUIT) { - if (x->fd >= 0) { - fd = x->fd; - pthread_mutex_unlock(&x->mutex); - close (fd); - pthread_mutex_lock(&x->mutex); - x->fd = -1; - } - x->requestcode = REQUEST_NOTHING; - sfread_cond_signal(&x->answercondition); - } - if (x->requestcode == REQUEST_QUIT) break; - } - pthread_mutex_unlock(&x->mutex); - return 0; -} - -/******** the object proper runs in the calling (parent) thread ****/ - -static void readsf_tick(t_readsf *x); - -static void *readsf_new(t_floatarg fnchannels, t_floatarg fbufsize) { - int nchannels = int(fnchannels), bufsize = int(fbufsize); - if (nchannels < 1) nchannels = 1; - else if (nchannels > MAXSFCHANS) nchannels = MAXSFCHANS; - if (bufsize <= 0) bufsize = DEFBUFPERCHAN * nchannels; - else if (bufsize < MINBUFSIZE) bufsize = MINBUFSIZE; - else if (bufsize > MAXBUFSIZE) bufsize = MAXBUFSIZE; - char *buf = (char *)getbytes(bufsize); - if (!buf) return 0; - t_readsf *x = (t_readsf *)pd_new(readsf_class); - for (int i=0; i<nchannels; i++) outlet_new(x,gensym("signal")); - x->noutlets = nchannels; - x->bangout = outlet_new(x,&s_bang); - pthread_mutex_init(&x->mutex, 0); - pthread_cond_init(&x->requestcondition, 0); - pthread_cond_init(&x->answercondition, 0); - x->vecsize = MAXVECSIZE; - x->state = STATE_IDLE; - x->clock = clock_new(x, (t_method)readsf_tick); - x->canvas = canvas_getcurrent(); - x->p.bytespersample = 2; - x->p.nchannels = 1; - x->fd = -1; - x->buf = buf; - x->bufsize = bufsize; - x->fifosize = x->fifohead = x->fifotail = x->requestcode = 0; - pthread_create(&x->childthread, 0, readsf_child_main, x); - return x; -} - -static void readsf_tick(t_readsf *x) {x->bangout->send();} - -static t_int *readsf_perform(t_int *w) { - t_readsf *x = (t_readsf *)(w[1]); - int vecsize = x->vecsize, noutlets = x->noutlets; - if (x->state == STATE_STREAM) { - int wantbytes; - pthread_mutex_lock(&x->mutex); - wantbytes = vecsize * x->p.bytesperchannel(); - while (!x->eof && x->fifohead >= x->fifotail && x->fifohead < x->fifotail + wantbytes-1) { - sfread_cond_signal(&x->requestcondition); - sfread_cond_wait(&x->answercondition, &x->mutex); - } - if (x->eof && x->fifohead >= x->fifotail && x->fifohead < x->fifotail + wantbytes-1) { - if (x->fileerror) { - error("dsp: %s: %s", x->filename, x->fileerror == EIO ? "unknown or bad header format" : strerror(x->fileerror)); - } - clock_delay(x->clock, 0); - x->state = STATE_IDLE; - /* if there's a partial buffer left, copy it out. */ - int xfersize = (x->fifohead - x->fifotail + 1) / x->p.bytesperchannel(); - if (xfersize) { - soundfile_xferin(x->p.nchannels, noutlets, x->outvec, 0, - (unsigned char *)(x->buf + x->fifotail), xfersize, x->p.bytespersample, x->p.bigendian); - vecsize -= xfersize; - } - /* then zero out the (rest of the) output */ - for (int i=0; i<noutlets; i++) { - float *fp = x->outvec[i] + xfersize; - for (int j=vecsize; j--; ) *fp++ = 0; - } - sfread_cond_signal(&x->requestcondition); - pthread_mutex_unlock(&x->mutex); - return w+2; - } - soundfile_xferin(x->p.nchannels, noutlets, x->outvec, 0, (unsigned char *)(x->buf + x->fifotail), vecsize, x->p.bytespersample, x->p.bigendian); - x->fifotail += wantbytes; - if (x->fifotail >= x->fifosize) x->fifotail = 0; - if ((--x->sigcountdown) <= 0) { - sfread_cond_signal(&x->requestcondition); - x->sigcountdown = x->sigperiod; - } - pthread_mutex_unlock(&x->mutex); - } else { - for (int i=0; i<noutlets; i++) { - float *fp = x->outvec[i]; - for (int j=vecsize; j--; ) *fp++=0; - } - } - return w+2; -} - -static void readsf_start(t_readsf *x) { - /* start making output. If we're in the "startup" state change - to the "running" state. */ - if (x->state == STATE_STARTUP) x->state = STATE_STREAM; - else error("readsf: start requested with no prior 'open'"); -} - -static void readsf_stop(t_readsf *x) { - /* LATER rethink whether you need the mutex just to set a variable? */ - pthread_mutex_lock(&x->mutex); - x->state = STATE_IDLE; - x->requestcode = REQUEST_CLOSE; - sfread_cond_signal(&x->requestcondition); - pthread_mutex_unlock(&x->mutex); -} - -static void readsf_float(t_readsf *x, t_floatarg f) { - if (f != 0) readsf_start(x); else readsf_stop(x); -} - -/* open method. Called as: open filename [skipframes headersize channels bytespersample endianness] - (if headersize is zero, header is taken to be automatically detected; thus, use the special "-1" to mean a truly headerless file.) */ -static void readsf_open(t_readsf *x, t_symbol *s, int argc, t_atom *argv) { - t_symbol *filesym = atom_getsymbolarg(0, argc, argv); - t_float onsetframes = atom_getfloatarg(1, argc, argv); - t_float headerbytes = atom_getfloatarg(2, argc, argv); - t_float channels = atom_getfloatarg(3, argc, argv); - t_float bytespersample = atom_getfloatarg(4, argc, argv); - t_symbol *endian = atom_getsymbolarg(5, argc, argv); - if (!*filesym->name) return; - pthread_mutex_lock(&x->mutex); - x->requestcode = REQUEST_OPEN; - x->filename = filesym->name; - x->fifotail = 0; - x->fifohead = 0; - if (*endian->name == 'b') x->p.bigendian = 1; - else if (*endian->name == 'l') x->p.bigendian = 0; - else if (*endian->name) error("endianness neither 'b' nor 'l'"); - else x->p.bigendian = garray_ambigendian(); - x->onsetframes = max(long(onsetframes),0L); - x->skipheaderbytes = int(headerbytes > 0 ? headerbytes : headerbytes == 0 ? -1 : 0); - x->p.nchannels = max(int(channels),1); - x->p.bytespersample = max(int(bytespersample),2); - x->eof = 0; - x->fileerror = 0; - x->state = STATE_STARTUP; - sfread_cond_signal(&x->requestcondition); - pthread_mutex_unlock(&x->mutex); -} - -static void readsf_dsp(t_readsf *x, t_signal **sp) { - int i, noutlets = x->noutlets; - pthread_mutex_lock(&x->mutex); - x->vecsize = sp[0]->n; - x->sigperiod = (x->fifosize / (x->p.bytesperchannel() * x->vecsize)); - for (i = 0; i < noutlets; i++) x->outvec[i] = sp[i]->v; - pthread_mutex_unlock(&x->mutex); - dsp_add(readsf_perform, 1, x); -} - -static void readsf_print(t_readsf *x) { - post("state %d", x->state); - post("fifo head %d", x->fifohead); - post("fifo tail %d", x->fifotail); - post("fifo size %d", x->fifosize); - post("fd %d", x->fd); - post("eof %d", x->eof); -} - -static void readsf_free(t_readsf *x) { - /* request QUIT and wait for acknowledge */ - void *threadrtn; - pthread_mutex_lock(&x->mutex); - x->requestcode = REQUEST_QUIT; - sfread_cond_signal(&x->requestcondition); - while (x->requestcode != REQUEST_NOTHING) { - sfread_cond_signal(&x->requestcondition); - sfread_cond_wait(&x->answercondition, &x->mutex); - } - pthread_mutex_unlock(&x->mutex); - if (pthread_join(x->childthread, &threadrtn)) error("readsf_free: join failed"); - pthread_cond_destroy(&x->requestcondition); - pthread_cond_destroy(&x->answercondition); - pthread_mutex_destroy(&x->mutex); - free(x->buf); - clock_free(x->clock); -} - -static void readsf_setup() { - t_class *c = readsf_class = class_new2("readsf~", (t_newmethod)readsf_new, (t_method)readsf_free, sizeof(t_readsf), 0, "FF"); - class_addfloat(c, (t_method)readsf_float); - class_addmethod2(c, (t_method)readsf_start, "start",""); - class_addmethod2(c, (t_method)readsf_stop, "stop",""); - class_addmethod2(c, (t_method)readsf_dsp, "dsp",""); - class_addmethod2(c, (t_method)readsf_open, "open","*"); - class_addmethod2(c, (t_method)readsf_print, "print",""); -} - -/******************************* writesf *******************/ - -static t_class *writesf_class; -typedef t_readsf t_writesf; /* just re-use the structure */ - -/************** the child thread which performs file I/O ***********/ - -static void *writesf_child_main(void *zz) { - t_writesf *x = (t_writesf*)zz; - pthread_mutex_lock(&x->mutex); - while (1) { - if (x->requestcode == REQUEST_NOTHING) { - sfread_cond_signal(&x->answercondition); - sfread_cond_wait(&x->requestcondition, &x->mutex); - } else if (x->requestcode == REQUEST_OPEN) { - int fd, sysrtn, writebytes; - /* copy file stuff out of the data structure so we can relinquish the mutex while we're in open_soundfile(). */ - int filetype = x->filetype; - char *filename = x->filename; - t_canvas *canvas = x->canvas; - float samplerate = x->samplerate; - /* alter the request code so that an ensuing "open" will get noticed. */ - x->requestcode = REQUEST_BUSY; - x->fileerror = 0; - /* if there's already a file open, close it. This should never happen since - writesf_open() calls stop if needed and then waits until we're idle. */ - if (x->fd >= 0) { - int bytesperframe = x->p.bytesperchannel(); - char *filename = x->filename; - int fd = x->fd; - int filetype = x->filetype; - int itemswritten = x->itemswritten; - int swap = x->swap; - pthread_mutex_unlock(&x->mutex); - soundfile_finishwrite(x, filename, fd, filetype, 0x7fffffff, itemswritten, bytesperframe, swap); - close (fd); - pthread_mutex_lock(&x->mutex); - x->fd = -1; - if (x->requestcode != REQUEST_BUSY) continue; - } - /* open the soundfile with the mutex unlocked */ - pthread_mutex_unlock(&x->mutex); - fd = create_soundfile(canvas, filename, filetype, 0, - x->p.bytespersample, x->p.bigendian, x->p.nchannels, garray_ambigendian() != x->p.bigendian, samplerate); - pthread_mutex_lock(&x->mutex); - if (fd < 0) { - x->fd = -1; - x->eof = 1; - x->fileerror = errno; - x->requestcode = REQUEST_NOTHING; - continue; - } - /* check if another request has been made; if so, field it */ - if (x->requestcode != REQUEST_BUSY) continue; - x->fd = fd; - x->fifotail = 0; - x->itemswritten = 0; - x->swap = garray_ambigendian() != x->p.bigendian; - /* in a loop, wait for the fifo to have data and write it to disk */ - while (x->requestcode == REQUEST_BUSY || (x->requestcode == REQUEST_CLOSE && x->fifohead != x->fifotail)) { - int fifosize = x->fifosize, fifotail; - char *buf = x->buf; - /* if the head is < the tail, we can immediately write - from tail to end of fifo to disk; otherwise we hold off - writing until there are at least WRITESIZE bytes in the - buffer */ - if (x->fifohead < x->fifotail || x->fifohead >= x->fifotail + WRITESIZE - || (x->requestcode == REQUEST_CLOSE && x->fifohead != x->fifotail)) { - writebytes = (x->fifohead < x->fifotail ? fifosize : x->fifohead) - x->fifotail; - if (writebytes > READSIZE) writebytes = READSIZE; - } else { - sfread_cond_signal(&x->answercondition); - sfread_cond_wait(&x->requestcondition,&x->mutex); - continue; - } - fifotail = x->fifotail; - fd = x->fd; - pthread_mutex_unlock(&x->mutex); - sysrtn = write(fd, buf + fifotail, writebytes); - pthread_mutex_lock(&x->mutex); - if (x->requestcode != REQUEST_BUSY && x->requestcode != REQUEST_CLOSE) break; - if (sysrtn < writebytes) {x->fileerror = errno; break;} - else { - x->fifotail += sysrtn; - if (x->fifotail == fifosize) x->fifotail = 0; - } - x->itemswritten += sysrtn / x->p.bytesperchannel(); - /* signal parent in case it's waiting for data */ - sfread_cond_signal(&x->answercondition); - } - } else if (x->requestcode == REQUEST_CLOSE || x->requestcode == REQUEST_QUIT) { - if (x->fd >= 0) { - int bytesperframe = x->p.bytesperchannel(); - char *filename = x->filename; - int fd = x->fd; - int filetype = x->filetype; - int itemswritten = x->itemswritten; - int swap = x->swap; - pthread_mutex_unlock(&x->mutex); - soundfile_finishwrite(x, filename, fd, filetype, 0x7fffffff, itemswritten, bytesperframe, swap); - close(fd); - pthread_mutex_lock(&x->mutex); - x->fd = -1; - } - x->requestcode = REQUEST_NOTHING; - sfread_cond_signal(&x->answercondition); - } - if (x->requestcode == REQUEST_QUIT) break; - } - pthread_mutex_unlock(&x->mutex); - return 0; -} - -/******** the object proper runs in the calling (parent) thread ****/ - -static void *writesf_new(t_floatarg fnchannels, t_floatarg fbufsize) { - int nchannels = int(fnchannels), bufsize = int(fbufsize), i; - if (nchannels < 1) nchannels = 1; - else if (nchannels > MAXSFCHANS) nchannels = MAXSFCHANS; - if (bufsize <= 0) bufsize = DEFBUFPERCHAN * nchannels; - else if (bufsize < MINBUFSIZE) bufsize = MINBUFSIZE; - else if (bufsize > MAXBUFSIZE) bufsize = MAXBUFSIZE; - char *buf = (char *)getbytes(bufsize); - if (!buf) return 0; - t_writesf *x = (t_writesf *)pd_new(writesf_class); - for (i = 1; i < nchannels; i++) inlet_new(x,x, &s_signal, &s_signal); - x->f = 0; - x->p.nchannels = nchannels; - pthread_mutex_init(&x->mutex, 0); - pthread_cond_init(&x->requestcondition, 0); - pthread_cond_init(&x->answercondition, 0); - x->vecsize = MAXVECSIZE; - x->insamplerate = x->samplerate = 0; - x->state = STATE_IDLE; - x->clock = 0; /* no callback needed here */ - x->canvas = canvas_getcurrent(); - x->p.bytespersample = 2; - x->fd = -1; - x->buf = buf; - x->bufsize = bufsize; - x->fifosize = x->fifohead = x->fifotail = x->requestcode = 0; - pthread_create(&x->childthread, 0, writesf_child_main, x); - return x; -} - -static t_int *writesf_perform(t_int *w) { - t_writesf *x = (t_writesf *)(w[1]); - if (x->state == STATE_STREAM) { - int wantbytes; - pthread_mutex_lock(&x->mutex); - wantbytes = x->vecsize * x->p.bytesperchannel(); - while (x->fifotail > x->fifohead && x->fifotail < x->fifohead + wantbytes + 1) { - sfread_cond_signal(&x->requestcondition); - sfread_cond_wait(&x->answercondition, &x->mutex); - /* resync local cariables -- bug fix thanks to Shahrokh */ - wantbytes = x->vecsize * x->p.bytesperchannel(); - } - soundfile_xferout(x->p.nchannels, x->outvec, (unsigned char *)(x->buf + x->fifohead), x->vecsize, 0, x->p.bytespersample, x->p.bigendian, 1.); - x->fifohead += wantbytes; - if (x->fifohead >= x->fifosize) x->fifohead = 0; - if ((--x->sigcountdown) <= 0) { - sfread_cond_signal(&x->requestcondition); - x->sigcountdown = x->sigperiod; - } - pthread_mutex_unlock(&x->mutex); - } - return w+2; -} - -static void writesf_start(t_writesf *x) { - /* start making output. If we're in the "startup" state change to the "running" state. */ - if (x->state == STATE_STARTUP) x->state = STATE_STREAM; - else error("writesf: start requested with no prior 'open'"); -} - -static void writesf_stop(t_writesf *x) { - /* LATER rethink whether you need the mutex just to set a Svariable? */ - pthread_mutex_lock(&x->mutex); - x->state = STATE_IDLE; - x->requestcode = REQUEST_CLOSE; - sfread_cond_signal(&x->requestcondition); - pthread_mutex_unlock(&x->mutex); -} - -/* open method. Called as: open [args] filename with args as in soundfiler_writeargparse(). */ -static void writesf_open(t_writesf *x, t_symbol *s, int argc, t_atom *argv) { - t_symbol *filesym; - int filetype, bytespersample, swap, bigendian, normalize; - long onset, nframes; - float samplerate; - if (x->state != STATE_IDLE) writesf_stop(x); - if (soundfiler_writeargparse(x, &argc, &argv, &filesym, &filetype, &bytespersample, &swap, &bigendian, - &normalize, &onset, &nframes, &samplerate)) { - error("writesf~: usage: open [-bytes [234]] [-wave,-nextstep,-aiff] ..."); - post("... [-big,-little] [-rate ####] filename"); - return; - } - if (normalize || onset || (nframes != 0x7fffffff)) - error("normalize/onset/nframes argument to writesf~: ignored"); - if (argc) error("extra argument(s) to writesf~: ignored"); - pthread_mutex_lock(&x->mutex); - while (x->requestcode != REQUEST_NOTHING) { - sfread_cond_signal(&x->requestcondition); - sfread_cond_wait(&x->answercondition, &x->mutex); - } - x->p.bytespersample = max(bytespersample,2); - x->swap = swap; - x->p.bigendian = bigendian; - x->filename = filesym->name; - x->filetype = filetype; - x->itemswritten = 0; - x->requestcode = REQUEST_OPEN; - x->fifotail = 0; - x->fifohead = 0; - x->eof = 0; - x->fileerror = 0; - x->state = STATE_STARTUP; - x->samplerate = samplerate>0 ? samplerate : x->insamplerate>0 ? x->insamplerate : sys_getsr(); - /* set fifosize from bufsize. fifosize must be a multiple of the number of bytes eaten for each DSP tick. */ - x->fifosize = x->bufsize - x->bufsize % (x->p.bytesperchannel() * MAXVECSIZE); - /* arrange for the "request" condition to be signalled 16 times per buffer */ - x->sigcountdown = x->sigperiod = x->fifosize / (16 * x->p.bytesperchannel() * x->vecsize); - sfread_cond_signal(&x->requestcondition); - pthread_mutex_unlock(&x->mutex); -} - -static void writesf_dsp(t_writesf *x, t_signal **sp) { - int ninlets = x->p.nchannels; - pthread_mutex_lock(&x->mutex); - x->vecsize = sp[0]->n; - x->sigperiod = x->fifosize / (x->p.bytesperchannel() * x->vecsize); - for (int i=0; i<ninlets; i++) x->outvec[i] = sp[i]->v; - x->insamplerate = sp[0]->sr; - pthread_mutex_unlock(&x->mutex); - dsp_add(writesf_perform, 1, x); -} - -static void writesf_print(t_writesf *x) { - post("state %d", x->state); - post("fifo head %d", x->fifohead); - post("fifo tail %d", x->fifotail); - post("fifo size %d", x->fifosize); - post("fd %d", x->fd); - post("eof %d", x->eof); -} - -static void writesf_free(t_writesf *x) { - /* request QUIT and wait for acknowledge */ - void *threadrtn; - pthread_mutex_lock(&x->mutex); - x->requestcode = REQUEST_QUIT; - /* post("stopping writesf thread..."); */ - sfread_cond_signal(&x->requestcondition); - while (x->requestcode != REQUEST_NOTHING) { - /* post("signalling..."); */ - sfread_cond_signal(&x->requestcondition); - sfread_cond_wait(&x->answercondition, &x->mutex); - } - pthread_mutex_unlock(&x->mutex); - if (pthread_join(x->childthread, &threadrtn)) error("writesf_free: join failed"); - /* post("... done."); */ - pthread_cond_destroy(&x->requestcondition); - pthread_cond_destroy(&x->answercondition); - pthread_mutex_destroy(&x->mutex); - free(x->buf); -} - -static void writesf_setup() { - t_class *c = writesf_class = class_new2("writesf~", (t_newmethod)writesf_new, (t_method)writesf_free, sizeof(t_writesf), 0, "FF"); - class_addmethod2(c, (t_method)writesf_start, "start", ""); - class_addmethod2(c, (t_method)writesf_stop, "stop", ""); - class_addmethod2(c, (t_method)writesf_dsp, "dsp", ""); - class_addmethod2(c, (t_method)writesf_open, "open", "*"); - class_addmethod2(c, (t_method)writesf_print, "print", ""); - CLASS_MAINSIGNALIN(c, t_writesf, f); -} - -/* ------------------------ global setup routine ------------------------- */ - -void d_soundfile_setup() { - if (sizeof(uint16)!=2) bug("uint16 should really be 16 bits"); - if (sizeof(uint32)!=4) bug("uint32 should really be 32 bits"); - soundfiler_setup(); - readsf_setup(); - writesf_setup(); -} diff --git a/desiredata/src/d_ugen.c b/desiredata/src/d_ugen.c deleted file mode 100644 index cccedbe7..00000000 --- a/desiredata/src/d_ugen.c +++ /dev/null @@ -1,972 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* These routines build a copy of the DSP portion of a graph, which is - then sorted into a linear list of DSP operations which are added to - the DSP duty cycle called by the scheduler. Once that's been done, - we delete the copy. The DSP objects are represented by "ugenbox" - structures which are parallel to the DSP objects in the graph and - have vectors of siginlets and sigoutlets which record their - interconnections. -*/ - -/* hacked to run subpatches with different power-of-2 samplerates - mfg.gfd.uil IOhannes */ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -#include <stdlib.h> -#include <stdarg.h> - -/* T.Grill - include SIMD functionality */ -#include "m_simd.h" - -extern t_class *vinlet_class, *voutlet_class, *canvas_class; -t_sample *obj_findsignalscalar(t_object *x, int m); -static int ugen_loud; -static t_int *dsp_chain; -static int dsp_chainsize; -struct t_vinlet; -struct t_voutlet; - -void vinlet_dspprolog(t_vinlet *x, t_signal **parentsigs, int myvecsize, int calcsize, int phase, int period, int frequency, - int downsample, int upsample, int reblock, int switched); -void voutlet_dspprolog(t_voutlet *x, t_signal **parentsigs, int myvecsize, int calcsize, int phase, int period, int frequency, - int downsample, int upsample, int reblock, int switched); -void voutlet_dspepilog(t_voutlet *x, t_signal **parentsigs, int myvecsize, int calcsize, int phase, int period, int frequency, - int downsample, int upsample, int reblock, int switched); - -/* zero out a vector */ -t_int *zero_perform(t_int *w) { - t_float *out = (t_float *)w[1]; - int n = int(w[2]); - while (n--) *out++ = 0; - return w+3; -} - -t_int *zero_perf8(t_int *w) { - t_float *out = (t_float *)w[1]; - int n = int(w[2]); - for (; n; n -= 8, out += 8) { - out[0] = 0; out[1] = 0; - out[2] = 0; out[3] = 0; - out[4] = 0; out[5] = 0; - out[6] = 0; out[7] = 0; - } - return w+3; -} - -void dsp_add_zero(t_sample *out, int n) { - if (n&7) dsp_add(zero_perform, 2, out, n); - else if(SIMD_CHECK1(n,out)) dsp_add(zero_perf_simd, 2, out, n); - else dsp_add(zero_perf8, 2, out, n); -} - -/* ---------------------------- block~ ----------------------------- */ -/* The "block~ object maintains the containing canvas's DSP computation, -calling it at a super- or sub-multiple of the containing canvas's -calling frequency. The block~'s creation arguments specify block size -and overlap. Block~ does no "dsp" computation in its own right, but it -adds prolog and epilog code before and after the canvas's unit generators. - -A subcanvas need not have a block~ at all; if there's none, its -ugens are simply put on the list without any prolog or epilog code. - -Block~ may be invoked as switch~, in which case it also acts to switch the -subcanvas on and off. The overall order of scheduling for a subcanvas -is thus, - - inlet and outlet prologue code (1) - block prologue (2) - the objects in the subcanvas, including inlets and outlets - block epilogue (2) - outlet epilogue code (2) - -where (1) means, "if reblocked" and (2) means, "if reblocked or switched". - -If we're reblocked, the inlet prolog and outlet epilog code takes care of -overlapping and buffering to deal with vector size changes. If we're switched -but not reblocked, the inlet prolog is not needed, and the output epilog is -ONLY run when the block is switched off; in this case the epilog code simply -copies zeros to all signal outlets. -*/ - -static int dsp_phase; -static t_class *block_class; - -struct t_block : t_object { - int vecsize; /* size of audio signals in this block */ - int calcsize; /* number of samples actually to compute */ - int overlap; - int phase; /* from 0 to period-1; when zero we run the block */ - int period; /* submultiple of containing canvas */ - int frequency; /* supermultiple of comtaining canvas */ - int count; /* number of times parent block has called us */ - int chainonset; /* beginning of code in DSP chain */ - int blocklength; /* length of dspchain for this block */ - int epiloglength; /* length of epilog */ - char switched; /* true if we're acting as a a switch */ - char switchon; /* true if we're switched on */ - char reblock; /* true if inlets and outlets are reblocking */ - int upsample; /* IOhannes: upsampling-factor */ - int downsample; /* IOhannes: downsampling-factor */ - int x_return; /* stop right after this block (for one-shots) */ -}; - -static void block_set(t_block *x, t_floatarg fvecsize, t_floatarg foverlap, t_floatarg fupsample); - -static void *block_new(t_floatarg fcalcsize, t_floatarg foverlap, t_floatarg fupsample) /* IOhannes */ { - t_block *x = (t_block *)pd_new(block_class); - x->phase = 0; - x->period = 1; - x->frequency = 1; - x->switched = 0; - x->switchon = 1; - block_set(x, fcalcsize, foverlap, fupsample); - return x; -} - -static void block_set(t_block *x, t_floatarg fcalcsize, t_floatarg foverlap, t_floatarg fupsample) { - int upsample, downsample; /* IOhannes */ - int calcsize = (int)fcalcsize; - int overlap = (int)foverlap; - int dspstate = canvas_suspend_dsp(); - if (overlap < 1) overlap = 1; - if (calcsize < 0) calcsize = 0; /* this means we'll get it from parent later. */ - /* IOhannes { */ - if (fupsample <= 0) upsample = downsample = 1; - else if (fupsample >= 1) { - upsample = (int)fupsample; - downsample = 1; - } else { - downsample = int(1.0 / fupsample); - upsample = 1; - } - /* } IOhannes */ - /* vecsize is smallest power of 2 large enough to hold calcsize */ - int vecsize = 0; - if (calcsize) { - vecsize = (1 << ilog2(calcsize)); - if (vecsize != calcsize) vecsize *= 2; - } - if (vecsize && vecsize != (1 << ilog2(vecsize))) {error("block~: vector size not a power of 2"); vecsize = 64;} - if ( overlap != (1 << ilog2(overlap))) {error("block~: overlap not a power of 2"); overlap = 1;} - /* IOhannes { */ - if (downsample != (1 << ilog2(downsample))) {error("block~: downsampling not a power of 2"); downsample = 1;} - if ( upsample != (1 << ilog2( upsample))) {error("block~: upsampling not a power of 2"); upsample = 1;} - /* } IOhannes */ - x->calcsize = calcsize; - x->vecsize = vecsize; - x->overlap = overlap; - /* IOhannes { */ - x->upsample = upsample; - x->downsample = downsample; - /* } IOhannes */ - canvas_resume_dsp(dspstate); -} - -static void *switch_new(t_floatarg fvecsize, t_floatarg foverlap, t_floatarg fupsample) /* IOhannes */ { - t_block *x = (t_block *)(block_new(fvecsize, foverlap, fupsample)); /* IOhannes */ - x->switched = 1; - x->switchon = 0; - return x; -} - -static void block_float(t_block *x, t_floatarg f) { - if (x->switched) x->switchon = f!=0; -} - -static void block_bang(t_block *x) { - if (x->switched && !x->switchon) { - x->x_return = 1; - for (t_int *ip = dsp_chain + x->chainonset; ip; ) ip = t_perfroutine(*ip)(ip); - x->x_return = 0; - } else error("bang to block~ or on-state switch~ has no effect"); -} - -#define PROLOGCALL 2 -#define EPILOGCALL 2 - -static t_int *block_prolog(t_int *w) { - t_block *x = (t_block *)w[1]; - int phase = x->phase; - /* if we're switched off, jump past the epilog code */ - if (!x->switchon) return w+x->blocklength; - if (phase) { - phase++; - if (phase == x->period) phase = 0; - x->phase = phase; - return w+x->blocklength; /* skip block; jump past epilog */ - } else { - x->count = x->frequency; - x->phase = (x->period > 1 ? 1 : 0); - return w+PROLOGCALL; /* beginning of block is next ugen */ - } -} - -static t_int *block_epilog(t_int *w) { - t_block *x = (t_block *)w[1]; - int count = x->count - 1; - if (x->x_return) return 0; - if (!x->reblock) return w+x->epiloglength+EPILOGCALL; - if (count) { - x->count = count; - return w - (x->blocklength - (PROLOGCALL + EPILOGCALL)); /* go to ugen after prolog */ - } else return w+EPILOGCALL; -} - -static void block_dsp(t_block *x, t_signal **sp) {/* do nothing here */} - -void block_tilde_setup() { - block_class = class_new2("block~", (t_newmethod)block_new, 0, sizeof(t_block), 0,"FFF"); - class_addcreator2("switch~",(t_newmethod)switch_new,"FFF"); - class_addmethod2(block_class, (t_method)block_set,"set","FFF"); - class_addmethod2(block_class, (t_method)block_dsp,"dsp",""); - class_addfloat(block_class, block_float); - class_addbang(block_class, block_bang); -} - -/* ------------------ DSP call list ----------------------- */ - -static t_int dsp_done(t_int *w) {return 0;} - -void dsp_add(t_perfroutine f, int n, ...) { - va_list ap; - va_start(ap, n); - int newsize = dsp_chainsize + n+1; - dsp_chain = (t_int *)resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int), newsize * sizeof (t_int)); - dsp_chain[dsp_chainsize-1] = (t_int)f; - for (int i=0; i<n; i++) dsp_chain[dsp_chainsize + i] = va_arg(ap, t_int); - dsp_chain[newsize-1] = (t_int)dsp_done; - dsp_chainsize = newsize; - va_end(ap); -} - -/* at Guenter's suggestion, here's a vectorized version */ -void dsp_addv(t_perfroutine f, int n, t_int *vec) { - int newsize = dsp_chainsize + n+1; - dsp_chain = (t_int *)resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int), newsize * sizeof (t_int)); - dsp_chain[dsp_chainsize-1] = (t_int)f; - for (int i=0; i<n; i++) dsp_chain[dsp_chainsize + i] = vec[i]; - dsp_chain[newsize-1] = (t_int)dsp_done; - dsp_chainsize = newsize; -} - -void dsp_tick() { - if (dsp_chain) { - for (t_int *ip = dsp_chain; ip; ) ip = ((t_perfroutine)*ip)(ip); - dsp_phase++; - } -} - -/* ---------------- signals ---------------------------- */ - -int ilog2(int n) { - int r = -1; - if (n <= 0) return 0; - while (n) { - r++; - n >>= 1; - } - return r; -} - -/* list of signals which can be reused, sorted by buffer size */ -static t_signal *signal_freelist[MAXLOGSIG+1]; -/* list of reusable "borrowed" signals (which don't own sample buffers) */ -static t_signal *signal_freeborrowed; -/* list of all signals allocated (not including "borrowed" ones) */ -static t_signal *signal_usedlist; - -/* call this when DSP is stopped to free all the signals */ -void signal_cleanup() { - t_signal *sig; - while ((sig = signal_usedlist)) { - signal_usedlist = sig->nextused; - if (!sig->isborrowed) { -#ifndef VECTORALIGNMENT - free(sig->v); -#else - freealignedbytes(sig->v, sig->vecsize * sizeof (*sig->v)); -#endif - } - free(sig); - } - for (int i=0; i<=MAXLOGSIG; i++) signal_freelist[i] = 0; - signal_freeborrowed = 0; -} - -/* mark the signal "reusable." */ -extern "C" void signal_makereusable(t_signal *sig) { - int logn = ilog2(sig->vecsize); -#if 1 - for (t_signal *s5 = signal_freeborrowed; s5; s5 = s5->nextfree) {if (s5 == sig) {bug("signal_free 3"); return;}} - for (t_signal *s5 = signal_freelist[logn]; s5; s5 = s5->nextfree) {if (s5 == sig) {bug("signal_free 4"); return;}} -#endif - if (ugen_loud) post("free %lx: %d", long(sig), sig->isborrowed); - if (sig->isborrowed) { - /* if the signal is borrowed, decrement the borrowed-from signal's reference count, possibly marking it reusable too */ - t_signal *s2 = sig->borrowedfrom; - if ((s2 == sig) || !s2) bug("signal_free"); - s2->refcount--; - if (!s2->refcount) signal_makereusable(s2); - sig->nextfree = signal_freeborrowed; - signal_freeborrowed = sig; - } else { - /* if it's a real signal (not borrowed), put it on the free list so we can reuse it. */ - if (signal_freelist[logn] == sig) bug("signal_free 2"); - sig->nextfree = signal_freelist[logn]; - signal_freelist[logn] = sig; - } -} - -/* reclaim or make an audio signal. If n is zero, return a "borrowed" - signal whose buffer and size will be obtained later via signal_setborrowed(). */ -t_signal *signal_new(int n, float sr) { - int vecsize = 0; - t_signal *ret, **whichlist; - int logn = ilog2(n); - if (n) { - if ((vecsize = (1<<logn)) != n) vecsize *= 2; - if (logn > MAXLOGSIG) bug("signal buffer too large"); - whichlist = signal_freelist + logn; - } else whichlist = &signal_freeborrowed; - /* first try to reclaim one from the free list */ - ret = *whichlist; - if (ret) *whichlist = ret->nextfree; - else { - /* LATER figure out what to do for out-of-space here! */ - ret = (t_signal *)t_getbytes(sizeof *ret); - if (n) { -#ifndef VECTORALIGNMENT - ret->v = (t_sample *)getbytes(vecsize * sizeof (*ret->v)); -#else - /* T.Grill - make signal vectors aligned! */ - ret->v = (t_sample *)getalignedbytes(vecsize * sizeof (*ret->v)); -#endif - ret->isborrowed = 0; - } else { - ret->v = 0; - ret->isborrowed = 1; - } - ret->nextused = signal_usedlist; - signal_usedlist = ret; - } - ret->n = n; - ret->vecsize = vecsize; - ret->sr = sr; - ret->refcount = 0; - ret->borrowedfrom = 0; - if (ugen_loud) post("new %lx: %d", long(ret), ret->isborrowed); - return ret; -} - -static t_signal *signal_newlike(const t_signal *sig) {return signal_new(sig->n, sig->sr);} - -extern "C" void signal_setborrowed(t_signal *sig, t_signal *sig2) { - if (!sig->isborrowed || sig->borrowedfrom) bug("signal_setborrowed"); - if (sig == sig2) bug("signal_setborrowed 2"); - sig->borrowedfrom = sig2; - sig->v = sig2->v; - sig->n = sig2->n; - sig->vecsize = sig2->vecsize; -} - -int signal_compatible(t_signal *s1, t_signal *s2) {return s1->n == s2->n && s1->sr == s2->sr;} - -/* ------------------ ugen ("unit generator") sorting ----------------- */ - -struct t_ugenbox { - struct t_siginlet *in; int nin; - struct t_sigoutlet *out; int nout; - int u_phase; - t_ugenbox *next; - t_object *obj; - int done; -}; - -struct t_siginlet { - int nconnect; - int ngot; - t_signal *signal; -}; - -struct t_sigoutconnect { - t_ugenbox *who; - int inno; - t_sigoutconnect *next; -}; - -struct t_sigoutlet { - int nconnect; - int nsent; - t_signal *signal; - t_sigoutconnect *connections; -}; - -struct t_dspcontext { - t_ugenbox *ugenlist; - t_dspcontext *parentcontext; - int ninlets; - int noutlets; - t_signal **iosigs; - float srate; - int vecsize; /* vector size, power of two */ - int calcsize; /* number of elements to calculate */ - char toplevel; /* true if "iosigs" is invalid. */ - char reblock; /* true if we have to reblock inlets/outlets */ - char switched; /* true if we're switched */ -}; - -static int ugen_sortno = 0; -static t_dspcontext *ugen_currentcontext; - -void ugen_stop() { - if (dsp_chain) { - free(dsp_chain); - dsp_chain = 0; - } - signal_cleanup(); -} - -void ugen_start() { - ugen_stop(); - ugen_sortno++; - dsp_chain = (t_int *)getbytes(sizeof(*dsp_chain)); - dsp_chain[0] = (t_int)dsp_done; - dsp_chainsize = 1; - if (ugen_currentcontext) bug("ugen_start"); -} - -int ugen_getsortno() {return ugen_sortno;} - -#if 0 -void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv) { - int i, count; - t_signal *sig; - for (count = 0, sig = signal_usedlist; sig; count++, sig = sig->nextused) {} - post("used signals %d", count); - for (i = 0; i < MAXLOGSIG; i++) { - for (count = 0, sig = signal_freelist[i]; sig; count++, sig = sig->nextfree) {} - if (count) post("size %d: free %d", (1 << i), count); - } - for (count = 0, sig = signal_freeborrowed; sig; count++, sig = sig->nextfree) {} - post("free borrowed %d", count); - ugen_loud = argc; -} -#endif - -/* start building the graph for a canvas */ -extern "C" t_dspcontext *ugen_start_graph(int toplevel, t_signal **sp, int ninlets, int noutlets) { - t_dspcontext *dc = (t_dspcontext *)getbytes(sizeof(*dc)); - if (ugen_loud) post("ugen_start_graph..."); - dc->ugenlist = 0; - dc->toplevel = toplevel; - dc->iosigs = sp; - dc->ninlets = ninlets; - dc->noutlets = noutlets; - dc->parentcontext = ugen_currentcontext; - ugen_currentcontext = dc; - return dc; -} - -/* first the canvas calls this to create all the boxes... */ -extern "C" void ugen_add(t_dspcontext *dc, t_object *obj) { - t_ugenbox *x = (t_ugenbox *)getbytes(sizeof *x); - int i; - t_sigoutlet *uout; - t_siginlet *uin; - x->next = dc->ugenlist; - dc->ugenlist = x; - x->obj = obj; - x->nin = obj_nsiginlets(obj); - x->in = (t_siginlet *)getbytes(x->nin * sizeof (*x->in)); - for (uin = x->in, i = x->nin; i--; uin++) uin->nconnect = 0; - x->nout = obj_nsigoutlets(obj); - x->out = (t_sigoutlet *)getbytes(x->nout * sizeof (*x->out)); - for (uout = x->out, i = x->nout; i--; uout++) uout->connections = 0, uout->nconnect = 0; -} - -/* and then this to make all the connections. */ -extern "C" void ugen_connect(t_dspcontext *dc, t_object *x1, int outno, t_object *x2, int inno) { - t_ugenbox *u1, *u2; - int sigoutno = obj_sigoutletindex(x1, outno); - int siginno = obj_siginletindex(x2, inno); - if (ugen_loud) post("%s -> %s: %d->%d", class_getname(x1->ob_pd), class_getname(x2->ob_pd), outno, inno); - for (u1 = dc->ugenlist; u1 && u1->obj != x1; u1 = u1->next) {} - for (u2 = dc->ugenlist; u2 && u2->obj != x2; u2 = u2->next) {} - if (!u1 || !u2 || siginno < 0) { - pd_error(u1->obj, "signal outlet connect to nonsignal inlet (ignored)"); - return; - } - if (sigoutno < 0 || sigoutno >= u1->nout || siginno >= u2->nin) { - bug("ugen_connect %s %s %d %d (%d %d)", - class_getname(x1->ob_pd), class_getname(x2->ob_pd), sigoutno, siginno, u1->nout, u2->nin); - } - t_sigoutlet *uout = u1->out + sigoutno; - t_siginlet * uin = u2->in + siginno; - /* add a new connection to the outlet's list */ - t_sigoutconnect *oc = (t_sigoutconnect *)getbytes(sizeof *oc); - oc->next = uout->connections; - uout->connections = oc; - oc->who = u2; - oc->inno = siginno; - /* update inlet and outlet counts */ - uout->nconnect++; - uin->nconnect++; -} - -/* get the index of a ugenbox or -1 if it's not on the list */ -static int ugen_index(t_dspcontext *dc, t_ugenbox *x) { - int ret=0; - for (t_ugenbox *u = dc->ugenlist; u; u = u->next, ret++) if (u == x) return ret; - return -1; -} - -/* put a ugenbox on the chain, recursively putting any others on that this one might uncover. */ -static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) { - t_sigoutlet *uout; - t_siginlet *uin; - t_sigoutconnect *oc; - t_class *klass = pd_class(u->obj); - int i, n; - /* suppress creating new signals for the outputs of signal-inlets and subpatches, except in the case we're an inlet - and "blocking" is set. We don't yet know if a subcanvas will be "blocking" so there we delay new signal creation, - which will be handled by calling signal_setborrowed in the ugen_done_graph routine below. When we encounter a - subcanvas or a signal outlet, suppress freeing the input signals as they may be "borrowed" for the parent or subpatch; - same exception as above, but also if we're "switched" we have to do a copy rather than a borrow. */ - int nonewsigs = klass==canvas_class || (klass==vinlet_class && ! dc->reblock ); - int nofreesigs = klass==canvas_class || (klass==voutlet_class && !(dc->reblock || dc->switched)); - t_signal **insig, **outsig, **sig, *s1, *s2, *s3; - t_ugenbox *u2; - if (ugen_loud) post("doit %s %d %d", class_getname(klass), nofreesigs, nonewsigs); - for (i = 0, uin = u->in; i < u->nin; i++, uin++) { - if (!uin->nconnect) { - t_sample *scalar; - s3 = signal_new(dc->vecsize, dc->srate); - /* post("%s: unconnected signal inlet set to zero", class_getname(u->obj->ob_pd)); */ - if ((scalar = obj_findsignalscalar(u->obj, i))) dsp_add_scalarcopy(scalar, s3->v, s3->n); - else dsp_add_zero(s3->v, s3->n); - uin->signal = s3; - s3->refcount = 1; - } - } - insig = (t_signal **)getbytes((u->nin + u->nout) * sizeof(t_signal *)); - outsig = insig + u->nin; - for (sig = insig, uin = u->in, i = u->nin; i--; sig++, uin++) { - int newrefcount; - *sig = uin->signal; - newrefcount = --(*sig)->refcount; - /* if the reference count went to zero, we free the signal now, - unless it's a subcanvas or outlet; these might keep the - signal around to send to objects connected to them. In this - case we increment the reference count; the corresponding decrement - is in sig_makereusable(). */ - if (nofreesigs) (*sig)->refcount++; - else if (!newrefcount) signal_makereusable(*sig); - } - for (sig = outsig, uout = u->out, i = u->nout; i--; sig++, uout++) { - /* similarly, for outlets of subcanvases we delay creating - them; instead we create "borrowed" ones so that the refcount - is known. The subcanvas replaces the fake signal with one showing - where the output data actually is, to avoid having to copy it. - For any other object, we just allocate a new output vector; - since we've already freed the inputs the objects might get called "in place." */ - *sig = uout->signal = nonewsigs ? - signal_new(0, dc->srate) : - signal_new(dc->vecsize, dc->srate); - (*sig)->refcount = uout->nconnect; - } - /* now call the DSP scheduling routine for the ugen. This routine must fill in "borrowed" - signal outputs in case it's either a subcanvas or a signal inlet. */ - mess1(u->obj, gensym("dsp"), insig); - /* if any output signals aren't connected to anyone, free them now; otherwise they'll either - get freed when the reference count goes back to zero, or even later as explained above. */ - for (sig = outsig, uout = u->out, i = u->nout; i--; sig++, uout++) { - if (!(*sig)->refcount) signal_makereusable(*sig); - } - if (ugen_loud) { - if (u->nin+u->nout==0) post("put %s %d", class_getname(u->obj->ob_pd),ugen_index(dc,u)); - else if (u->nin+u->nout==1) post("put %s %d (%lx)", class_getname(u->obj->ob_pd),ugen_index(dc,u),long(sig[0])); - else if (u->nin+u->nout==2) post("put %s %d (%lx %lx)",class_getname(u->obj->ob_pd),ugen_index(dc,u),long(sig[0]),long(sig[1])); - else post("put %s %d (%lx %lx %lx ...)",class_getname(u->obj->ob_pd),ugen_index(dc,u),long(sig[0]),long(sig[1]),long(sig[2])); - } - /* pass it on and trip anyone whose last inlet was filled */ - for (uout = u->out, i = u->nout; i--; uout++) { - s1 = uout->signal; - for (oc = uout->connections; oc; oc = oc->next) { - u2 = oc->who; - uin = &u2->in[oc->inno]; - /* if there's already someone here, sum the two */ - s2 = uin->signal; - if (s2) { - s1->refcount--; - s2->refcount--; - if (!signal_compatible(s1, s2)) {pd_error(u->obj, "%s: incompatible signal inputs", class_getname(u->obj->ob_pd)); return;} - s3 = signal_newlike(s1); - dsp_add_plus(s1->v, s2->v, s3->v, s1->n); - uin->signal = s3; - s3->refcount = 1; - if (!s1->refcount) signal_makereusable(s1); - if (!s2->refcount) signal_makereusable(s2); - } else uin->signal = s1; - uin->ngot++; - if (uin->ngot < uin->nconnect) goto notyet; - if (u2->nin > 1) for (uin = u2->in, n = u2->nin; n--; uin++) if (uin->ngot < uin->nconnect) goto notyet; - ugen_doit(dc, u2); - notyet: ; - } - } - free(insig); - u->done = 1; -} - -/* once the DSP graph is built, we call this routine to sort it. This routine also deletes the graph; later we might - want to leave the graph around, in case the user is editing the DSP network, to save having to recreate it all the - time. But not today. */ -extern "C" void ugen_done_graph(t_dspcontext *dc) { - t_sigoutlet *uout; - t_siginlet *uin; - int i, n; - t_block *blk; - int period, frequency, phase, vecsize, calcsize; - float srate; - int reblock = 0, switched; - int downsample = 1, upsample = 1; /* IOhannes */ - /* debugging printout */ - if (ugen_loud) { - post("ugen_done_graph..."); - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - post("ugen: %s", class_getname(u->obj->ob_pd)); - for (uout = u->out, i = 0; i < u->nout; uout++, i++) - for (t_sigoutconnect *oc = uout->connections; oc; oc = oc->next) { - post("... out %d to %s, index %d, inlet %d", i, class_getname(oc->who->obj->ob_pd), ugen_index(dc, oc->who), oc->inno); - } - } - } - /* search for an object of class "block~" */ - blk = 0; - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - t_pd *zz = u->obj; - if (pd_class(zz) == block_class) { - if (blk) pd_error(blk, "conflicting block~ objects in same page"); - else blk = (t_block *)zz; - } - } - t_dspcontext *parent_context = dc->parentcontext; - float parent_srate = parent_context ? parent_context->srate : sys_getsr(); - int parent_vecsize = parent_context ? parent_context->vecsize : sys_getblksize(); - if (blk) { - int realoverlap; - vecsize = blk->vecsize; if (!vecsize) vecsize = parent_vecsize; - calcsize = blk->calcsize;if (!calcsize) calcsize = vecsize; - realoverlap = blk->overlap; if (realoverlap > vecsize) realoverlap = vecsize; - /* IOhannes { */ - downsample = blk->downsample; - upsample = blk->upsample; - if (downsample > parent_vecsize) downsample=parent_vecsize; - period = (vecsize * downsample) / (parent_vecsize * realoverlap * upsample); - frequency = (parent_vecsize * realoverlap * upsample) / (vecsize * downsample); - /* } IOhannes*/ - phase = blk->phase; - srate = parent_srate * realoverlap * upsample / downsample; - /* IOhannes */ - if (period < 1) period = 1; - if (frequency < 1) frequency = 1; - blk->frequency = frequency; - blk->period = period; - blk->phase = dsp_phase & (period - 1); - if (!parent_context || realoverlap!=1 || vecsize!=parent_vecsize || downsample!=1 || upsample!=1) /* IOhannes */ - reblock = 1; - switched = blk->switched; - } else { - srate = parent_srate; - vecsize = parent_vecsize; - calcsize = parent_context ? parent_context->calcsize : vecsize; - downsample = upsample = 1;/* IOhannes */ - period = frequency = 1; - phase = 0; - if (!parent_context) reblock = 1; - switched = 0; - } - dc->reblock = reblock; - dc->switched = switched; - dc->srate = srate; - dc->vecsize = vecsize; - dc->calcsize = calcsize; - /* if we're reblocking or switched, we now have to create output signals to fill in for the "borrowed" ones we - have now. This is also possibly true even if we're not blocked/switched, in the case that there was a - signal loop. But we don't know this yet. */ - if (dc->iosigs && (switched || reblock)) { - t_signal **sigp; - for (i = 0, sigp = dc->iosigs + dc->ninlets; i < dc->noutlets; i++, sigp++) { - if ((*sigp)->isborrowed && !(*sigp)->borrowedfrom) { - signal_setborrowed(*sigp, signal_new(parent_vecsize, parent_srate)); - (*sigp)->refcount++; - if (ugen_loud) post("set %lx->%lx", long(*sigp), long((*sigp)->borrowedfrom)); - } - } - } - if (ugen_loud) post("reblock %d, switched %d", reblock, switched); - /* schedule prologs for inlets and outlets. If the "reblock" flag is set, an inlet will put code on the DSP chain - to copy its input into an internal buffer here, before any unit generators' DSP code gets scheduled. If we don't - "reblock", inlets will need to get pointers to their corresponding inlets/outlets on the box we're inside, - if any. Outlets will also need pointers, unless we're switched, in which case outlet epilog code will kick in. */ - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - t_pd *zz = u->obj; - t_signal **outsigs = dc->iosigs; - if (outsigs) outsigs += dc->ninlets; - if (pd_class(zz) == vinlet_class) - vinlet_dspprolog((t_vinlet *)zz, dc->iosigs, vecsize, calcsize, dsp_phase, period, frequency, - downsample, upsample, reblock, switched); - else if (pd_class(zz) == voutlet_class) - voutlet_dspprolog((t_voutlet *)zz, outsigs, vecsize, calcsize, dsp_phase, period, frequency, - downsample, upsample, reblock, switched); - } - int chainblockbegin = dsp_chainsize; /* DSP chain onset before block prolog code */ - if (blk && (reblock || switched)) { /* add the block DSP prolog */ - dsp_add(block_prolog, 1, blk); - blk->chainonset = dsp_chainsize - 1; - } - /* Initialize for sorting */ - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - u->done = 0; - for (uout = u->out, i = u->nout; i--; uout++) uout->nsent = 0; - for (uin = u->in, i = u->nin; i--; uin++) uin->ngot = 0, uin->signal = 0; - } - /* Do the sort */ - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - /* check that we have no connected signal inlets */ - if (u->done) continue; - for (uin = u->in, i = u->nin; i--; uin++) - if (uin->nconnect) goto next; - ugen_doit(dc, u); - next: ; - } - /* check for a DSP loop, which is evidenced here by the presence of ugens not yet scheduled. */ - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) if (!u->done) { - t_signal **sigp; - pd_error(u->obj, "DSP loop detected (some tilde objects not scheduled)"); - /* this might imply that we have unfilled "borrowed" outputs which we'd better fill in now. */ - for (i = 0, sigp = dc->iosigs + dc->ninlets; i < dc->noutlets; i++, sigp++) { - if ((*sigp)->isborrowed && !(*sigp)->borrowedfrom) { - t_signal *s3 = signal_new(parent_vecsize, parent_srate); - signal_setborrowed(*sigp, s3); - (*sigp)->refcount++; - dsp_add_zero(s3->v, s3->n); - if (ugen_loud) post("oops, belatedly set %lx->%lx", long(*sigp), long((*sigp)->borrowedfrom)); - } - } - break; /* don't need to keep looking. */ - } - /* add block DSP epilog */ - if (blk && (reblock || switched)) dsp_add(block_epilog, 1, blk); - int chainblockend = dsp_chainsize; /* and after block epilog code */ - /* add epilogs for outlets. */ - for (t_ugenbox *u = dc->ugenlist; u; u = u->next) { - t_pd *zz = u->obj; - if (pd_class(zz) == voutlet_class) { - t_signal **iosigs = dc->iosigs; - if (iosigs) iosigs += dc->ninlets; - voutlet_dspepilog((t_voutlet *)zz, iosigs, vecsize, calcsize, dsp_phase, period, frequency, - downsample, upsample, reblock, switched); - } - } - int chainafterall = dsp_chainsize; /* and after signal outlet epilog */ - if (blk) { - blk->blocklength = chainblockend - chainblockbegin; - blk->epiloglength = chainafterall - chainblockend; - blk->reblock = reblock; - } - if (ugen_loud) { - t_int *ip; - if (!dc->parentcontext) for (i=dsp_chainsize, ip=dsp_chain; i--; ip++) post("chain %lx", *ip); - post("... ugen_done_graph done."); - } - /* now delete everything. */ - while (dc->ugenlist) { - for (uout = dc->ugenlist->out, n = dc->ugenlist->nout; n--; uout++) { - t_sigoutconnect *oc = uout->connections, *oc2; - while (oc) { - oc2 = oc->next; - free(oc); - oc = oc2; - } - } - free(dc->ugenlist->out); - free(dc->ugenlist->in); - t_ugenbox *u = dc->ugenlist; - dc->ugenlist = u->next; - free(u); - } - if (ugen_currentcontext == dc) ugen_currentcontext = dc->parentcontext; else bug("ugen_currentcontext"); - free(dc); -} - -t_signal *ugen_getiosig(int index, int inout) { - if (!ugen_currentcontext) bug("ugen_getiosig"); - if (ugen_currentcontext->toplevel) return 0; - if (inout) index += ugen_currentcontext->ninlets; - return ugen_currentcontext->iosigs[index]; -} - -/* resampling code originally by Johannes Zmlnig in 2001 */ -/* also "block-resampling" added by Johannes in 2004.09 */ -/* --------------------- up/down-sampling --------------------- */ -/* LATER: add some downsampling-filters for HOLD and LINEAR */ - -/* up: upsampling factor */ -/* down: downsampling factor */ -/* parent: original vectorsize */ -t_int *downsampling_perform_0(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float *,out, int,down, int,parent); - int n=parent/down; - while(n--) {*out++=*in; in+=down;} - return w+5; -} -/* the downsampled vector is exactly the first part of the parent vector; the rest of the parent is just skipped - * cool for FFT-data, where you only want to process the significant (1st) part of the vector */ -t_int *downsampling_perform_block(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float *,out, int,down, int,parent); - int n=parent/down; - while(n--) *out++=*in++; - return w+5; -} -t_int *upsampling_perform_0(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float *,out, int,up, int,parent); - int n=parent*up; - t_float *dummy = out; - while(n--) *out++=0; - n = parent; - out = dummy; - while(n--) {*out=*in++; out+=up;} - return w+5; -} -t_int *upsampling_perform_hold(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float *,out, int,up, int,parent); - int i=up; - t_float *dum_out = out; - t_float *dum_in = in; - while (i--) { - int n = parent; - out = dum_out+i; - in = dum_in; - while(n--) {*out=*in++; out+=up;} - } - return w+5; -} -t_int *upsampling_perform_linear(t_int *w) { - PERFORM5ARGS(t_resample *,x, t_float *,in, t_float *,out, int,up, int,parent); - const int length = parent*up; - t_float a=*x->buffer, b=*in; - const t_float up_inv = (t_float)1.0/up; - t_float findex = 0.f; - for (int n=0; n<length; n++) { - const int index = int(findex+=up_inv); - t_float frac=findex-index; - if(frac==0.)frac=1.; - *out++ = frac * b + (1.-frac) * a; - t_float *fp=in+index; - b=*fp; - // do we still need the last sample of the previous pointer for interpolation ? - a=(index)?*(fp-1):a; - } - *x->buffer = a; - return w+6; -} -/* 1st part of the upsampled signal-vector will be the original one; 2nd part of the upsampled signal-vector is just 0 - * cool for FFT-data, where you only want to process the significant (1st) part of the vector */ -t_int *upsampling_perform_block(t_int *w) { - PERFORM4ARGS(t_float *,in, t_float *,out, int,up, int,parent); - int i=parent; - int n=parent*(up-1); - while (i--) *out++=*in++; - while (n--) *out++=0.f; - return w+5; -} - -/* ----------------------- public -------------------------------- */ -/* utils */ - -void resample_init(t_resample *x) { - x->method=0; - x->downsample=x->upsample=1; - x->n = x->coefsize = x->bufsize = 0; - x->v = x->coeffs = x->buffer = 0; -} -void resample_free(t_resample *x) { - if (x->n) free(x->v); - if (x->coefsize) free(x->coeffs); - if (x->bufsize) free(x->buffer); - x->n = x->coefsize = x->bufsize = 0; - x->v = x->coeffs = x->buffer = 0; -} -void resample_dsp(t_resample *x, t_sample* in, int insize, t_sample* out, int outsize, int method) { - if (insize == outsize) {bug("nothing to be done"); return;} - if (insize > outsize) { /* downsampling */ - if (insize % outsize) {error("bad downsampling factor"); return;} - switch (method) { - case RESAMPLE_BLOCK: dsp_add(downsampling_perform_block, 4, in, out, insize/outsize, insize); break; - default: dsp_add(downsampling_perform_0, 4, in, out, insize/outsize, insize); - } - } else { /* upsampling */ - if (outsize % insize) {error("bad upsampling factor"); return;} - switch (method) { - case RESAMPLE_HOLD: dsp_add(upsampling_perform_hold, 4, in, out, outsize/insize, insize); break; - case RESAMPLE_LINEAR: - if (x->bufsize != 1) { - free(x->buffer); - x->bufsize = 1; - x->buffer = (t_float *)t_getbytes(x->bufsize*sizeof(*x->buffer)); - } - dsp_add(upsampling_perform_linear, 5, x, in, out, outsize/insize, insize); - break; - case RESAMPLE_BLOCK: dsp_add(upsampling_perform_block, 4, in, out, outsize/insize, insize); break; - default: dsp_add(upsampling_perform_0, 4, in, out, outsize/insize, insize); - } - } -} -void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method) { - if (insize==outsize) { free(x->v); x->n = 0; x->v = in; return;} - if (x->n != outsize) { free(x->v); x->v = (t_float *)t_getbytes(outsize * sizeof(*x->v)); x->n = outsize;} - resample_dsp(x, in, insize, x->v, x->n, method); -} -void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method) { - if (insize==outsize) {if (x->n) free(x->v); x->n = 0; x->v = out; return;} - if (x->n != insize) { free(x->v); x->v = (t_float *)t_getbytes(insize * sizeof(*x->v)); x->n = insize;} - resample_dsp(x, x->v, x->n, out, outsize, method); -} - -/* ------------------------ samplerate~ -------------------------- */ - -static t_class *samplerate_tilde_class; -struct t_samplerate : t_object { - t_canvas *canvas; -}; -extern "C" void *canvas_getblock(t_class *blockclass, t_canvas **canvasp); -static void samplerate_tilde_bang(t_samplerate *x) { - float srate = sys_getsr(); - t_canvas *canvas = x->canvas; - while (canvas) { - t_block *b = (t_block *)canvas_getblock(block_class, &canvas); - if (b) srate *= float(b->upsample) / float(b->downsample); - } - x->ob_outlet->send(srate); -} -static void *samplerate_tilde_new(t_symbol *s) { - t_samplerate *x = (t_samplerate *)pd_new(samplerate_tilde_class); - outlet_new(x,&s_float); - x->canvas = canvas_getcurrent(); - return x; -} -static void samplerate_tilde_setup() { - samplerate_tilde_class = class_new2("samplerate~",samplerate_tilde_new,0,sizeof(t_samplerate),0,""); - class_addbang(samplerate_tilde_class, samplerate_tilde_bang); -} - -/* -------------------- setup routine -------------------------- */ - -void d_ugen_setup () { - block_tilde_setup(); - samplerate_tilde_setup(); -} diff --git a/desiredata/src/defaults.ddrc b/desiredata/src/defaults.ddrc deleted file mode 100644 index 919912da..00000000 --- a/desiredata/src/defaults.ddrc +++ /dev/null @@ -1,191 +0,0 @@ -look { - TextBox { - bgedit #ffffff - } - View { - language auto - language2 francais - language_dual 0 - } - Client { - console 666 - } - Box { - extrapix 1 - } - Canvas { - pointer_sense 5 - bgedit #dddddd - bgrun #ffffff - grid #ffffff - buttonbar 1 - compbg #ffffff - compfg #000000 - compselectbg #000000 - compselectfg #ffffff - crosshair #ff14ff - hairsnap 1 - hairstate 1 - gridstate 1 - grid_size 20 - snap_grid 1 - showcomp 10 - statusbar 1 - menubar 1 - scrollbar 0 - } - Comment { - bg #cccccc - fg #000000 - frame1 #ffffff - frame2 #888888 - frame3 #cccccc - } - FutureWire { - dash #ee0012 - } - SelRect { - rect #ff12ff - } - TextBox { - bgedit {#ffffff} - fg {#000000} - } - View { - bg #ffffff - fg #000000 - font {Courier -12} - frame1 #99cccc - frame2 #668888 - frame3 #000000 - selectframe #0080ff - tooltip 1 - } - Box { - iowidth 7 - minobjwidth 21 - inletfg #000000 - outletfg #000000 - iopos -1 - } - Wire { - dspfg #890098 - fg #888888 - fg2 #ee0000 - thick 1 - wirearrow 1 - } - KeyboardDialogue { - font {Courier -10} - } - Console { - font {Courier -10} - } -} -key { - Canvas { - Array {} - bng Alt+b - cnv Alt+c - Comment Ctrl+5 - Graph {} - hradio Alt+i - hsl Alt+h - Message Ctrl+2 - Number Ctrl+3 - nbx Alt+n - Object Ctrl+1 - Pdwindow {} - Symbol Ctrl+4 - tgl Alt+t - vu Alt+u - vradio Alt+d - vsl Alt+v - about {} - audio_off Ctrl+period - audio_on Ctrl+slash - class_browser {} - close Ctrl+w - copy Ctrl+c - crosshair {} - cut Ctrl+x - decr_scale Ctrl+UNDERSCORE - decr_zoom Ctrl+minus - dropper Alt+y - duplicate Ctrl+d - editmodeswitch Ctrl+e - visual_diff Ctrl+E - find Ctrl+f - find_again Ctrl+g - find_last_error {} - incr_scale Ctrl+PLUS - incr_zoom Ctrl+equal - key_nav_down Ctrl+down - key_nav_down_shift Ctrl+DOWN - key_nav_ioselect Ctrl+tab - key_nav_left Ctrl+left - key_nav_left_shift Ctrl+LEFT - key_nav_right Ctrl+right - key_nav_right_shift Ctrl+RIGHT - key_nav_up Ctrl+up - key_nav_up_shift Ctrl+UP - latency_meter {} - load_meter {} - new_file Ctrl+n - open_file Ctrl+o - parentwindow {} - paste Ctrl+v - paths {} - popup_help {} - popup_open {} - popup_properties {} - print Ctrl+p - quit Ctrl+q - redo Ctrl+Z - redraw {} - reload Ctrl+r - save Ctrl+s - save_as Ctrl+S - select_all Ctrl+a - text_editor Ctrl+t - tidy_up {} - undo Ctrl+z - insert_object Ctrl+i - chain_object Ctrl+6 - clear_wires Ctrl+k - auto_wire Ctrl+j - subpatcherize Alt+s - clear_selection Ctrl+A - auto_test Ctrl+grave - runcommand Alt+x - keyprefix Ctrl+QUESTION - macro_toggle Alt+m - macro_play Ctrl+m - macro_copy Ctrl+M - id_toggle Ctrl+semicolon - } - Client { - Canvas Alt+c - about {} - audio_off Ctrl+period - audio_on Ctrl+slash - audio_settings {} - class_browser {} - client_class_tree Ctrl+grave - client_prefs Ctrl+l - find Ctrl+f - find_again Ctrl+g - find_last_error {} - latency_meter {} - load_meter {} - midi_settings {} - new_file Ctrl+n - open_file Ctrl+o - paths {} - server_prefs Ctrl+p - quit Ctrl+q - send_message Ctrl+m - test_audio_and_midi {} - text_editor Ctrl+t - } -} diff --git a/desiredata/src/desire b/desiredata/src/desire deleted file mode 100755 index 5bd14237..00000000 --- a/desiredata/src/desire +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -wish $(cd $(dirname $0) && pwd)/desire.tk "$@" - diff --git a/desiredata/src/desire.c b/desiredata/src/desire.c deleted file mode 100644 index 18c04141..00000000 --- a/desiredata/src/desire.c +++ /dev/null @@ -1,7139 +0,0 @@ -/* $Id: desire.c,v 1.1.2.217.2.235 2007-08-21 19:50:25 matju Exp $ - - This file is part of DesireData. - Copyright (c) 2004-2007 by Mathieu Bouchard. - Portions Copyright (c) 1997-2005 Miller Puckette, Günter Geiger, Krzysztof Czaja, - Johannes Zmoelnig, Thomas Musil, Joseph Sarlo, etc. - The remains of IEMGUI Copyright (c) 2000-2001 Thomas Musil (IEM KUG Graz Austria) - For information on usage and redistribution, and for a DISCLAIMER OF ALL - WARRANTIES, see the file, "LICENSE.txt," in this distribution. -*/ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include <ctype.h> -#include <math.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "m_simd.h" -#include <errno.h> -#include <sys/time.h> -#include <sstream> -#include <vector> -#include <map> -#include <algorithm> - -#ifdef MSW -#include <io.h> -#define snprintf _snprintf -#else -#include <unistd.h> -#endif - -/* -#define sys_vgui(args...) do { \ - fprintf(stderr,"\e[0;1;31m"); \ - L fprintf(stderr,args); \ - fprintf(stderr,"\e[0m"); \ - sys_vgui(args); } while(0) -*/ - -#define foreach(ITER,COLL) for(typeof(COLL.begin()) ITER = COLL.begin(); ITER != (COLL).end(); ITER++) - -#define boxes_each(CHILD,BOXES) for(t_gobj *CHILD= (BOXES)->first(); CHILD; CHILD=CHILD->next()) -#define canvas_each(CHILD,CANVAS) for(t_gobj *CHILD=(CANVAS)->boxes->first(); CHILD; CHILD=CHILD->next()) -#define canvas_wires_each(WIRE,TRAV,CANVAS) \ - for (t_outconnect *WIRE=(t_outconnect *)666; WIRE==(t_outconnect *)666; ) \ - for (t_linetraverser TRAV(CANVAS); (WIRE=linetraverser_next(&TRAV)); ) - -#undef SET -#define SET(attr,value) do {gobj_changed(x,#attr); x->attr = (value);} while(0) - -#define a_float a_w.w_float -#define a_symbol a_w.w_symbol - -#define CLAMP(_var,_min,_max) do {if (_var<_min) _var=_min; else if (_var>_max) _var=_max;} while(0) -#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) -#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) - -template <class T> T *realloc2(T *p, size_t n) {return (T *)realloc(p,n*sizeof(T));} - -int imin(int a, int b) {return a<b?a:b;} -int imax(int a, int b) {return a>b?a:b;} -t_symbol *s_empty, *s_pd, *s_Pd; - -std::ostream &operator << (std::ostream &str, t_pd *self) { - t_binbuf *b; - if (self->_class->patchable && (b = ((t_text *)self)->binbuf)) { - char *buf; int bufn; - binbuf_gettext(b,&buf,&bufn); - str << "[" << buf << "]"; - free(buf); - } else str << "<" << self->_class->name->name << ":" << std::hex << (long)self << ">"; - return str; -} - -//-------------------------------------------------------------------------- - -t_class *boxes_class; - -struct t_boxes : t_gobj { - typedef std::map<int,t_gobj *> M; - typedef std::pair<int,t_gobj *> KV; -//private: - std::map<int,t_gobj *> map; -public: - void invariant () {size();} - t_boxes() {} - size_t size() { - size_t n=0; - boxes_each(g,this) n++; - if (map.size()!=n) post("map size=%d list size=%d",map.size(),n); - return n; - } - t_gobj *first() {return map.begin() != map.end() ? map.begin()->second : 0;} - t_gobj *last() {M::iterator iter = map.end(); iter--; return iter->second;} - t_gobj *next(t_gobj *x) { - M::iterator iter = map.begin(); - while (iter->second != x) iter++; - iter++; - return iter == map.end() ? 0 : iter->second; - } - t_gobj *get(int i) {return map.find(i)==map.end() ? 0 : map[i];} - void add(t_gobj *x) {map.insert(KV(x->dix->index,x)); invariant();} - void remove(int i) {map.erase(i); invariant();} - void remove_by_value(t_gobj *x) {map.erase(x->dix->index); invariant();} -}; - -t_boxes *boxes_new() { - t_boxes *self = (t_boxes *)pd_new(boxes_class); - new(self) t_boxes; - return self; -} - -void boxes_notice(t_boxes *self, t_gobj *origin, int argc, t_atom *argv) { - gobj_changed3(self,origin,argc,argv); -} - -void boxes_free(t_boxes *self) {self->~t_boxes();} - -t_gobj *_gobj::next() {return dix->canvas->boxes->next(this);} - -//-------------------------------------------------------------------------- - -t_class *gop_filtre_class; - -struct t_gop_filtre : t_gobj { - t_canvas *canvas; -}; - -// test for half-open interval membership -bool inside (int x, int x0, int x1) {return x0<=x && x<x1;} - -/* this method is always called when a canvas is in gop mode so we don't check for this */ -/* it doesn't filtre out all that needs to be filtred out, but does not filtre out anything that has to stay */ -void gop_filtre_notice(t_gop_filtre *self,t_gobj *origin, int argc, t_atom *argv) { - /* here, assume that the canvas *is* a gop; else we wouldn't be in this method. */ - t_object *o = (t_object *)origin; - t_canvas *c = self->canvas; - if (0/* check for messagebox, comment, but you can't check for objectboxes in general */) return; - if (c->goprect) { - if (!inside(o->x, c->xmargin, c->xmargin + c->pixwidth )) return; - if (!inside(o->y, c->ymargin, c->ymargin + c->pixheight)) return; - } - gobj_changed3(self,origin,argc,argv); -} - -t_gobj *gop_filtre_new(t_canvas *canvas) { - t_gop_filtre *self = (t_gop_filtre *)pd_new(gop_filtre_class); - new(self) t_gop_filtre; - self->canvas = canvas; - gobj_subscribe(canvas->boxes,self); - return self; -} - -void gop_filtre_free(t_boxes *self) {} - -//-------------------------------------------------------------------------- -// t_appendix: an extension to t_gobj made by matju so that all t_gobj's may have new fields -// without sacrificing binary compat with externals compiled for PureMSP. - -typedef t_hash<t_symbol *, t_arglist *> t_visual; - -t_appendix *appendix_new (t_gobj *master) { - //fprintf(stderr,"appendix_new %p\n",master); - t_appendix *self = (t_appendix *)malloc(sizeof(t_appendix)); - self->canvas = 0; - self->nobs = 0; - self->obs = 0; - self->visual = new t_visual(1); - self->index = 0; - self->elapsed = 0; - return self; -} - -void appendix_save (t_gobj *master, t_binbuf *b) { - t_visual *h = master->dix->visual; - //fprintf(stderr,"appendix_save %p size=%ld\n",master,hash_size(h)); - if (!h->size()) return; - t_symbol *k; - t_arglist *v; - int i=0; - binbuf_addv(b,"t","#V"); - hash_foreach(k,v,h) { - t_arglist *al = (t_arglist *)v; - binbuf_addv(b,"s",k); - binbuf_add(b,al->c,al->v); - if (size_t(i+1)==h->size()) binbuf_addv(b, ";"); else binbuf_addv(b,"t",","); - i++; - } -} - -void appendix_free (t_gobj *master) { - t_appendix *self = master->dix; - t_symbol *k; - t_arglist *v; - if (self->visual) { - hash_foreach(k,v,self->visual) free(v); - delete self->visual; - } - free(self); -} - -/* subscribing N spies takes N*N time, but it's not important for now */ -/* subscription could become just a special use of t_outlet in the future, or sometimes become implied. */ -/* perhaps use [bindelem] here? */ -void gobj_subscribe(t_gobj *self, t_gobj *observer) { - t_appendix *d = self->dix; - for (size_t i=0; i<d->nobs; i++) if (d->obs[i]) return; - d->obs=realloc2(d->obs,1+d->nobs); - d->obs[d->nobs++] = observer; - t_onsubscribe ons = self->_class->onsubscribe; - ons(self,observer); - //post("x%p has %d observers",self,(int)d->nobs); -} - -void gobj_unsubscribe (t_gobj *self, t_gobj *observer) { - t_appendix *d = self->dix; - size_t i; - for (i=0; i<d->nobs; i++) if (d->obs[i]) break; - if (i==d->nobs) return; - d->nobs--; - for (; i<d->nobs; i++) d->obs[i] = d->obs[i+1]; - // should have something like onunsubscribe too, to handle delete?... or just use onsubscribe differently. -} - -void gobj_setcanvas (t_gobj *self, t_canvas *c) { - if (self->dix->canvas == c) return; - if (self->dix->canvas) gobj_unsubscribe(self,self->dix->canvas); - self->dix->canvas = c; - if (self->dix->canvas) gobj_subscribe(self,self->dix->canvas); -} - -/* for future use */ -t_canvas *gobj_canvas (t_gobj *self) {return self->dix->canvas;} - -// if !k then suppose all of the object might have changed. -void gobj_changed (t_gobj *self, const char *k) { - int dirty = k ? (1<<class_getfieldindex(self->_class,k)) : -1; - t_atom argv[1]; - SETFLOAT(argv,(float)dirty); - gobj_changed3(self,self,1,argv); -} -//#define gobj_changed(SELF,K) do {L; gobj_changed(SELF,K);} while(0) - -// if only a float is sent, it's a bitset of at most 25 elements -// else it may mean whatever else... -void gobj_changed2 (t_gobj *self, int argc, t_atom *argv) { - gobj_changed3(self,self,argc,argv); -} - -void gobj_changed3 (t_gobj *self, t_gobj *origin, int argc, t_atom *argv) { - t_appendix *d = self->dix; - std::ostringstream s; - for (int i=0; i<argc; i++) s << " " << &argv[i]; - //fprintf(stderr,"gobj_changed3 self=%lx origin=%lx args=%s\n",(long)self,(long)origin,s.str().data()); - /* TRACE THE DIFFERENTIAL UPLOAD REQUESTS */ - //std::cerr << "gobj_changed3 self=" << self << " origin=" << origin << " args={" << s.str().data()+(!!argc) << "}\n"; - if (!d) {post("gobj_changed3: no appendix in %p",self); return;} - for (size_t i=0; i<d->nobs; i++) { - t_gobj *obs = d->obs[i]; - t_notice ice = obs->_class->notice; - if (ice) ice(obs,origin,argc,argv); - else post("null func ptr for class %s",self->_class->name->name); - } -} - -//-------------------------------------------------------------------------- -// some simple ringbuffer-style queue -// when this becomes too small, use a bigger constant or a better impl. - -#define QUEUE_SIZE 16384 -struct t_queue { - int start,len; - t_pd *o[QUEUE_SIZE]; -}; - -t_queue *queue_new () { - t_queue *self = (t_queue *)getbytes(sizeof(t_queue)); - self->start = self->len = 0; - return self; -} - -static bool debug_queue=0; - -static void pd_print (t_pd *self, const char *header) { - if (self->_class->gobj && (object_table->get(self)&1)==0) {printf("%s %p dead\n",header,self); return;} - if (self->_class->patchable) { - t_binbuf *b = ((t_text *)self)->binbuf; - if (b) { - char *buf; int bufn; - binbuf_gettext(b,&buf,&bufn); - printf("%s %p [%.*s]\n",header,self,bufn,buf); - return; - } - } - printf("%s %p (%s)\n",header,self,self->_class->name->name); -} - -void queue_put (t_queue *self, t_pd *stuff) { - if (debug_queue) pd_print(stuff,"queue_put"); - if (self->len==QUEUE_SIZE) {bug("queue full"); return;} - self->o[(self->start+self->len)%QUEUE_SIZE] = stuff; - self->len++; - if (debug_queue) post("queue_put: items in queue: %d",self->len); -} - -void *queue_get (t_queue *self) { - t_pd *stuff = self->o[self->start]; - self->start = (self->start+1)%QUEUE_SIZE; - self->len--; - if (debug_queue) {post("queue_get: items in queue: %d",self->len); pd_print(stuff,"queue_get");} - return stuff; -} - -#define queue_each(i,self) \ - for (int i=self->start; i!=(self->start+self->len)%QUEUE_SIZE; i=(i+1)%QUEUE_SIZE) - -void queue_free (t_queue *self) { - abort(); - free(self); -} - -int queue_empty (t_queue *self) {return self->len==0;} -int queue_full (t_queue *self) {return self->len==QUEUE_SIZE;} - -//-------------------------------------------------------------------------- -// reply system: - -struct t_reply : t_gobj { - short serial; - void *answer; -}; - -t_class *reply_class; - -static t_reply *reply_new (short serial, void *answer) { - t_reply *self = (t_reply *)pd_new(reply_class); - self->dix = appendix_new(self); - self->serial = serial; - self->answer = answer; - return self; -} - -static void reply_send (t_reply *self) { - sys_vgui("serial %ld x%lx\n",(long)self->serial,(long)self->answer); -} - -static void reply_free (t_reply *self) {} - -//-------------------------------------------------------------------------- -// update manager: - -struct t_dirtyentry { - long fields; - size_t start,end; - t_dirtyentry() {} -}; - -typedef t_hash <t_gobj *, t_dirtyentry *> t_dirtyset; - -struct t_manager : t_text { - t_queue *q; - t_clock *clock; - t_binbuf *b; /* reusable, for processing messages from the gui */ - t_dirtyset *dirty; -}; - -static t_class *manager_class; -t_manager *manager; - -void manager_call (void *foo) { - t_manager *self = (t_manager *)foo; - while (!queue_empty(self->q)) { - t_gobj *o = (t_gobj *)queue_get(self->q); - if (!o) continue; /* cancelled notice */ - //fprintf(stderr,"manager_call, o->_class=%s\n",o->_class->c_name->name); - if (o->_class == reply_class) { - reply_send((t_reply *)o); - pd_free(o); - } else { - if (self->dirty->exists(o)) { - pd_upload(o); - self->dirty->del(o); - } - } - } - clock_delay(self->clock,25); -} - -void manager_notice (t_gobj *self_, t_gobj *origin, int argc, t_atom *argv) { - t_manager *self = (t_manager *)self_; - if (!self->dirty->exists(origin)) { - //std::cerr << "manager_notice:"; - //for (int i=0; i<argc; i++) std::cerr << " " << &argv[i]; - //std::cerr << "\n"; - queue_put(self->q,origin); - self->dirty->set(origin,0); - } -} - -t_manager *manager_new (t_symbol *s, int argc, t_atom *argv) { - t_manager *self = (t_manager *)pd_new(manager_class); - self->q = queue_new(); - self->clock = clock_new(self,(t_method)manager_call); - self->b = binbuf_new(); - clock_delay(self->clock,0); - self->dirty = new t_dirtyset(127); - return self; -} - -void manager_free (t_manager *self) { - clock_free(self->clock); - queue_free(self->q); - binbuf_free(self->b); - pd_free(self); -} - -extern "C" void manager_anything (t_manager *self, t_symbol *s, int argc, t_atom *argv) { - binbuf_clear(self->b); - binbuf_addv(self->b,"s",s); - binbuf_add(self->b,argc,argv); - binbuf_eval(self->b,0,0,0); -} - -//-------------------------------------------------------------------------- -/* -IOhannes changed the canvas_restore, so that it might accept $args as well -(like "pd $0_test") so you can make multiple & distinguishable templates. -*/ - -#define CANVAS_DEFCANVASWIDTH 450 -#define CANVAS_DEFCANVASHEIGHT 300 - -#ifdef __APPLE__ -#define CANVAS_DEFCANVASYLOC 22 -#else -#define CANVAS_DEFCANVASYLOC 0 -#endif - -extern short next_object; -extern t_pd *newest; -t_class *canvas_class; -int canvas_dspstate; /* whether DSP is on or off */ -t_canvas *canvas_whichfind; /* last canvas we did a find in */ -std::map<t_canvas *,int> windowed_canvases; /* where int is dummy */ -static void canvas_setbounds(t_canvas *x, t_floatarg x1, t_floatarg y1, t_floatarg x2, t_floatarg y2); -static t_symbol *canvas_newfilename = &s_; -static t_symbol *canvas_newdirectory = &s_; -static int canvas_newargc; -static t_atom *canvas_newargv; - -/* add a canvas the list of "root" canvases (toplevels without parents.) */ -/* should those two functions still exist? */ -static void canvas_addtolist(t_canvas *x) { - windowed_canvases.insert(std::pair<t_canvas *,int>(x,42)); - if (x->havewindow) gobj_subscribe(x,manager); -} -static void canvas_takeofflist(t_canvas *x) {windowed_canvases.erase(x);} - -/* if there's an old one lying around free it here. - This happens if an abstraction is loaded but never gets as far as calling canvas_new(). */ -void canvas_setargs(int argc, t_atom *argv) { - if (canvas_newargv) free(canvas_newargv); - canvas_newargc = argc; - canvas_newargv = (t_atom *)copybytes(argv, argc * sizeof(t_atom)); -} - -void glob_setfilename(void *self, t_symbol *filesym, t_symbol *dirsym) { - canvas_newfilename = filesym; - canvas_newdirectory = dirsym; -} - -t_canvas *canvas_getcurrent () {return ((t_canvas *)pd_findbyclass(&s__X, canvas_class));} - -t_canvasenvironment *canvas_getenv(t_canvas *x) { - while (!x->env) x = x->dix->canvas; - return x->env; -} - -int canvas_getdollarzero () { - t_canvas *x = canvas_getcurrent(); - t_canvasenvironment *env = x ? canvas_getenv(x) : 0; - return env ? env->dollarzero : 0; -} - -t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s) { - if (strchr(s->name,'$')) { - t_canvasenvironment *env = canvas_getenv(x); - pd_pushsym(x); - t_symbol *ret = binbuf_realizedollsym(s, env->argc, env->argv, 1); - pd_popsym(x); - return ret; - } - return s; -} - -t_symbol *canvas_getcurrentdir () {return canvas_getenv(canvas_getcurrent())->dir;} -t_symbol *canvas_getdir(t_canvas *x) {return canvas_getenv( x)->dir;} - -char *canvas_makefilename(t_canvas *x, char *file, char *result, int resultsize) { - char *dir = canvas_getenv(x)->dir->name; - if (file[0] == '/' || (file[0] && file[1] == ':') || !*dir) { - if (!result) return strdup(file); - strncpy(result, file, resultsize); - result[resultsize-1] = 0; - } else { - if (result) {snprintf(result,resultsize,"%s/%s",dir,file); result[resultsize-1] = 0;} - else asprintf(&result, "%s/%s",dir,file); - } - return result; -} - -static void canvas_rename(t_canvas *x, t_symbol *s, t_symbol *dir) { - t_symbol *bs = canvas_makebindsym(s); - if (x->name!=s_Pd) pd_unbind(x, bs); - SET(name,s); - if (x->name!=s_Pd) pd_bind(x, bs); - if (dir && dir != &s_) { - canvas_getenv(x)->dir = dir; - gobj_changed(x,"dir"); - } -} - -/* --------------- traversing the set of lines in a canvas ----------- */ - -t_linetraverser::t_linetraverser(t_canvas *canvas) {linetraverser_start(this,canvas);} - -void linetraverser_start(t_linetraverser *t, t_canvas *x) { - t->from = 0; - t->canvas = x; - t->next = 0; - t->nextoutno = t->nout = 0; -} - -t_outconnect *linetraverser_next(t_linetraverser *t) { - t_outconnect *rval = t->next; - while (!rval) { - int outno = t->nextoutno; - while (outno == t->nout) { - t_object *ob = 0; - t_gobj *y = t->from ? t->from->next() : t->canvas->boxes->first(); - for (; y; y = y->next()) if ((ob = pd_checkobject(y))) break; - if (!ob) return 0; - t->from = ob; - t->nout = obj_noutlets(ob); - outno = 0; - } - t->nextoutno = outno + 1; - rval = obj_starttraverseoutlet(t->from, &t->outletp, outno); - t->outlet = outno; - } - t->next = obj_nexttraverseoutlet(rval, &t->to, &t->inletp, &t->inlet); - t->nin = obj_ninlets(t->to); - if (!t->nin) bug("linetraverser_next"); - return rval; -} - -/* -------------------- the canvas object -------------------------- */ -static int hack = 1; - -static t_canvas *canvas_new2() { - t_canvas *x = (t_canvas *)pd_new(canvas_class); - /* zero out every field except "pd" and "dix" */ - memset(((char *)x) + sizeof(t_gobj), 0, sizeof(*x) - sizeof(t_gobj)); - x->xlabel = (t_symbol **)getbytes(0); - x->ylabel = (t_symbol **)getbytes(0); - // only manage this canvas if it's not one of the 3 invisible builtin canvases - x->boxes = boxes_new(); - return x; -} - -static void canvas_vis(t_canvas *x, t_floatarg f); - -/* make a new canvas. It will either be a "root" canvas or else it appears as - a "text" object in another window (canvas_getcurrent() tells us which.) */ -static t_canvas *canvas_new(void *self, t_symbol *sel, int argc, t_atom *argv) { - t_canvas *x = canvas_new2(); - t_canvas *owner = canvas_getcurrent(); - t_symbol *s = &s_; - int width = CANVAS_DEFCANVASWIDTH, xloc = 0; - int height = CANVAS_DEFCANVASHEIGHT, yloc = CANVAS_DEFCANVASYLOC; - int vis=0, font = owner?owner->font:10; - if (!owner) canvas_addtolist(x); - /* toplevel vs subwindow */ - if (argc==5) pd_scanargs(argc,argv,"iiiii", &xloc,&yloc,&width,&height,&font); - else if (argc==6) pd_scanargs(argc,argv,"iiiisi",&xloc,&yloc,&width,&height,&s,&vis); - /* (otherwise assume we're being created from the menu.) */ - if (canvas_newdirectory->name[0]) { - static long dollarzero = 1000; - t_canvasenvironment *env = x->env = (t_canvasenvironment *)getbytes(sizeof(*x->env)); - if (!canvas_newargv) canvas_newargv = (t_atom *)getbytes(0); - env->dir = canvas_newdirectory; - env->argc = canvas_newargc; - env->argv = canvas_newargv; - env->dollarzero = dollarzero++; - env->path = 0; - canvas_newdirectory = &s_; - canvas_newargc = 0; - canvas_newargv = 0; - } else x->env = 0; - - if (yloc < CANVAS_DEFCANVASYLOC) yloc = CANVAS_DEFCANVASYLOC; - if (xloc < 0) xloc = 0; - x->x1 = 0; x->y1 = 0; - x->x2 = 1; x->y2 = 1; - canvas_setbounds(x, xloc, yloc, xloc + width, yloc + height); - gobj_setcanvas(x,owner); - x->name = *s->name ? s : canvas_newfilename ? canvas_newfilename : s_Pd; - if (x->name != s_Pd) pd_bind(x, canvas_makebindsym(x->name)); - x->goprect = 0; /* no GOP rectangle unless it's turned on later */ - /* cancel "vis" flag if we're a subpatch of an abstraction inside another patch. - A separate mechanism prevents the toplevel abstraction from showing up. */ - if (vis && gensym("#X")->thing && gensym("#X")->thing->_class == canvas_class) { - t_canvas *z = (t_canvas *)(gensym("#X")->thing); - while (z && !z->env) z = z->dix->canvas; - if (z && canvas_isabstraction(z) && z->dix->canvas) vis = 0; - } - if (vis) canvas_vis(x,vis); - x->font = 10 /*sys_nearestfontsize(font)*/; - pd_pushsym(x); - newest = x; - return x; -} - -void canvas_setgraph(t_canvas *x, int flag, int nogoprect); - -static void canvas_coords(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - pd_scanargs(argc,argv,"ffffii*",&x->x1,&x->y1,&x->x2,&x->y2,&x->pixwidth,&x->pixheight); - if (argc <= 7) canvas_setgraph(x, atom_getintarg(6, argc, argv), 1); - else { - canvas_setgraph(x, atom_getintarg(6, argc, argv), 0); - SET(xmargin, atom_getintarg(7, argc, argv)); - SET(ymargin, atom_getintarg(8, argc, argv)); - } - gobj_changed(x,0); -} - -//template <class T> void swap(T &a, T &b) {T c=a; a=b; b=c;} -#define swap std::swap - -#define CANVAS_DEFGRAPHWIDTH 200 -#define CANVAS_DEFGRAPHHEIGHT 140 -/* make a new canvas and add it to this canvas. It will appear as a "graph", not a text object. */ -static t_canvas *canvas_addcanvas(t_canvas *g, t_symbol *sym, -float x1, float y1, float x2, float y2, -float px1, float py1, float px2, float py2) { - static int gcount = 0; - int menu = 0; - t_canvas *x = canvas_new2(); - if (!*sym->name) { - sym = symprintf("graph%d", ++gcount); - menu = 1; - } else if (!strncmp(sym->name,"graph",5)) { - int zz = atoi(sym->name+5); - if (zz>gcount) gcount = zz; - } - /* in 0.34 and earlier, the pixel rectangle and the y bounds were reversed; this would behave the same, - except that the dialog window would be confusing. The "correct" way is to have "py1" be the value - that is higher on the screen. */ - if (py2 < py1) {swap(y1,y2); swap(py1,py2);} - if (x1 == x2 || y1 == y2) {x1=0; x2=100; y1=1; y2=-1;} - if (px1 >= px2 || py1 >= py2) { - px1=100; px2=px1+CANVAS_DEFGRAPHWIDTH; - py1=20; py2=py1+CANVAS_DEFGRAPHHEIGHT; - } - x->name = sym; - SET(x1,x1); SET(y1,y1); SET(x,short(px1)); SET(pixwidth ,int(px2-px1)); - SET(x2,x2); SET(y2,y2); SET(y,short(py1)); SET(pixheight,int(py2-py1)); - x->font = (canvas_getcurrent() ? canvas_getcurrent()->font : 42 /*sys_defaultfont*/); - x->screenx1 = x->screeny1 = 0; x->screenx2 = 450; x->screeny2 = 300; - if (x->name != s_Pd) pd_bind(x, canvas_makebindsym(x->name)); - gobj_setcanvas(x,g); - x->gop = 1; - x->goprect = 0; - x->binbuf = binbuf_new(); - binbuf_addv(x->binbuf,"t","graph"); - if (!menu) pd_pushsym(x); - canvas_add(g,x); - return x; -} - -static void canvas_canvas(t_canvas *g, t_symbol *s, int argc, t_atom *argv) { - t_symbol *sym; - float x1,y1,x2,y2,px1,py1,px2,py2; - pd_scanargs(argc,argv,"sffffffff",&sym,&x1,&y1,&x2,&y2,&px1,&py1,&px2,&py2); - canvas_addcanvas(g, sym, x1, y1, x2, y2, px1, py1, px2, py2); -} - -static void canvas_redraw(t_canvas *x) { - gobj_changed(x,0); - canvas_each(y,x) if (y->_class==canvas_class) canvas_redraw((t_canvas *)y); else gobj_changed(y,0); -} - -/* This is sent from the GUI to inform a toplevel that its window has been moved or resized. */ -static void canvas_setbounds(t_canvas *x, t_floatarg x1, t_floatarg y1, t_floatarg x2, t_floatarg y2) { - int heightwas = int(y2-y1); - if (x->screenx1 == x1 && x->screeny1 == y1 && - x->screenx2 == x2 && x->screeny2 == y2) return; - x->screenx1 = int(x1); x->screeny1 = int(y1); - x->screenx2 = int(x2); x->screeny2 = int(y2); - if (!x->gop && x->y2 < x->y1) { - /* if it's flipped so that y grows upward, fix so that zero is bottom edge and redraw. - This is only appropriate if we're a regular "text" object on the parent. */ - float diff = x->y1 - x->y2; - x->y1 = heightwas * diff; - x->y2 = x->y1 - diff; - canvas_redraw(x); - } -} - -t_symbol *canvas_makebindsym(t_symbol *s) {return symprintf("pd-%s",s->name);} - -static void canvas_vis(t_canvas *x, t_floatarg f) { - int hadwindow = x->havewindow; - SET(havewindow,!!f); - if (hadwindow && !x->havewindow) gobj_unsubscribe(x,manager); - if (!hadwindow && x->havewindow) gobj_subscribe(x,manager); -} - -/* we call this on a non-toplevel canvas to "open" it into its own window. */ -static void canvas_menu_open(t_canvas *x) { - if (canvas_isvisible(x) && !canvas_istoplevel(x)) { - if (!x->dix->canvas) {error("this works only on subpatch or abstraction"); return;} - SET(havewindow,1); - } -} - -int canvas_isvisible(t_canvas *x) {return gstack_empty() && canvas_getcanvas(x)->havewindow;} - -/* we consider a graph "toplevel" if it has its own window or if it appears as a box in its parent window - so that we don't draw the actual contents there. */ -int canvas_istoplevel(t_canvas *x) {return x->havewindow || !x->gop;} - -static void canvas_free(t_canvas *x) { - int dspstate = canvas_suspend_dsp(); - if (canvas_whichfind == x) canvas_whichfind = 0; - t_gobj *y; - while ((y = x->boxes->first())) canvas_delete(x, y); - canvas_vis(x, 0); - if (x->name != s_Pd) pd_unbind(x,canvas_makebindsym(x->name)); - if (x->env) { - free(x->env->argv); - free(x->env); - } - canvas_resume_dsp(dspstate); - free(x->xlabel); - free(x->ylabel); - if (!x->dix->canvas) canvas_takeofflist(x); -} - -/* kill all lines for one inlet or outlet */ -void canvas_deletelinesforio(t_canvas *x, t_text *text, t_inlet *inp, t_outlet *outp) { - canvas_wires_each(oc,t,x) - if ((t.from == text && t.outletp == outp) || - (t.to == text && t.inletp == inp)) - obj_disconnect(t.from, t.outlet, t.to, t.inlet); -} -void canvas_deletelinesfor(t_canvas *x, t_text *text) { - canvas_wires_each(oc,t,x) - if (t.from == text || t.to == text) - obj_disconnect(t.from, t.outlet, t.to, t.inlet); -} - -static void canvas_resortinlets(t_canvas *x); -static void canvas_resortoutlets(t_canvas *x); -static void canvas_push(t_canvas *x, t_floatarg f) {pd_pushsym(x);} -/* assuming that this only ever gets called on toplevel canvases (?) */ -static void canvas_pop(t_canvas *x, t_floatarg fvis) { - pd_popsym(x); canvas_resortinlets(x); canvas_resortoutlets(x); - if (fvis) canvas_vis(x, 1); -} -extern "C" void canvas_popabstraction(t_canvas *x) { - pd_set_newest(x); - pd_popsym(x); canvas_resortinlets(x); canvas_resortoutlets(x); -} - -void canvas_objfor(t_canvas *gl, t_text *x, int argc, t_atom *argv); - -const char *atomtype_name(t_atomtype i) { -#define T(TYPE) case TYPE: return #TYPE; - switch (i) { - T(A_NULL) - T(A_FLOAT) T(A_SYMBOL) T(A_POINTER) - T(A_SEMI) T(A_COMMA) - T(A_DEFFLOAT) T(A_DEFSYM) - T(A_DOLLAR) T(A_DOLLSYM) - T(A_GIMME) - T(A_CANT) -/* regular pd stops here, before #12 */ - T(A_ATOM) - T(A_LIST) - T(A_GRID) - T(A_GRIDOUT) - default: return "A_UNKNOWN"; - } -} - -void canvas_restore(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - if (argc > 3) { - t_atom *ap=argv+3; - if (ap->a_type == A_SYMBOL) { - t_canvasenvironment *e = canvas_getenv(canvas_getcurrent()); - for (int i=0; i<e->argc; i++) post("restore: arg %d has type %s",i,atomtype_name(e->argv[i].a_type)); - canvas_rename(x, binbuf_realizedollsym(ap->a_symbol,e->argc,e->argv,1), 0); - } - } - canvas_pop(x,0); /* 0 means "don't touch" here. */ - t_pd *z = gensym("#X")->thing; - if (!z) {error("out of context"); return;} - if (z->_class != canvas_class) {error("wasn't a canvas"); return;} - gobj_setcanvas(x,(t_canvas *)z); - canvas_objfor((t_canvas *)z, x, argc, argv); - newest = x; -} - -static void canvas_loadbang(t_canvas *x); - -static void canvas_loadbangabstractions(t_canvas *x) { - canvas_each(y,x) if (y->_class == canvas_class) { - t_canvas *z = (t_canvas *)y; - if (canvas_isabstraction(z)) canvas_loadbang(z); else canvas_loadbangabstractions(z); - } -} - -void canvas_loadbangsubpatches(t_canvas *x) { - t_symbol *s = gensym("loadbang"); - canvas_each(y,x) if (y->_class == canvas_class) { - t_canvas *z = (t_canvas *)y; - if (!canvas_isabstraction(z)) canvas_loadbangsubpatches(z); - } - canvas_each(y,x) if ((y->_class != canvas_class) && zgetfn(y,s)) pd_vmess(y,s,""); -} - -static void canvas_loadbang(t_canvas *x) { - canvas_loadbangabstractions(x); - canvas_loadbangsubpatches(x); -} - -/* When you ask a canvas its size the result is 2 pixels more than what you gave it to open it; - perhaps there's a 1-pixel border all around it or something. Anyway, we just add the 2 pixels back here; - seems we have to do this for linux but not MSW; not sure about MacOS. */ -#ifdef MSW -#define HORIZBORDER 0 -#define VERTBORDER 0 -#else -#define HORIZBORDER 2 -#define VERTBORDER 2 -#endif - -static void canvas_relocate(t_canvas *x, t_symbol *canvasgeom, t_symbol *topgeom) { - int cxpix, cypix, cw, ch, txpix, typix, tw, th; - if (sscanf(canvasgeom->name, "%dx%d+%d+%d", &cw, &ch, &cxpix, &cypix) < 4 || - sscanf( topgeom->name, "%dx%d+%d+%d", &tw, &th, &txpix, &typix) < 4) - bug("canvas_relocate"); - /* for some reason this is initially called with cw=ch=1 so we just suppress that here. */ - if (cw>5 && ch>5) canvas_setbounds(x, txpix, typix, txpix + cw - HORIZBORDER, typix + ch - VERTBORDER); -} - -void pd_set_newest (t_pd *x) {newest = x;} - -static void *subcanvas_new(t_symbol *s) { - t_atom a[6]; - t_canvas *z = canvas_getcurrent(); - if (!*s->name) s = gensym("/SUBPATCH/"); - SETFLOAT(a, 0); - SETFLOAT(a+1, CANVAS_DEFCANVASYLOC); - SETFLOAT(a+2, CANVAS_DEFCANVASWIDTH); - SETFLOAT(a+3, CANVAS_DEFCANVASHEIGHT); - SETSYMBOL(a+4, s); - SETFLOAT(a+5, 1); - t_canvas *x = canvas_new(0, 0, 6, a); - gobj_setcanvas(x,z); - canvas_pop(x, 1); - return x; -} - -static void canvas_rename_method(t_canvas *x, t_symbol *s, int ac, t_atom *av) { - if (ac && av->a_type == A_SYMBOL) canvas_rename(x, av->a_symbol, 0); - else if (ac && av->a_type == A_DOLLSYM) { - t_canvasenvironment *e = canvas_getenv(x); - pd_pushsym(x); - canvas_rename(x, binbuf_realizedollsym(av->a_symbol, e->argc, e->argv, 1), 0); - pd_popsym(x); - } else canvas_rename(x, gensym("Pd"), 0); -} - -/* ------------------ table ---------------------------*/ - -static t_garray *graph_array(t_canvas *gl, t_symbol *s, t_symbol *tmpl, t_floatarg f, t_floatarg saveit); - -static int tabcount = 0; - -static void *table_new(t_symbol *s, t_floatarg f) { - t_atom a[9]; - t_canvas *z = canvas_getcurrent(); - if (s == &s_) s = symprintf("table%d", tabcount++); - if (f <= 1) f = 100; - SETFLOAT(a, 0); - SETFLOAT(a+1, CANVAS_DEFCANVASYLOC); - SETFLOAT(a+2, 600); - SETFLOAT(a+3, 400); - SETSYMBOL(a+4, s); - SETFLOAT(a+5, 0); - t_canvas *x = canvas_new(0,0,6,a); - gobj_setcanvas(x,z); - /* create a graph for the table */ - t_canvas *gl = canvas_addcanvas(x, &s_, 0, -1, (f > 1 ? f-1 : 1), 1, 50, 350, 550, 50); - graph_array(gl, s, &s_float, f, 0); - canvas_pop(x, 0); - return x; -} - -/* return true if the "canvas" object is an abstraction (so we don't save its contents, fogr example.) */ -int canvas_isabstraction(t_canvas *x) {return x->env!=0;} - -/* return true if the "canvas" object is a "table". */ -int canvas_istable(t_canvas *x) { - t_atom *argv = x->binbuf ? binbuf_getvec( x->binbuf) : 0; - int argc = x->binbuf ? binbuf_getnatom(x->binbuf) : 0; - return argc && argv[0].a_type == A_SYMBOL && argv[0].a_symbol == gensym("table"); -} - -/* return true if the "canvas" object should be treated as a text - object. This is true for abstractions but also for "table"s... */ -/* JMZ: add a flag to gop-abstractions to hide the title */ -static int canvas_showtext(t_canvas *x) { - t_atom *argv = x->binbuf? binbuf_getvec( x->binbuf) : 0; - int argc = x->binbuf? binbuf_getnatom(x->binbuf) : 0; - int isarray = argc && argv[0].a_type == A_SYMBOL && argv[0].a_symbol == gensym("graph"); - return x->hidetext ? 0 : !isarray; -} - -/* get the document containing this canvas */ -t_canvas *canvas_getrootfor(t_canvas *x) { - if (!x->dix->canvas || canvas_isabstraction(x)) return x; - return canvas_getrootfor(x->dix->canvas); -} - -/* ------------------------- DSP chain handling ------------------------- */ - -typedef struct _dspcontext t_dspcontext; - -extern void ugen_start (); -extern void ugen_stop (); -extern "C" t_dspcontext *ugen_start_graph(int toplevel, t_signal **sp, int ninlets, int noutlets); -extern "C" void ugen_add(t_dspcontext *dc, t_object *x); -extern "C" void ugen_connect(t_dspcontext *dc, t_object *from, int outlet, t_object *to, int inlet); -extern "C" void ugen_done_graph(t_dspcontext *dc); - -/* schedule one canvas for DSP. This is called below for all "root" canvases, - but is also called from the "dsp" method for sub-canvases, which are treated almost like any other tilde object. */ -static void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp) { - t_object *ob; - t_symbol *dspsym = gensym("dsp"); - t_dspcontext *dc = ugen_start_graph(toplevel, sp, obj_nsiginlets(x), obj_nsigoutlets(x)); - canvas_each(y,x) {ob = pd_checkobject(y); if (ob && zgetfn(y,dspsym)) ugen_add(dc, ob);} - canvas_wires_each(oc,t,x) if (obj_issignaloutlet(t.from, t.outlet)) ugen_connect(dc, t.from, t.outlet, t.to, t.inlet); - ugen_done_graph(dc); -} - -static void canvas_dsp(t_canvas *x, t_signal **sp) {canvas_dodsp(x, 0, sp);} - -/* this routine starts DSP for all root canvases. */ -static void canvas_start_dsp() { - if (canvas_dspstate) ugen_stop(); - else sys_gui("pdtk_pd_dsp 1\n"); - ugen_start(); - //timeval v0,v1; gettimeofday(&v0,0); - foreach(x,windowed_canvases) canvas_dodsp(x->first,1,0); - //gettimeofday(&v1,0); printf("canvas_start_dsp took %ld us\n",(v1.tv_sec-v0.tv_sec)*1000000+(v1.tv_usec-v0.tv_usec)); - canvas_dspstate = 1; -} - -/*static*/ void canvas_stop_dsp() { - if (canvas_dspstate) { - ugen_stop(); - sys_gui("pdtk_pd_dsp 0\n"); - canvas_dspstate = 0; - } -} - -/* DSP can be suspended before, and resumed after, operations which might affect the DSP chain. - For example, we suspend before loading and resume afterwards, so that DSP doesn't get resorted for every DSP object in the patch. */ -int canvas_suspend_dsp () { - int rval = canvas_dspstate; - if (rval) canvas_stop_dsp(); - return rval; -} -void canvas_resume_dsp(int oldstate) {if (oldstate) canvas_start_dsp();} -/* this is equivalent to suspending and resuming in one step. */ -void canvas_update_dsp () {if (canvas_dspstate) canvas_start_dsp();} - -extern "C" void glob_dsp(void *self, t_symbol *s, int argc, t_atom *argv) { - if (argc) { - int newstate = atom_getintarg(0, argc, argv); - if (newstate && !canvas_dspstate) { - canvas_start_dsp(); - sys_set_audio_state(1); - } else if (!newstate && canvas_dspstate) { - sys_set_audio_state(0); - canvas_stop_dsp(); - } - } else post("dsp state %d", canvas_dspstate); -} - -extern "C" void *canvas_getblock(t_class *blockclass, t_canvas **canvasp) { - t_canvas *canvas = *canvasp; - void *ret = 0; - canvas_each(g,canvas) if (g->_class == blockclass) ret = g; - *canvasp = canvas->dix->canvas; - return ret; -} - -/******************* redrawing data *********************/ - -static t_float slot_getcoord(t_slot *f, t_template *, t_word *wp, int loud); -static void slot_setcoord(t_slot *f, t_template *, t_word *wp, float pix, int loud); -static t_float slot_cvttocoord(t_slot *f, float val); -static t_template *template_new(t_symbol *sym, int argc, t_atom *argv); -static void template_free(t_template *x); -static int template_match(t_template *x1, t_template *x2); -static int template_find_field(t_template *x, t_symbol*name, int*p_onset, int*p_type, t_symbol **p_arraytype); -static t_float template_getfloat( t_template *x, t_symbol *fieldname, t_word *wp, int loud); -static void template_setfloat( t_template *x, t_symbol *fieldname, t_word *wp, t_float f, int loud); -static t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname, t_word *wp, int loud); -static void template_setsymbol(t_template *x, t_symbol *fieldname, t_word *wp, t_symbol *s, int loud); -static t_template *gtemplate_get(t_gtemplate *x); -static t_template *template_findbyname(t_symbol *s); -static t_canvas *template_findcanvas(t_template *tmpl); -static void template_notify(t_template *, t_symbol *s, int argc, t_atom *argv); - -/* find the template defined by a canvas, and redraw all elements for that */ -void canvas_redrawallfortemplatecanvas(t_canvas *x, int action) { - t_template *tmpl; - t_symbol *s1 = gensym("struct"); - canvas_each(g,x) { - t_object *ob = pd_checkobject(g); - if (!ob || /* ob->type != T_OBJECT || */ binbuf_getnatom(ob->binbuf) < 2) continue; - t_atom *argv = binbuf_getvec(ob->binbuf); - if (argv[0].a_type != A_SYMBOL || argv[1].a_type != A_SYMBOL || argv[0].a_symbol != s1) - continue; - tmpl = template_findbyname(argv[1].a_symbol); - //canvas_redrawallfortemplate(tmpl, action); - } - //canvas_redrawallfortemplate(0, action); -} - -void canvas_disconnect(t_canvas *x, float from_, float outlet, float to_, float inlet) { - int ifrom=(int)from_, ito=int(to_); - t_gobj *from=0, *to=0; - canvas_each(gfrom,x) if (gfrom->dix->index == ifrom) {from=gfrom; break;} - canvas_each( gto,x) if ( gto->dix->index == ito) { to= gto; break;} - if (!from || !to) goto bad; - obj_disconnect((t_object *)from, int(outlet), (t_object *)to, int(inlet)); - return; -bad: - post("dumb."); -} - -static t_binbuf *canvas_cut_wires(t_canvas *x, t_gobj *o); -static void canvas_paste_wires(t_canvas *x, t_binbuf *buf); - -/* recursively check for abstractions to reload as result of a save. - Don't reload the one we just saved ("except") though. */ -/* LATER try to do the same trick for externs. */ -static void canvas_doreload(t_canvas *gl, t_symbol *name, t_symbol *dir, t_gobj *except) { - int i=0, nobj = gl->boxes->size(); - for (t_gobj *g = gl->boxes->first(); g && i < nobj; i++) { - if (g != except && g->_class == canvas_class) { - t_canvas *c = (t_canvas *)g; - if (canvas_isabstraction(c) && c->name==name && canvas_getdir(c) == dir) { - /* we're going to remake the object, so "g" will go stale. Get its index here, and afterwards restore g. - Also, the replacement will be at the end of the list, so we don't do g = g->next() in this case. */ - int j = g->dix->index; - int hadwindow = gl->havewindow; - if (!hadwindow) canvas_vis(canvas_getcanvas(gl), 1); - t_binbuf *buf = canvas_cut_wires(gl,g); - gl->boxes->remove(j); - //MISSING: remake the object here. - canvas_paste_wires(gl,buf); - if (!hadwindow) canvas_vis(canvas_getcanvas(gl), 0); - continue; - } - canvas_doreload(c,name,dir,except); - } - g = g->next(); - } -} - -void canvas_reload(t_symbol *name, t_symbol *dir, t_gobj *except) { - foreach(x,windowed_canvases) canvas_doreload(x->first, name, dir, except); -} - -/* ------------------------ event handling ------------------------ */ - -/* set a canvas up as a graph-on-parent. - Set reasonable defaults for any missing paramters and redraw things if necessary. */ -void canvas_setgraph(t_canvas *x, int flag, int nogoprect) { - if (!flag && x->gop) { - x->gop = 0; - } else if (flag) { - if (x->pixwidth <= 0) x->pixwidth = CANVAS_DEFGRAPHWIDTH; - if (x->pixheight <= 0) x->pixheight = CANVAS_DEFGRAPHHEIGHT; - SET(gop,1); - SET(hidetext,!!(flag&2)); - if (!nogoprect && !x->goprect) canvas_each(g,x) if (pd_checkobject(g)) {SET(goprect,1); break;} - if (canvas_isvisible(x) && x->goprect) gobj_changed(x,0); - } -} - -/* keep me */ -static int canvas_isconnected (t_canvas *x, t_text *ob1, int n1, t_text *ob2, int n2) { - canvas_wires_each(oc,t,x) - if (t.from == ob1 && t.outlet == n1 && t.to == ob2 && t.inlet == n2) return 1; - return 0; -} - -/* ----------------------------- window stuff ----------------------- */ - -void canvas_close(t_canvas *x) { - if (x->dix->canvas) canvas_vis(x, 0); else pd_free(x); -} - -static int canvas_find_index1, canvas_find_index2; -static t_binbuf *canvas_findbuf; -int binbuf_match(t_binbuf *inbuf, t_binbuf *searchbuf); - -/* find an atom or string of atoms */ -static int canvas_dofind(t_canvas *x, int *myindex1p) { - int myindex1 = *myindex1p, myindex2=0; - if (myindex1 >= canvas_find_index1) { - canvas_each(y,x) { - t_object *ob = pd_checkobject(y); - if (ob && binbuf_match(ob->ob_binbuf, canvas_findbuf)) { - if (myindex1 > canvas_find_index1 || - (myindex1 == canvas_find_index1 && myindex2 > canvas_find_index2)) { - canvas_find_index1 = myindex1; - canvas_find_index2 = myindex2; - vmess(x,gensym("menu-open"),""); - return 1; - } - } - myindex2++; - } - } - myindex2=0; - canvas_each(y,x) { - if (y->_class == canvas_class) { - (*myindex1p)++; - if (canvas_dofind((t_canvas *)y, myindex1p)) return 1; - } - myindex2++; - } - return 0; -} - -static void canvas_find_parent(t_canvas *x) { - if (x->dix->canvas) canvas_vis(canvas_getcanvas(x->dix->canvas), 1); -} - -static int canvas_dofinderror(t_canvas *gl, void *error_object) { - canvas_each(g,gl) { - if (g==error_object) { - /* got it... now show it. */ - canvas_vis(canvas_getcanvas(gl), 1); - return 1; - } else if (g->_class == canvas_class) { - if (canvas_dofinderror((t_canvas *)g, error_object)) return 1; - } - } - return 0; -} - -void canvas_finderror(void *error_object) { - foreach(x,windowed_canvases) if (canvas_dofinderror(x->first, error_object)) return; - post("... sorry, I couldn't find the source of that error."); -} - -extern t_class *text_class; -extern t_class *dummy_class; - -static int is_dummy (t_text *x) {return x->_class==dummy_class;} - -long canvas_base_o_index(void); - -void canvas_connect(t_canvas *x, t_floatarg ffrom, t_floatarg foutlet, t_floatarg fto,t_floatarg finlet) { - int base = canvas_base_o_index(); - int ifrom=base+int(ffrom), outlet=(int)foutlet; - int ito=base+int(fto), inlet=(int)finlet; - t_gobj *gfrom=0, *gto=0; - t_object *from=0, *to=0; - t_outconnect *oc; - if (ifrom<0) goto bad; - if (ito <0) goto bad; - canvas_each(zfrom,x) if (zfrom->dix->index == ifrom) {gfrom=zfrom; break;} - if (!gfrom) goto bad; - canvas_each( zto,x) if ( zto->dix->index == ito) { gto= zto; break;} - if (!gto) goto bad; - from = pd_checkobject(gfrom); - to = pd_checkobject( gto); - if (!from || !to) goto bad; - /* if object creation failed, make dummy inlets or outlets as needed */ - if (is_dummy(from)) while (outlet >= obj_noutlets(from)) outlet_new(from, &s_); - if (is_dummy(to)) while ( inlet >= obj_ninlets(to)) inlet_new(to,to,&s_,&s_); - if (!(oc = obj_connect(from,outlet,to,inlet))) goto bad; - pd_set_newest(oc); - gobj_setcanvas(oc,x); - oc->dix->index = x->next_w_index++; - return; -bad: - post("%s %d %d %d %d (%s->%s) connection failed", x->name->name,ifrom,outlet,ito,inlet, - from ? class_getname(from->_class) : "???", - to ? class_getname( to->_class) : "???"); -} - -#define ARRAYPAGESIZE 1000 /* this should match the page size in u_main.tk */ -/* aux routine to bash leading '#' to '$' for dialogs in u_main.tk which can't send symbols - starting with '$' (because the Pd message interpreter would change them!) */ -static t_symbol *sharptodollar(t_symbol *s) { - if (*s->name != '#') return s; - return symprintf("$%s",s->name+1); -} - -/* --------- "pure" arrays with scalars for elements. --------------- */ - -/* Pure arrays have no a priori graphical capabilities. -They are instantiated by "garrays" below or can be elements of other -scalars (g_scalar.c); their graphical behavior is defined accordingly. */ - -t_class *array_class; - -static t_array *array_new(t_symbol *tsym, t_gpointer *parent) { - t_array *x = (t_array *)pd_new(array_class); - t_template *t = template_findbyname(tsym); - x->tsym = tsym; - x->n = 1; - x->elemsize = sizeof(t_word) * t->n; - x->vec = (char *)getalignedbytes(x->elemsize); - /* note here we blithely copy a gpointer instead of "setting" a new one; this gpointer isn't accounted for - and needn't be since we'll be deleted before the thing pointed to gets deleted anyway; see array_free. */ - x->gp = *parent; - word_init((t_word *)x->vec, t, parent); - return x; -} - -void array_resize(t_array *x, int n) { - t_template *t = template_findbyname(x->tsym); - if (n < 1) n = 1; - int oldn = x->n; - int elemsize = sizeof(t_word) * t->n; - x->vec = (char *)resizealignedbytes(x->vec, oldn * elemsize, n * elemsize); - x->n = n; - if (n > oldn) { - char *cp = x->vec + elemsize * oldn; - for (int i = n-oldn; i--; cp += elemsize) { - t_word *wp = (t_word *)cp; - word_init(wp, t, &x->gp); - } - } -} - -static void array_resize_and_redraw(t_array *array, int n) {array_resize(array,n); gobj_changed(array,0);} - -void word_free(t_word *wp, t_template *t); - -static void array_free(t_array *x) { - t_template *scalartemplate = template_findbyname(x->tsym); - for (int i=0; i < x->n; i++) word_free((t_word *)(x->vec + x->elemsize*i), scalartemplate); - freealignedbytes(x->vec, x->elemsize * x->n); -} - -/* --------------------- graphical arrays (garrays) ------------------- */ -t_class *garray_class; -static t_pd *garray_arraytemplatecanvas; -void pd_eval_text2(const char *s) {pd_eval_text(s,strlen(s));} - -/* create invisible, built-in canvases to determine the templates for floats and float-arrays. */ -extern "C" void garray_init () { - hack = 0; /* invisible canvases must be, uh, invisible */ - if (garray_arraytemplatecanvas) return; - t_binbuf *b = binbuf_new(); - glob_setfilename(0, gensym("_float"), gensym(".")); - pd_eval_text2( - "#N canvas 0 0 458 153 10;\n" - "#X obj 43 31 struct _float_array array z float float style float linewidth float color;\n" - "#X obj 43 70 plot z color linewidth 0 0 1 style;\n"); - vmess(s__X.thing, gensym("pop"), "i", 0); - glob_setfilename(0, gensym("_float_array"), gensym(".")); - pd_eval_text2( - "#N canvas 0 0 458 153 10;\n" - "#X obj 39 26 struct float float y;\n"); - garray_arraytemplatecanvas = s__X.thing; - vmess(s__X.thing, gensym("pop"), "i", 0); - glob_setfilename(0, &s_, &s_); - binbuf_free(b); - hack = 1; /* enable canvas visibility for upcoming canvases */ -} - -/* create a new scalar attached to a symbol. Used to make floating-point arrays (the scalar will be of type "_float_array"). - Currently this is always called by graph_array() below; - but when we make a more general way to save and create arrays this might get called more directly. */ -static t_garray *graph_scalar(t_canvas *gl, t_symbol *s, t_symbol *tsym, int saveit) { - if (!template_findbyname(tsym)) return 0; - t_garray *x = (t_garray *)pd_new(garray_class); - x->scalar = scalar_new(gl, tsym); - x->realname = s; - x->realname = canvas_realizedollar(gl, s); - pd_bind(x,x->realname); - x->usedindsp = 0; - x->saveit = saveit; - x->listviewing = 0; - canvas_add(gl,x); - x->canvas = gl; - return x; -} - -#define TEMPLATE_CHECK(tsym,ret) if (!t) {error("couldn't find template %s", tsym->name); return ret;} -#define TEMPLATE_FLOATY(a,ret) if (!a) {error("%s: needs floating-point 'y' field", x->realname->name); return ret;} - -/* get a garray's "array" structure. */ -t_array *garray_getarray(t_garray *x) { - int zonset, ztype; - t_symbol *zarraytype; - t_scalar *sc = x->scalar; - t_template *t = template_findbyname(sc->t); - TEMPLATE_CHECK(sc->t,0) - if (!template_find_field(t,gensym("z"),&zonset,&ztype,&zarraytype)) { - error("template %s has no 'z' field", sc->t->name); - return 0; - } - if (ztype != DT_ARRAY) {error("template %s, 'z' field is not an array", sc->t->name); return 0;} - return sc->v[zonset].w_array; -} - -/* get the "array" structure and furthermore check it's float */ -static t_array *garray_getarray_floatonly(t_garray *x, int *yonsetp, int *elemsizep) { - t_array *a = garray_getarray(x); - int yonset, type; - t_symbol *arraytype; - t_template *t = template_findbyname(a->tsym); - if (!template_find_field(t,&s_y,&yonset,&type,&arraytype) || type != DT_FLOAT) return 0; - *yonsetp = yonset; - *elemsizep = a->elemsize; - return a; -} - -/* get the array's name. Return nonzero if it should be hidden */ -int garray_getname(t_garray *x, t_symbol **namep) { -// *namep = x->name; - *namep = x->realname; - return x->hidename; -} - -/* if there is one garray in a graph, reset the graph's coordinates to fit a new size and style for the garray */ -static void garray_fittograph(t_garray *x, int n, int style) { - t_array *array = garray_getarray(x); - t_canvas *gl = x->canvas; - if (gl->boxes->first() == x && !x->next()) - vmess(gl,gensym("bounds"),"ffff",0.,gl->y1, double(style==PLOTSTYLE_POINTS || n==1 ? n : n-1), gl->y2); - array_resize_and_redraw(array, n); -} - -/* handle "array" message to canvases; call graph_scalar above with an appropriate template; then set size and flags. - This is called from the menu and in the file format for patches. LATER replace this by a more coherent (and general) invocation. */ -t_garray *graph_array(t_canvas *gl, t_symbol *s, t_symbol *templateargsym, t_floatarg fsize, t_floatarg fflags) { - int n = (int)fsize, zonset, ztype, saveit; - t_symbol *zarraytype; - t_symbol *tsym = gensym("pd-_float_array"); - int flags = (int)fflags; - int filestyle = (flags & 6)>>1; - int style = filestyle == 0 ? PLOTSTYLE_POLY : filestyle == 1 ? PLOTSTYLE_POINTS : filestyle; - if (templateargsym != &s_float) {error("%s: only 'float' type understood", templateargsym->name); return 0;} - t_template *t = template_findbyname(tsym); - TEMPLATE_CHECK(tsym,0) - if (!template_find_field(t,gensym("z"),&zonset,&ztype,&zarraytype)) {error("template %s has no 'z' field", tsym->name); return 0;} - if (ztype != DT_ARRAY) {error("template %s, 'z' field is not an array", tsym->name); return 0;} - t_template *ztemplate = template_findbyname(zarraytype); - if (!ztemplate) {error("no template of type %s", zarraytype->name); return 0;} - saveit = (flags & 1) != 0; - t_garray *x = graph_scalar(gl, s, tsym, saveit); - x->hidename = (flags>>3)&1; - if (n <= 0) n = 100; - array_resize(x->scalar->v[zonset].w_array, n); - template_setfloat(t, gensym("style"), x->scalar->v, style, 1); - template_setfloat(t, gensym("linewidth"), x->scalar->v, style==PLOTSTYLE_POINTS?2:1, 1); - t_pd *x2 = pd_findbyclass(gensym("#A"), garray_class); - if (x2) pd_unbind(x2,gensym("#A")); - pd_bind(x,gensym("#A")); - garray_redraw(x); - return x; -} - -/* find the graph most recently added to this canvas; if none exists, return 0. */ -static t_canvas *canvas_findgraph(t_canvas *x) { - t_gobj *y = 0; - canvas_each(z,x) if (z->_class==canvas_class && ((t_canvas *)z)->gop) y = z; - return (t_canvas *)y; -} - -/* this is called back from the dialog window to create a garray. - The otherflag requests that we find an existing graph to put it in. */ -static void canvas_arraydialog(t_canvas *parent, t_symbol *name, t_floatarg size, t_floatarg fflags, t_floatarg otherflag) { - int flags = (int)fflags; - if (size<1) size=1; - t_canvas *gl = otherflag ? canvas_findgraph(parent) : 0; - if (!gl) gl = canvas_addcanvas(parent, &s_, 0, 1, (size>1 ? size-1 : size), -1, 0, 0, 0, 0); - graph_array(gl, sharptodollar(name), &s_float, size, flags); -} - -void garray_arrayviewlist_close(t_garray *x) { - x->listviewing = 0; - sys_vgui("pdtk_array_listview_closeWindow %s\n", x->realname->name); -} - -/* this is called from the properties dialog window for an existing array */ -void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize, t_floatarg fflags, t_floatarg deleteit) { - int flags = (int)fflags; - int saveit = (flags&1)!=0; - int style = (flags>>1)&3; - float stylewas = template_getfloat(template_findbyname(x->scalar->t), gensym("style"), x->scalar->v, 1); - if (deleteit) {canvas_delete(x->canvas,x); return;} - t_symbol *argname = sharptodollar(name); - t_array *a = garray_getarray(x); - t_template *scalartemplate; - if (!a) {error("can't find array"); return;} - if (!(scalartemplate = template_findbyname(x->scalar->t))) {error("no template of type %s", x->scalar->t->name); return;} - if (argname != x->realname) { - if (x->listviewing) garray_arrayviewlist_close(x); - x->realname = argname; /* is this line supposed to exist? */ - pd_unbind(x,x->realname); - x->realname = canvas_realizedollar(x->canvas, argname); - pd_bind(x,x->realname); - gobj_changed(x,0); - } - int size = max(1,int(fsize)); - if (size != a->n) garray_resize(x, size); else if (style != stylewas) garray_fittograph(x, size, style); - template_setfloat(scalartemplate, gensym("style"), x->scalar->v, (float)style, 0); - garray_setsaveit(x, saveit!=0); - garray_redraw(x); -} - -void garray_arrayviewlist_new(t_garray *x) { - char *s = x->realname->name; - int yonset=0, elemsize=0; - char cmdbuf[200]; - t_array *a = garray_getarray_floatonly(x, &yonset, &elemsize); - if (!a) {error("garray_arrayviewlist_new()"); return;} - x->listviewing = 1; - sprintf(cmdbuf, "pdtk_array_listview_new %%s %s %d\n",s,0); - for (int i=0; i < ARRAYPAGESIZE && i < a->n; i++) { - float yval = *(float *)(a->vec + elemsize*i + yonset); - sys_vgui(".%sArrayWindow.lb insert %d {%d) %g}\n",s,i,i,yval); - } -} - -void garray_arrayviewlist_fillpage(t_garray *x, t_float page, t_float fTopItem) { - char *s = x->realname->name; - int yonset=0, elemsize=0, topItem=(int)fTopItem; - t_array *a = garray_getarray_floatonly(x, &yonset, &elemsize); - if (!a) {error("garray_arrayviewlist_fillpage()"); return;} - if (page<0) { - page = 0; - } else if ((page * ARRAYPAGESIZE) >= a->n) { - page = int(((int)a->n - 1)/ (int)ARRAYPAGESIZE); - } - sys_vgui("pdtk_array_listview_setpage %s %d\n",s,(int)page); - sys_vgui(".%sArrayWindow.lb delete 0 %d\n",s,ARRAYPAGESIZE-1); - for (int i = (int)page * ARRAYPAGESIZE; (i < (page+1)*ARRAYPAGESIZE && i < a->n); i++) { - float yval = *(float *)(a->vec + elemsize*i + yonset); - sys_vgui(".%sArrayWindow.lb insert %d {%d) %g}\n",s,i%ARRAYPAGESIZE,i,yval); - } - sys_vgui(".%sArrayWindow.lb yview %d\n",s,topItem); -} - -static void garray_free(t_garray *x) { - if (x->listviewing) garray_arrayviewlist_close(x); - pd_unbind(x,x->realname); - /* LATER find a way to get #A unbound earlier (at end of load?) */ - t_pd *x2; - while ((x2 = pd_findbyclass(gensym("#A"), garray_class))) pd_unbind(x2, gensym("#A")); -} - -/* ------------- code used by both array and plot widget functions ---- */ - -static void array_redraw(t_array *a, t_canvas *canvas) { - /* what was that for? */ - scalar_redraw(a->gp.scalar, canvas); -} - -static int canvas_xtopixels(t_canvas *x, float xval); -static int canvas_ytopixels(t_canvas *x, float yval); - -/* routine to get screen coordinates of a point in an array */ -static void array_getcoordinate(t_canvas *canvas, char *elem, int xonset, int yonset, int wonset, int indx, -float basex, float basey, float xinc, t_slot *xslot, t_slot *yslot, t_slot *wslot, -float *xp, float *yp, float *wp) { - float xval, yval, ypix, wpix; - if (xonset >= 0) xval = *(float *)(elem + xonset); else xval = indx * xinc; - if (yonset >= 0) yval = *(float *)(elem + yonset); else yval = 0; - ypix = canvas_ytopixels(canvas, basey + slot_cvttocoord(yslot, yval)); - if (wonset >= 0) { - /* found "w" field which controls linewidth. */ - float wval = *(float *)(elem + wonset); - wpix = canvas_ytopixels(canvas, basey + slot_cvttocoord(yslot,yval) + slot_cvttocoord(wslot,wval)) - ypix; - if (wpix < 0) wpix = -wpix; - } else wpix = 1; - *xp = canvas_xtopixels(canvas, basex + slot_cvttocoord(xslot, xval)); - *yp = ypix; - *wp = wpix; -} - -static struct { - float xcumulative, ycumulative; - t_slot *xfield, *yfield; - t_canvas *canvas; - t_scalar *scalar; - t_array *array; - t_word *wp; - t_template *t; - int npoints, elemsize; - float initx, xperpix, yperpix; - int lastx, fatten; -} ammo; - -/* LATER protect against the template changing or the scalar disappearing - probably by attaching a gpointer here ... */ -#if 0 -static void array_motion(void *z, t_floatarg dx, t_floatarg dy) { - ammo.xcumulative += dx * ammo.xperpix; - ammo.ycumulative += dy * ammo.yperpix; - if (ammo.xfield) {// xy plot - for (int i=0; i<ammo.npoints; i++) { - t_word *thisword = (t_word *)(((char *)ammo.wp) + i*ammo.elemsize); - float xwas = slot_getcoord(ammo.xfield, ammo.t, thisword, 1); - float ywas = ammo.yfield ? slot_getcoord(ammo.yfield, ammo.t, thisword, 1) : 0; - slot_setcoord(ammo.xfield, ammo.t, thisword, xwas + dx, 1); - if (ammo.yfield) { - if (ammo.fatten) { - if (i == 0) { - float newy = max(0.f,ywas+dy*ammo.yperpix); - slot_setcoord(ammo.yfield, ammo.t, thisword, newy, 1); - } - } else slot_setcoord(ammo.yfield, ammo.t, thisword, ywas + dy*ammo.yperpix, 1); - } - } - } else if (ammo.yfield) {// y plot - int thisx = int(ammo.initx + ammo.xcumulative + 0.5), x2; - int increment, nchange; - float newy = ammo.ycumulative; - float oldy = slot_getcoord(ammo.yfield, ammo.t, (t_word *)(((char *)ammo.wp) + ammo.elemsize * ammo.lastx), 1); - float ydiff = newy-oldy; - CLAMP(thisx,0,1); - increment = thisx > ammo.lastx ? -1 : 1; - nchange = 1 + increment * (ammo.lastx - thisx); - x2 = thisx; - for (int i=0; i<nchange; i++, x2 += increment) { - slot_setcoord(ammo.yfield, ammo.t, (t_word *)(((char *)ammo.wp) + ammo.elemsize * x2), newy, 1); - if (nchange > 1) newy -= ydiff/(nchange-1); - } - ammo.lastx = thisx; - } - if (ammo.scalar) scalar_redraw(ammo.scalar, ammo.canvas); - if (ammo.array) array_redraw(ammo.array, ammo.canvas); -} -#endif - -int scalar_doclick(t_word *data, t_template *t, t_scalar *sc, t_array *ap, t_canvas *owner, float xloc, float yloc, -int xpix, int ypix, int shift, int alt, int dbl, int doit); - -static int array_getfields(t_symbol *elemtsym, t_canvas **elemtemplatecanvasp, -t_template **elemtemplatep, int *elemsizep, t_slot *xslot, t_slot *yslot, t_slot *wslot, -int *xonsetp, int *yonsetp, int *wonsetp); - -/* try clicking on an element of the array as a scalar (if clicking on the trace of the array failed) */ -static int array_doclick_element(t_array *array, t_canvas *canvas, t_scalar *sc, t_array *ap, -t_symbol *elemtsym, float linewidth, float xloc, float xinc, float yloc, -t_slot *xfield, t_slot *yfield, t_slot *wfield, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_canvas *elemtemplatecanvas; - t_template *elemtemplate; - int elemsize, yonset, wonset, xonset, incr; - //float xsum=0; - if (elemtsym == &s_float) return 0; - if (array_getfields(elemtsym,&elemtemplatecanvas,&elemtemplate,&elemsize,xfield,yfield,wfield,&xonset,&yonset,&wonset)) return 0; - /* if it has more than 2000 points, just check 300 of them. */ - if (array->n < 2000) incr=1; else incr = array->n/300; - for (int i=0; i < array->n; i += incr) { - //float usexloc = xonset>=0 ? xloc + slot_cvttocoord(xfield, *(float *)&array->vec[elemsize*i+xonset]) : xloc + xsum; - //if (xonset>=0) xsum += xinc; - //float useyloc = yloc + (yonset>=0 ? slot_cvttocoord(yfield, *(float *)&array->vec[elemsize*i+yonset]):0); - int hit = 0; - /* hit = scalar_doclick((t_word *)&array->vec[elemsize*i], - elemtemplate, 0, array, canvas, usexloc, useyloc, xpix, ypix, shift, alt, dbl, doit);*/ - if (hit) return hit; - } - return 0; -} - -static float canvas_pixelstox(t_canvas *x, float xpix); -static float canvas_pixelstoy(t_canvas *x, float xpix); - -/* convert an X screen distance to an X coordinate increment. */ -static float canvas_dpixtodx(t_canvas*x,float dxpix){return dxpix*(canvas_pixelstox(x,1)-canvas_pixelstox(x,0));} -static float canvas_dpixtody(t_canvas*x,float dypix){return dypix*(canvas_pixelstoy(x,1)-canvas_pixelstoy(x,0));} - -/* LATER move this and others back into plot parentwidget code, so they can be static (look in g_canvas.h for candidates). */ -int array_doclick(t_array *array, t_canvas *canvas, t_scalar *sc, t_array *ap, -t_symbol *elemtsym, float linewidth, float xloc, float xinc, float yloc, float scalarvis, -t_slot *xfield, t_slot *yfield, t_slot *wfield, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_canvas *elemtemplatecanvas; - t_template *elemtemplate; - int elemsize, yonset, wonset, xonset; - if (!array_getfields(elemtsym, &elemtemplatecanvas, &elemtemplate, &elemsize, - xfield, yfield, wfield, &xonset, &yonset, &wonset)) { - float best = 100; - /* if it has more than 2000 points, just check 1000 of them. */ - int incr = (array->n <= 2000 ? 1 : array->n / 1000); - for (int i=0; i < array->n; i += incr) { - float pxpix, pypix, pwpix, dx, dy; - array_getcoordinate(canvas, &array->vec[elemsize*i], xonset, yonset, wonset, i, - xloc, yloc, xinc, xfield, yfield, wfield, &pxpix, &pypix, &pwpix); - if (pwpix < 4) pwpix = 4; - dx = fabs(pxpix-xpix); if (dx>8) continue; - dy = fabs(pypix-ypix); if (dx+dy<best) best=dx+dy; - if (wonset >= 0) { - dy = fabs(pypix+pwpix-ypix); if (dx+dy < best) best = dx+dy; - dy = fabs(pypix-pwpix-ypix); if (dx+dy < best) best = dx+dy; - } - } if (best > 8) { - if (scalarvis != 0) return array_doclick_element(array, canvas, sc, ap, elemtsym, - linewidth, xloc, xinc, yloc, xfield, yfield, wfield, xpix, ypix, shift, alt, dbl, doit); - return 0; - } - best += 0.001; /* add truncation error margin */ - for (int i=0; i < array->n; i += incr) { - float pxpix, pypix, pwpix, dx, dy, dy2, dy3; - array_getcoordinate(canvas, &array->vec[elemsize*i], xonset, yonset, wonset, i, - xloc, yloc, xinc, xfield, yfield, wfield, &pxpix, &pypix, &pwpix); - if (pwpix < 4) pwpix = 4; - dx = fabs(pxpix-xpix); - dy = fabs(pypix-ypix); - if (wonset >= 0) { - dy2 = fabs(pypix+pwpix-ypix); - dy3 = fabs(pypix-pwpix-ypix); - if (yonset < 0) dy = 100; - } else dy2 = dy3 = 100; - if (dx + dy <= best || dx + dy2 <= best || dx + dy3 <= best) { - if (dy<dy2 && dy<dy3) ammo.fatten = 0; - else if (dy2<dy3) ammo.fatten = -1; - else ammo.fatten = 1; - if (doit) { - char *elem = array->vec; - ammo.elemsize = elemsize; - ammo.canvas = canvas; - ammo.scalar = sc; - ammo.array = ap; - ammo.t = elemtemplate; - ammo.xperpix = canvas_dpixtodx(canvas, 1); - ammo.yperpix = canvas_dpixtody(canvas, 1); - if (alt && xpix < pxpix) { /* delete a point */ - if (array->n <= 1) return 0; - memmove(&array->vec[elemsize*i], &array->vec[elemsize*(i+1)], (array->n-1-i) * elemsize); - array_resize_and_redraw(array, array->n - 1); - return 0; - } else if (alt) { - /* add a point (after the clicked-on one) */ - array_resize_and_redraw(array, array->n + 1); - elem = array->vec; - memmove(elem + elemsize * (i+1), elem + elemsize*i, (array->n-i-1) * elemsize); - i++; - } - if (xonset >= 0) { - ammo.xfield = xfield; - ammo.xcumulative = slot_getcoord(xfield,ammo.t,(t_word *)(elem+elemsize*i),1); - ammo.wp = (t_word *)(elem + elemsize*i); - if (shift) ammo.npoints = array->n - i; - else ammo.npoints = 1; - } else { - ammo.xfield = 0; - ammo.xcumulative = 0; - ammo.wp = (t_word *)elem; - ammo.npoints = array->n; - ammo.initx = i; - ammo.lastx = i; - ammo.xperpix *= (xinc == 0 ? 1 : 1./xinc); - } - if (ammo.fatten) { - ammo.yfield = wfield; - ammo.ycumulative = slot_getcoord(wfield,ammo.t,(t_word *)(elem+elemsize*i),1); - ammo.yperpix *= -ammo.fatten; - } else if (yonset >= 0) { - ammo.yfield = yfield; - ammo.ycumulative = slot_getcoord(yfield,ammo.t,(t_word *)(elem+elemsize*i),1); - } else { - ammo.yfield = 0; - ammo.ycumulative = 0; - } - /* canvas_grab(canvas, 0, array_motion, 0, xpix, ypix); */ - } - return 0; - } - } - } - return 0; -} - -static void garray_save(t_gobj *z, t_binbuf *b) { - t_garray *x = (t_garray *)z; - t_array *array = garray_getarray(x); - /* LATER "save" the scalar as such */ - if (x->scalar->t != gensym("pd-_float_array")) {error("can't save arrays of type %s yet", x->scalar->t->name); return;} - t_template *scalartemplate = template_findbyname(x->scalar->t); - if (!scalartemplate) {error("no template of type %s", x->scalar->t->name); return;} - int style = (int)template_getfloat(scalartemplate, gensym("style"), x->scalar->v, 0); - int filestyle = (style == PLOTSTYLE_POINTS ? 1 : (style == PLOTSTYLE_POLY ? 0 : style)); - binbuf_addv(b, "ttsisi;","#X","array", x->realname, array->n, &s_float, x->saveit+2*filestyle+8*x->hidename); - if (x->saveit) { - int n = array->n, n2 = 0; - while (n2 < n) { - int chunk = imin(n-n2,1000); - binbuf_addv(b,"ti","#A",n2); - for (int i=0; i<chunk; i++) binbuf_addv(b, "f", ((float *)array->vec)[n2+i]); - binbuf_addv(b, ";"); - n2 += chunk; - } - } -} - -/* required by d_array.c and d_soundfile */ -void garray_redraw(t_garray *x) {gobj_changed(x,0);} - -/* those three required by d_array.c */ -void garray_usedindsp(t_garray *x) {x->usedindsp = 1;} -int garray_npoints(t_garray *x) {return garray_getarray(x)->n;} /* get the length */ -char *garray_vec(t_garray *x) {return (char *)garray_getarray(x)->vec;} /* get the contents */ - -/* routine that checks if we're just an array of floats and if so returns the goods */ -int garray_getfloatarray(t_garray *x, int *size, t_float **vec) { - int yonset, elemsize; t_array *a = garray_getarray_floatonly(x, &yonset, &elemsize); - TEMPLATE_FLOATY(a,0) - if (elemsize != sizeof(t_word)) {error("%s: has more than one field", x->realname->name); return 0;} - *size = garray_npoints(x); - *vec = (float *)garray_vec(x); - return 1; -} - -/* set the "saveit" flag */ -void garray_setsaveit(t_garray *x, int saveit) { - if (x->saveit && !saveit) post("warning: array %s: clearing save-in-patch flag", x->realname->name); - x->saveit = saveit; -} - -static void garray_const(t_garray *x, t_floatarg g) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - TEMPLATE_FLOATY(array,) - for (int i=0; i<array->n; i++) *((float *)(array->vec + elemsize*i) + yonset) = g; - garray_redraw(x); -} - -/* sum of Fourier components; called from functions below */ -static void garray_dofo(t_garray *x, int npoints, float dcval, int nsin, t_float *vsin, int sineflag) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - TEMPLATE_FLOATY(array,) - if (npoints == 0) npoints = 512; /* dunno what a good default would be... */ - if (npoints != (1<<ilog2(npoints))) { - npoints = 1<<ilog2(npoints); - post("%s: rounnding to %d points", array->tsym->name, npoints); - } - garray_resize(x, npoints + 3); - double phaseincr = 2. * 3.14159 / npoints; - double phase = -phaseincr; - for (int i=0; i<array->n; i++, phase += phaseincr) { - double fj; - double sum = dcval; - int j; - if (sineflag) for (j=0, fj=phase; j<nsin; j++, fj+=phase) sum += vsin[j] * sin(fj); - else for (j=0, fj= 0; j<nsin; j++, fj+=phase) sum += vsin[j] * cos(fj); - *((float *)(array->vec + elemsize*i) + yonset) = sum; - } - garray_redraw(x); -} - -static void garray_sinesum(t_garray *x, t_symbol *s, int argc, t_atom *argv) { - if (argc < 2) {error("%s: need number of points and partial strengths", x->realname->name); return;} - t_float *svec = (t_float *)getbytes(sizeof(t_float) * argc); - int npoints = atom_getintarg(0,argc--,argv++); - argv++, argc--; /* is it normal that this happens a second time? */ - for (int i=0; i < argc; i++) svec[i] = atom_getfloatarg(i, argc, argv); - garray_dofo(x, npoints, 0, argc, svec, 1); - free(svec); -} -static void garray_cosinesum(t_garray *x, t_symbol *s, int argc, t_atom *argv) { - if (argc < 2) {error("%s: need number of points and partial strengths", x->realname->name); return;} - t_float *svec = (t_float *)getbytes(sizeof(t_float) * argc); - int npoints = atom_getintarg(0,argc--,argv++); - for (int i=0; i < argc; i++) svec[i] = atom_getfloatarg(i, argc, argv); - garray_dofo(x, npoints, 0, argc, svec, 0); - free(svec); -} - -static void garray_normalize(t_garray *x, t_float f) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - double maxv=0; - TEMPLATE_FLOATY(array,) - if (f <= 0) f = 1; - for (int i=0; i < array->n; i++) { - double v = *((float *)(array->vec + elemsize*i) + yonset); - if ( v > maxv) maxv = v; - if (-v > maxv) maxv = -v; - } - if (maxv > 0) { - double renormer = f/maxv; - for (int i=0; i < array->n; i++) *((float *)(array->vec + elemsize*i) + yonset) *= renormer; - } - garray_redraw(x); -} - -/* list: the first value is an index; subsequent values are put in the "y" slot of the array. */ -static void garray_list(t_garray *x, t_symbol *s, int argc, t_atom *argv) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - TEMPLATE_FLOATY(array,) - if (argc < 2) return; - int firstindex = atom_getintarg(0,argc--,argv++); - if (firstindex < 0) { /* drop negative x values */ - argc += firstindex; - argv -= firstindex; - firstindex = 0; - } - if (argc + firstindex > array->n) argc = array->n - firstindex; - for (int i=0; i < argc; i++) *((float *)(array->vec + elemsize * (i + firstindex)) + yonset) = atom_getfloat(argv + i); - garray_redraw(x); -} - -static void garray_bounds(t_garray *x, t_floatarg x1, t_floatarg y1, t_floatarg x2, t_floatarg y2) -{vmess(x->canvas, gensym("bounds"), "ffff", x1, y1, x2, y2);} -static void garray_xticks(t_garray *x, t_floatarg point, t_floatarg inc, t_floatarg f) -{vmess(x->canvas, gensym("xticks"), "fff", point, inc, f);} -static void garray_yticks(t_garray *x, t_floatarg point, t_floatarg inc, t_floatarg f) -{vmess(x->canvas, gensym("yticks"), "fff", point, inc, f);} -static void garray_xlabel(t_garray *x, t_symbol *s, int argc, t_atom *argv) {typedmess(x->canvas, s, argc, argv);} -static void garray_ylabel(t_garray *x, t_symbol *s, int argc, t_atom *argv) {typedmess(x->canvas, s, argc, argv);} - -static void garray_rename(t_garray *x, t_symbol *s) { - if (x->listviewing) garray_arrayviewlist_close(x); - pd_unbind(x,x->realname); - x->realname = s; - pd_bind(x,x->realname); - garray_redraw(x); -} - -static void garray_read(t_garray *x, t_symbol *filename) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - FILE *fd; - char *buf, *bufptr; - TEMPLATE_FLOATY(array,) - int nelem = array->n; - int filedesc = canvas_open2(canvas_getcanvas(x->canvas), filename->name, "", &buf, &bufptr, 0); - if (filedesc<0) {error("%s: can't open", filename->name); free(buf); return;} - if (!(fd = fdopen(filedesc, "r"))) {error("%s: can't open", filename->name); free(buf); return;} - int i; - for (i=0; i < nelem; i++) { - if (!fscanf(fd, "%f", (float *)(array->vec + elemsize*i) + yonset)) { - post("%s: read %d elements into table of size %d", filename->name, i, nelem); - break; - } - } - while (i < nelem) *((float *)(array->vec + elemsize*i) + yonset) = 0, i++; - fclose(fd); - garray_redraw(x); - free(buf); -} - -static void garray_write(t_garray *x, t_symbol *filename) { - int yonset, elemsize; t_array *array = garray_getarray_floatonly(x, &yonset, &elemsize); - TEMPLATE_FLOATY(array,) - char *buf = canvas_makefilename(canvas_getcanvas(x->canvas),filename->name,0,0); - sys_bashfilename(buf, buf); - FILE *fd = fopen(buf, "w"); - if (!fd) {error("can't create file '%s'", buf); free(buf); return;} - free(buf); - for (int i=0; i < array->n; i++) { - if (fprintf(fd, "%g\n", *(float *)(((array->vec + sizeof(t_word) * i)) + yonset)) < 1) { - post("%s: write error", filename->name); - break; - } - } - fclose(fd); -} - -/* d_soundfile.c uses this! */ -int garray_ambigendian () { - unsigned short s = 1; - unsigned char c = *(char *)(&s); - return c==0; -} - -/* d_soundfile.c uses this! */ -void garray_resize(t_garray *x, t_floatarg f) { - t_array *array = garray_getarray(x); - int n = f<1?1:(int)f; - garray_fittograph(x, n, (int)template_getfloat(template_findbyname(x->scalar->t), gensym("style"), x->scalar->v, 1)); - array_resize_and_redraw(array, n); - if (x->usedindsp) canvas_update_dsp(); -} - -static void garray_print(t_garray *x) { - t_array *array = garray_getarray(x); - post("garray %s: template %s, length %d", x->realname->name, array->tsym->name, array->n); -} - -static void g_array_setup() { - t_class *c = garray_class = class_new2("array",0,garray_free,sizeof(t_garray),CLASS_GOBJ,""); - class_addlist(garray_class, garray_list); - class_addmethod2(c, garray_const, "const", "F"); - class_addmethod2(c, garray_bounds, "bounds", "ffff"); - class_addmethod2(c, garray_xticks, "xticks", "fff"); - class_addmethod2(c, garray_xlabel, "xlabel", "*"); - class_addmethod2(c, garray_yticks, "yticks", "fff"); - class_addmethod2(c, garray_ylabel, "ylabel", "*"); - class_addmethod2(c, garray_rename, "rename", "s"); - class_addmethod2(c, garray_read, "read", "s"); - class_addmethod2(c, garray_write, "write", "s"); - class_addmethod2(c, garray_resize, "resize", "f"); - class_addmethod2(c, garray_print, "print", ""); - class_addmethod2(c, garray_sinesum, "sinesum", "*"); - class_addmethod2(c, garray_cosinesum, "cosinesum", "*"); - class_addmethod2(c, garray_normalize, "normalize", "F"); - class_addmethod2(c, garray_arraydialog, "arraydialog", "sfff"); - class_addmethod2(c, garray_arrayviewlist_new, "arrayviewlistnew", ""); - class_addmethod2(c, garray_arrayviewlist_fillpage, "arrayviewlistfillpage", "fF"); - class_addmethod2(c, garray_arrayviewlist_close, "arrayviewclose", ""); - class_setsavefn(c, garray_save); - array_class = class_new2("array_really",0,array_free,sizeof(t_array),CLASS_GOBJ,""); -} - -static void graph_graphrect(t_gobj *z, t_canvas *canvas, int *xp1, int *yp1, int *xp2, int *yp2); - -void canvas_add_debug(t_canvas *x, t_gobj *y) { - if (!y->_class->patchable) { - printf("canvas_add %p %p class=%s (non-t_text)\n",x,y,y->_class->name->name); - } else { - t_binbuf *bb = ((t_text *)y)->binbuf; - if (binbuf_getvec(bb)) { - char *buf; int bufn; - binbuf_gettext(bb,&buf,&bufn); - printf("canvas_add %p %p [%.*s]\n",x,y,bufn,buf); - free(buf); - } else { - printf("canvas_add %p %p class=%s (binbuf without b_vec !)\n",x,y,y->_class->name->name); - } - } -} - -void canvas_add(t_canvas *x, t_gobj *y, int index) { - //post("canvas_add index=%d next_o_index=%d",index,x->next_o_index); - gobj_setcanvas(y,x); - if (index<0) y->dix->index = x->next_o_index++; - else y->dix->index = index; - x->boxes->add(y); - if (x->gop && !x->goprect && pd_checkobject(y)) SET(goprect,1); - //if (class_isdrawcommand(y->_class)) canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(canvas_getcanvas(x)->name)), 0); -} - -/* delete an object from a canvas and free it */ -void canvas_delete(t_canvas *x, t_gobj *y) { - bool chkdsp = !!zgetfn(y,gensym("dsp")); - //int drawcommand = class_isdrawcommand(y->_class); - /* if we're a drawing command, erase all scalars now, before deleting it; we'll redraw them once it's deleted below. */ - //if (drawcommand) canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(canvas_getcanvas(x)->name)), 2); - canvas_deletelinesfor(x,(t_text *)y); - x->boxes->remove_by_value(y); - /* BUG: should call gobj_onsubscribe here, to flush the zombie */ - pd_free(y); - if (chkdsp) canvas_update_dsp(); - //if (drawcommand) canvas_redrawallfortemplate(template_findbyname(canvas_makebindsym(canvas_getcanvas(x)->name)), 1); -} - -static void canvas_clear(t_canvas *x) { - t_gobj *y; - int dspstate = 0, suspended = 0; - t_symbol *dspsym = gensym("dsp"); - /* to avoid unnecessary DSP resorting, we suspend DSP only if we find a DSP object. */ - canvas_each(y,x) if (!suspended && pd_checkobject(y) && zgetfn(y,dspsym)) {dspstate = canvas_suspend_dsp(); suspended=1;} - while ((y = x->boxes->first())) x->boxes->remove_by_value(y); - if (suspended) canvas_resume_dsp(dspstate); -} - - -t_canvas *canvas_getcanvas(t_canvas *x) { - while (x->dix->canvas && !x->havewindow && x->gop) x = x->dix->canvas; - return x; -} - -static void scalar_getbasexy(t_scalar *x, float *basex, float *basey); - -static float gobj_getxforsort(t_gobj *g) { - if (g->_class!=scalar_class) return 0; - float x1, y1; - scalar_getbasexy((t_scalar *)g, &x1, &y1); - return x1; -} - -// three-way comparison (T is assumed Comparable) -// template <class T> static inline T cmp(T a, T b) {return a<b ? -1 : a>b;} - -bool canvas_sort_lt(t_gobj * const &a, t_gobj * const &b) /* is a StrictWeakOrdering */ { - return gobj_getxforsort(a) < gobj_getxforsort(b); -} - -void canvas_sort(t_canvas *x) { - std::vector<t_gobj *> v; - canvas_each(y,x) v.push_back(y); - sort(v.begin(),v.end(),canvas_sort_lt); - x->boxes->map.clear(); - int i=0; - foreach(y,v) {(*y)->dix->index=i++; x->boxes->add(*y);} -} - -static t_inlet *canvas_addinlet(t_canvas *x, t_pd *who, t_symbol *s, t_symbol* h) { - t_inlet *ip = inlet_new(x,who,s,0); inlet_settip(ip,h); - if (gstack_empty()) canvas_resortinlets(x); - gobj_changed(x,0); return ip; -} -static t_outlet *canvas_addoutlet(t_canvas *x, t_pd *who, t_symbol *s) { - t_outlet *op = outlet_new(x,s); - if (gstack_empty()) canvas_resortoutlets(x); - gobj_changed(x,0); return op; -} - -static void canvas_rminlet(t_canvas *x, t_inlet *ip) { - if (x->dix->canvas) canvas_deletelinesforio(x->dix->canvas,x,ip,0); - inlet_free(ip); /*gobj_changed(x,0);*/ -} -static void canvas_rmoutlet(t_canvas *x, t_outlet *op) { - if (x->dix->canvas) canvas_deletelinesforio(x->dix->canvas,x,0,op); - outlet_free(op); /*gobj_changed(x,0);*/ -} - -extern "C" t_inlet *vinlet_getit(t_pd *x); -extern "C" t_outlet *voutlet_getit(t_pd *x); - -typedef int (*t_order)(const void *, const void *); -int gobj_order_x (t_object **a, t_object **b) {return (*a)->x - (*b)->x;} - -//{std::ostringstream s; s<<"disorder:"; for (int i=0; i<n; i++) s<<" "<<vec[i]->x; post("%s",s.str().data());} - -void obj_moveinletfirst(t_object *x, t_inlet *i); -void obj_moveoutletfirst(t_object *x, t_outlet *o); - -static void canvas_resortinlets(t_canvas *x) { - int n=0; canvas_each(y,x) if (y->_class==vinlet_class) n++; - t_object **vec = new t_object *[n], **vp = vec; - canvas_each(y,x) if (y->_class==vinlet_class) *vp++ = (t_object *)y; - qsort(vec,n,sizeof(t_object *),(t_order)gobj_order_x); - for (int i=n; i--;) obj_moveinletfirst(x,vinlet_getit(vec[i])); - delete[] vec; -} -static void canvas_resortoutlets(t_canvas *x) { - int n=0; canvas_each(y,x) if (y->_class==voutlet_class) n++; - t_object **vec = new t_object *[n], **vp = vec; - canvas_each(y,x) if (y->_class==voutlet_class) *vp++ = (t_object *)y; - qsort(vec,n,sizeof(t_object *),(t_order)gobj_order_x); - for (int i=n; i--;) obj_moveoutletfirst(x,voutlet_getit(vec[i])); - delete[] vec; -} - -static void graph_bounds(t_canvas *x, t_floatarg x1, t_floatarg y1, t_floatarg x2, t_floatarg y2) { - x->x1 = x1; x->y1 = y1; - x->x2 = x2; x->y2 = y2; - if (x->x2 == x->x1 || x->y2 == x->y1) { - error("empty bounds rectangle"); - x->x1 = x->y1 = 0; - x->x2 = x->y2 = 1; - } - gobj_changed(x,0); -} - -static void graph_xticks(t_canvas *x, t_floatarg point, t_floatarg inc, t_floatarg f) -{t_tick *t = &x->xtick; t->point = point; t->inc = inc; t->lperb = (int)f; gobj_changed(x,"xticks");} -static void graph_yticks(t_canvas *x, t_floatarg point, t_floatarg inc, t_floatarg f) -{t_tick *t = &x->ytick; t->point = point; t->inc = inc; t->lperb = (int)f; gobj_changed(x,"yticks");} - -static void graph_xlabel(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - if (argc < 1) {error("graph_xlabel: no y value given"); return;} - x->xlabely = atom_getfloatarg(0,argc--,argv++); - x->xlabel = realloc2(x->xlabel,argc); - x->nxlabels = argc; - for (int i=0; i < argc; i++) x->xlabel[i] = atom_gensym(&argv[i]); - gobj_changed(x,"xlabel"); -} -static void graph_ylabel(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - if (argc < 1) {error("graph_ylabel: no x value given"); return;} - x->ylabelx = atom_getfloatarg(0,argc--,argv++); - x->ylabel = realloc2(x->ylabel,argc); - x->nylabels = argc; - for (int i=0; i < argc; i++) x->ylabel[i] = atom_gensym(&argv[i]); - gobj_changed(x,"ylabel"); -} - -/* if we appear as a text box on parent, our range in our coordinates (x1, etc.) - specifies the coordinate range of a one-pixel square at top left of the window. - if we're a graph when shown on parent, but own our own window right now, our range - in our coordinates (x1, etc.) is spread over the visible window size, given by screenx1, etc. - otherwise, we appear in a graph within a parent canvas, so get our screen rectangle on parent and transform. */ -static float canvas_pixelstox(t_canvas *x, float xpix) { - int x1, y1, x2, y2; float width = x->x2-x->x1; - if (!x->gop) return x->x1 + width * xpix; - if (x->havewindow) return x->x1 + width * xpix / (x->screenx2-x->screenx1); - graph_graphrect(x, x->dix->canvas, &x1, &y1, &x2, &y2); - return x->x1 + width * (xpix-x1) / (x2-x1); -} -static float canvas_pixelstoy(t_canvas *x, float ypix) { - int x1, y1, x2, y2; float height = x->y2-x->y1; - if (!x->gop) return x->y1 + height * ypix; - if (x->havewindow) return x->y1 + height * ypix / (x->screeny2-x->screeny1); - graph_graphrect(x, x->dix->canvas, &x1, &y1, &x2, &y2); - return x->y1 + height * (ypix-y1) / (y2-y1); -} - -/* convert an x coordinate value to an x pixel location in window */ -static int canvas_xtopixels(t_canvas *x, float xval) { - int x1, y1, x2, y2; float width = x->x2-x->x1; - if (!x->gop) return int((xval-x->x1)/width); - if (x->havewindow) return int((x->screenx2-x->screenx1) * (xval-x->x1) / width); - graph_graphrect(x, x->dix->canvas, &x1, &y1, &x2, &y2); - return int(x1 + (x2-x1) * (xval-x->x1) / width); -} -static int canvas_ytopixels(t_canvas *x, float yval) { - int x1, y1, x2, y2; float height = x->y2-x->y1; - if (!x->gop) return int((yval-x->y1)/height); - if (x->havewindow) return int((x->screeny2-x->screeny1) * (yval-x->y1) / height); - graph_graphrect(x, x->dix->canvas, &x1, &y1, &x2, &y2); - return int(y1 + (y2-y1) * (yval-x->y1) / height); -} - -/* --------------------------- widget behavior ------------------- */ -/* don't remove this code yet: has to be rewritten in tcl */ -#if 1 -#define FONT "pourier" -static void graph_vis(t_gobj *gr, int vis) { - t_canvas *x = (t_canvas *)gr; - t_canvas *c = canvas_getcanvas(x->dix->canvas); - char tag[50]; - int x1=69, y1=69, x2=69, y2=69; - sprintf(tag, "graph%lx", (t_int)x); - if (vis) { - sys_mgui(x,"ninlets=","i",0/*obj_ninlets(x)*/); - sys_mgui(x,"noutlets=","i",0/*obj_noutlets(x)*/); - } - /* if we look like a graph but have been moved to a toplevel, just show the bounding rectangle */ - if (x->havewindow) { - /*if (vis) sys_vgui(".x%lx.c create polygon %d %d %d %d %d %d %d %d %d %d -tags %s -fill #c0c0c0\n", - (long)c, x1, y1, x1, y2, x2, y2, x2, y1, x1, y1, tag);*/ - return; - } - /* draw a rectangle around the graph */ - sys_vgui(".x%lx.c create line %d %d %d %d %d %d %d %d %d %d -tags %s\n", - (long)c, x1, y1, x1, y2, x2, y2, x2, y1, x1, y1, tag); - /* if there's just one "garray" in the graph, write its name along the top */ - int i = min(y1,y2)-1; - t_symbol *arrayname; - canvas_each(g,x) if (g->g_pd == garray_class && !garray_getname((t_garray *)g, &arrayname)) { - // i -= sys_fontheight(glist_getfont(x)); - sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor nw\ - -font -*-courier-bold--normal--%d-* -tags %s\n", - (long)canvas_getcanvas(x), x1, i, arrayname->name, - 42/*sys_hostfontsize(canvas_getfont(x))*/, tag); - } - - /* draw ticks on horizontal borders. If lperb field is zero, this is disabled. */ - #define DRAWTICK(x1,y1,x2,y2) sys_vgui(".x%lx.c create line %d %d %d %d -tags %s\n", \ - (long)c, int(x1),int(y1),int(x2),int(y2),tag) - float f; - if (x->xtick.lperb) { - float upix, lpix; - if (y2<y1) {upix = y1; lpix = y2;} - else {upix = y2; lpix = y1;} - for (i=0,f=x->xtick.point; f<0.99*x->x2+0.01*x->x1; i++, f+=x->xtick.inc) { - int tickpix = i%x->xtick.lperb?2:4, x0 = canvas_xtopixels(x,f); - DRAWTICK(x0,upix,x0,upix-tickpix); - DRAWTICK(x0,lpix,x0,lpix+tickpix); - } - for (i=1,f=x->xtick.point-x->xtick.inc; f>0.99*x->x1+0.01*x->x2; i++,f-=x->xtick.inc) { - int tickpix = i%x->xtick.lperb?2:4, x0 = canvas_xtopixels(x,f); - DRAWTICK(x0,upix,x0,upix-tickpix); - DRAWTICK(x0,lpix,x0,lpix+tickpix); - } - } - /* draw ticks in vertical borders*/ - if (x->ytick.lperb) { - float ubound, lbound; - if (x->y2<x->y1) {ubound = x->y1; lbound = x->y2;} - else {ubound = x->y2; lbound = x->y1;} - for (i=0,f=x->ytick.point; f<0.99*ubound+0.01*lbound; i++, f += x->ytick.inc) { - int tickpix = i%x->ytick.lperb?2:4, y0 = canvas_ytopixels(x,f); - DRAWTICK(x1,y0,x1+tickpix,y0); - DRAWTICK(x2,y0,x2-tickpix,y0); - } - for (i=1,f=x->ytick.point-x->ytick.inc; f>0.99*lbound+0.01*ubound; i++,f-=x->ytick.inc) { - int tickpix = i%x->ytick.lperb?2:4, y0 = canvas_ytopixels(x,f); - DRAWTICK(x1,y0,x1+tickpix,y0); - DRAWTICK(x2,y0,x2-tickpix,y0); - } - } - /* draw labels */ - #define DRAWLABEL(x1,y1) sys_vgui(".x%lx.c create text %d %d -text {%s} -font "FONT" -tags %s\n", (long)c, \ - int(canvas_xtopixels(x,x1)),int(canvas_ytopixels(x,y1)),s,42,tag); - for (int i=0; i < x->nxlabels; i++) {char *s = x->xlabel[i]->name; DRAWLABEL(atof(s),x->xlabely);} - for (int i=0; i < x->nylabels; i++) {char *s = x->ylabel[i]->name; DRAWLABEL(x->ylabelx,atof(s));} -} -#endif - -/* nonstatic (to fix a -lib load error) */ -extern "C" int text_xpix(t_text *x, t_canvas *canvas) { - float width = canvas->x2-canvas->x1; - if (canvas->havewindow || !canvas->gop) return x->x; - if (canvas->goprect) return canvas->x+x->x-canvas->xmargin; - return canvas_xtopixels(canvas, canvas->x1 + width * x->x / (canvas->screenx2-canvas->screenx1)); -} -extern "C" int text_ypix(t_text *x, t_canvas *canvas) { - float height = canvas->y2-canvas->y1; - if (canvas->havewindow || !canvas->gop) return x->y; - if (canvas->goprect) return canvas->y+x->y-canvas->ymargin; - return canvas_ytopixels(canvas, canvas->y1 + height* x->y / (canvas->screeny2-canvas->screeny1)); -} -static void graph_graphrect(t_gobj *z, t_canvas *canvas, int *xp1, int *yp1, int *xp2, int *yp2) { - t_canvas *x = (t_canvas *)z; - *xp1 = text_xpix(x,canvas); *xp2 = *xp1+x->pixwidth; - *yp1 = text_ypix(x,canvas); *yp2 = *yp1+x->pixheight; -} - -#if 1 -static float graph_lastxpix, graph_lastypix; -static void graph_motion(void *z, t_floatarg dx, t_floatarg dy) { - t_canvas *x = (t_canvas *)z; - float newxpix = graph_lastxpix + dx, newypix = graph_lastypix + dy; - t_garray *a = (t_garray *)x->boxes->first(); - int oldx = int(0.5 + canvas_pixelstox(x, graph_lastxpix)); - int newx = int(0.5 + canvas_pixelstox(x, newxpix)); - float oldy = canvas_pixelstoy(x, graph_lastypix); - float newy = canvas_pixelstoy(x, newypix); - graph_lastxpix = newxpix; - graph_lastypix = newypix; - // verify that the array is OK - if (!a || a->_class != garray_class) return; - int nelem; - t_float *vec; - if (!garray_getfloatarray(a, &nelem, &vec)) return; - if (oldx < 0) oldx = 0; else if (oldx >= nelem) oldx = nelem - 1; - if (newx < 0) newx = 0; else if (newx >= nelem) newx = nelem - 1; - if (oldx < newx - 1) {for (int i=oldx+1; i<=newx; i++) vec[i] = newy + (oldy-newy) * float(newx-i)/float(newx - oldx);} - else if (oldx > newx + 1) {for (int i=oldx-1; i>=newx; i--) vec[i] = newy + (oldy-newy) * float(newx-i)/float(newx - oldx);} - else vec[newx] = newy; - garray_redraw(a); -} -#endif - -/* functions to read and write canvases to files: canvas_savetofile() writes a root canvas to a "pd" file. - (Reading "pd" files is done simply by passing the contents to the pd message interpreter.) - Alternatively, the glist_read() and glist_write() functions read and write "data" from and to files - (reading reads into an existing canvas), using a file format as in the dialog window for data. */ -static t_class *declare_class; -void canvas_savedeclarationsto(t_canvas *x, t_binbuf *b); - -/* the following functions read "scalars" from a file into a canvas. */ -static int canvas_scanbinbuf(int natoms, t_atom *vec, int *p_indexout, int *p_next) { - int i; - int indexwas = *p_next; - *p_indexout = indexwas; - if (indexwas >= natoms) return 0; - for (i = indexwas; i < natoms && vec[i].a_type != A_SEMI; i++) {} - if (i >= natoms) *p_next = i; else *p_next = i+1; - return i-indexwas; -} -static int canvas_readscalar(t_canvas *x, int natoms, t_atom *vec, int *p_nextmsg, int selectit); -static void canvas_readerror(int natoms, t_atom *vec, int message, int nline, const char *s) { - error("%s",s); - startpost("line was:"); - postatom(nline, vec + message); - endpost(); -} - -/* fill in the contents of the scalar into the vector w. */ -static void canvas_readatoms(t_canvas *x, int natoms, t_atom *vec, int *p_nextmsg, t_symbol *tsym, t_word *w, int argc, t_atom *argv) { - t_template *t = template_findbyname(tsym); - if (!t) {error("%s: no such template", tsym->name); *p_nextmsg = natoms; return;} - word_restore(w, t, argc, argv); - int n = t->n; - for (int i=0; i<n; i++) { - if (t->vec[i].type == DT_ARRAY) { - t_array *a = w[i].w_array; - int elemsize = a->elemsize, nitems = 0; - t_symbol *arraytsym = t->vec[i].arraytemplate; - t_template *arraytemplate = template_findbyname(arraytsym); - if (!arraytemplate) error("%s: no such template", arraytsym->name); - else while (1) { - int message; - t_word *element; - int nline = canvas_scanbinbuf(natoms, vec, &message, p_nextmsg); - /* empty line terminates array */ - if (!nline) break; - array_resize(a, nitems + 1); - element = (t_word *)&a->vec[nitems*elemsize]; - canvas_readatoms(x, natoms, vec, p_nextmsg, arraytsym, element, nline, vec + message); - nitems++; - } - } else if (t->vec[i].type == DT_CANVAS) { - while (1) { - if (!canvas_readscalar(w->w_canvas, natoms, vec, p_nextmsg, 0)) break; - } - } - } -} - -static int canvas_readscalar(t_canvas *x, int natoms, t_atom *vec, int *p_nextmsg, int selectit) { - int nextmsg = *p_nextmsg; - //int wasvis = canvas_isvisible(x); - if (nextmsg >= natoms || vec[nextmsg].a_type != A_SYMBOL) { - if (nextmsg < natoms) post("stopping early: type %d", vec[nextmsg].a_type); - *p_nextmsg = natoms; return 0; - } - t_symbol *ts = canvas_makebindsym(vec[nextmsg].a_symbol); - *p_nextmsg = nextmsg + 1; - t_template *t = template_findbyname(ts); - if (!t) {error("%s: no such template", ts->name); *p_nextmsg = natoms; return 0;} - t_scalar *sc = scalar_new(x, ts); - if (!sc) {error("couldn't create scalar \"%s\"", ts->name); *p_nextmsg = natoms; return 0;} - //if (wasvis) canvas_getcanvas(x)->mapped = 0; - canvas_add(x,sc); - int message; - int nline = canvas_scanbinbuf(natoms, vec, &message, p_nextmsg); - canvas_readatoms(x, natoms, vec, p_nextmsg, ts, sc->v, nline, vec + message); - //if (wasvis) canvas_getcanvas(x)->mapped = 1; - gobj_changed(sc,0);//is this necessary? - return 1; -} - -static void canvas_readfrombinbuf(t_canvas *x, t_binbuf *b, const char *filename, int selectem) { - int message, nextmsg = 0; - int natoms = binbuf_getnatom(b); - t_atom *vec = binbuf_getvec(b); - /* check for file type */ - int nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); - if (nline!=1 && vec[message].a_type != A_SYMBOL && strcmp(vec[message].a_symbol->name, "data")) { - error("%s: file apparently of wrong type", filename); - binbuf_free(b); - return; - } - /* read in templates and check for consistency */ - while (1) { - t_template *newt, *existt; - t_atom *targs = (t_atom *)getbytes(0); - int ntargs = 0; - nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); - if (nline < 2) break; - else if (nline > 2) canvas_readerror(natoms, vec, message, nline, "extra items ignored"); - else if (vec[message].a_type != A_SYMBOL || strcmp(vec[message].a_symbol->name, "template") || - vec[message+1].a_type != A_SYMBOL) { - canvas_readerror(natoms, vec, message, nline, "bad template header"); - continue; - } - t_symbol *tsym = canvas_makebindsym(vec[message + 1].a_symbol); - while (1) { - nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); - if (nline!=2 && nline!=3) break; - int newnargs = ntargs + nline; - targs = realloc2(targs,newnargs); - targs[ntargs] = vec[message]; - targs[ntargs+1] = vec[message+1]; - if (nline==3) targs[ntargs+2] = vec[message+2]; - ntargs = newnargs; - } - newt = template_new(tsym, ntargs, targs); - free(targs); - existt = template_findbyname(tsym); - if (!existt) {error("%s: template not found in current patch", tsym->name); template_free(newt); return;} - if (!template_match(existt, newt)) { - error("%s: template doesn't match current one", tsym->name); - template_free(newt); - return; - } - template_free(newt); - } - while (nextmsg < natoms) canvas_readscalar(x, natoms, vec, &nextmsg, selectem); -} - -static void canvas_doread(t_canvas *x, t_symbol *filename, t_symbol *format, int clearme) { - t_binbuf *b = binbuf_new(); - t_canvas *canvas = canvas_getcanvas(x); - int wasvis = canvas_isvisible(canvas); - int cr = strcmp(format->name, "cr")==0; - if (!cr && *format->name) error("unknown flag: %s", format->name); - /* flag 2 means eval continuously. this is required to autodetect the syntax */ - if (binbuf_read_via_path(b, filename->name, canvas_getdir(canvas)->name, cr|2)) { - error("read failed"); - binbuf_free(b); - return; - } - if (wasvis) canvas_vis(canvas, 0); - if (clearme) canvas_clear(x); - /* canvas_readfrombinbuf(x, b, filename->name, 0); */ /* what's this for? */ - if (wasvis) canvas_vis(canvas, 1); - binbuf_free(b); -} - -static void canvas_read( t_canvas *x, t_symbol *filename, t_symbol *format) {canvas_doread(x,filename,format,1);} -static void canvas_mergefile(t_canvas *x, t_symbol *filename, t_symbol *format) {canvas_doread(x,filename,format,0);} - -/* read text from a "properties" window, in answer to scalar_properties(). - We try to restore the object; if successful - we delete the scalar and put the new thing in its place on the list. */ -void canvas_dataproperties(t_canvas *x, t_scalar *sc, t_binbuf *b) { -// t_gobj *oldone = 0; -// t_gobj *newone = 0; - x->boxes->remove_by_value(sc); -// if (!newone) {error("couldn't update properties (perhaps a format problem?)"); return;} -// if (!oldone) {bug("data_properties: couldn't find old element"); return;} - canvas_readfrombinbuf(x, b, "properties dialog", 0); -} - -static void canvas_doaddtemplate(t_symbol *tsym, int *p_ntemplates, t_symbol ***p_templatevec) { - int n = *p_ntemplates; - t_symbol **templatevec = *p_templatevec; - for (int i=0; i < n; i++) if (templatevec[i] == tsym) return; - templatevec = realloc2(templatevec,n+1); - templatevec[n] = tsym; - *p_templatevec = templatevec; - *p_ntemplates = n+1; -} - -static void canvas_writelist(t_gobj *y, t_binbuf *b); - -static void canvas_writescalar(t_symbol *tsym, t_word *w, t_binbuf *b, int amarrayelement) { - t_template *t = template_findbyname(tsym); - t_atom *a = (t_atom *)getbytes(0); - int n = t->n; - if (!amarrayelement) { - t_atom templatename; - SETSYMBOL(&templatename, gensym(tsym->name + 3)); - binbuf_add(b, 1, &templatename); - } - if (!t) bug("canvas_writescalar"); - /* write the atoms (floats and symbols) */ - int natom = 0; - for (int i=0; i<n; i++) { - int ty = t->vec[i].type; - if (ty==DT_FLOAT || ty==DT_SYMBOL) { - a = realloc2(a,natom+1); - if (t->vec[i].type == DT_FLOAT) SETFLOAT( a + natom, w[i].w_float); - else SETSYMBOL(a + natom, w[i].w_symbol); - natom++; - } - } - /* array elements have to have at least something */ - if (natom == 0 && amarrayelement) {SETSYMBOL(a + natom, &s_bang); natom++;} - binbuf_add(b, natom, a); - binbuf_addsemi(b); - free(a); - for (int i=0; i<n; i++) { - if (t->vec[i].type == DT_ARRAY) { - t_array *a = w[i].w_array; - int elemsize = a->elemsize, nitems = a->n; - t_symbol *arraytsym = t->vec[i].arraytemplate; - for (int j = 0; j < nitems; j++) canvas_writescalar(arraytsym, (t_word *)&a->vec[elemsize*j], b, 1); - binbuf_addsemi(b); - } else if (t->vec[i].type == DT_CANVAS) { - canvas_writelist(w->w_canvas->boxes->first(), b); - binbuf_addsemi(b); - } - } -} - -static void canvas_writelist(t_gobj *y, t_binbuf *b) { - for (; y; y = y->next()) if (y->_class==scalar_class) { - t_scalar *z = (t_scalar *)y; - canvas_writescalar(z->t, z->v, b, 0); - } -} - -static void canvas_addtemplatesforlist(t_gobj *y, int *p_ntemplates, t_symbol ***p_templatevec); - -static void canvas_addtemplatesforscalar(t_symbol *tsym, t_word *w, int *p_ntemplates, t_symbol ***p_templatevec) { - t_template *t = template_findbyname(tsym); - canvas_doaddtemplate(tsym, p_ntemplates, p_templatevec); - if (!t) {bug("canvas_addtemplatesforscalar"); return;} - t_dataslot *ds = t->vec; - for (int i=t->n; i--; ds++, w++) { - if (ds->type == DT_ARRAY) { - t_array *a = w->w_array; - int elemsize = a->elemsize, nitems = a->n; - t_symbol *arraytsym = ds->arraytemplate; - canvas_doaddtemplate(arraytsym, p_ntemplates, p_templatevec); - for (int j=0; j<nitems; j++) - canvas_addtemplatesforscalar(arraytsym, (t_word *)&a->vec[elemsize*j], p_ntemplates, p_templatevec); - } else if (ds->type == DT_CANVAS) - canvas_addtemplatesforlist(w->w_canvas->boxes->first(), p_ntemplates, p_templatevec); - } -} - -static void canvas_addtemplatesforlist(t_gobj *y, int *p_ntemplates, t_symbol ***p_templatevec) { - for (; y; y = y->next()) if (y->_class == scalar_class) { - t_scalar *z = (t_scalar *)y; - canvas_addtemplatesforscalar(z->t, z->v, p_ntemplates, p_templatevec); - } -} - -static t_binbuf *canvas_writetobinbuf(t_canvas *x) { - t_symbol **templatevec = (t_symbol **)getbytes(0); - int ntemplates = 0; - t_binbuf *b = binbuf_new(); - canvas_each(y,x) if (y->_class==scalar_class) { - t_scalar *s = (t_scalar *)y; - canvas_addtemplatesforscalar(s->t, s->v, &ntemplates, &templatevec); - } - binbuf_addv(b,"t;","data"); - for (int i=0; i<ntemplates; i++) { - t_template *t = template_findbyname(templatevec[i]); - int m = t->n; - /* drop "pd-" prefix from template symbol to print it: */ - binbuf_addv(b,"tt;","template",templatevec[i]->name + 3); - for (int j=0; j<m; j++) { - t_symbol *type; - switch (t->vec[j].type) { - case DT_FLOAT: type = &s_float; break; - case DT_SYMBOL: type = &s_symbol; break; - case DT_ARRAY: type = gensym("array"); break; - case DT_CANVAS: type = &s_list; break; - default: type = &s_float; bug("canvas_write"); - } - if (t->vec[j].type == DT_ARRAY) - binbuf_addv(b,"sst;", type, t->vec[j].name, t->vec[j].arraytemplate->name + 3); - else binbuf_addv(b,"ss;", type, t->vec[j].name); - } - binbuf_addsemi(b); - } - binbuf_addsemi(b); - /* now write out the objects themselves */ - canvas_each(y,x) if (y->_class==scalar_class) { - t_scalar *z = (t_scalar *)y; - canvas_writescalar(z->t, z->v, b, 0); - } - return b; -} - -static void canvas_write(t_canvas *x, t_symbol *filename, t_symbol *format) { - t_canvas *canvas = canvas_getcanvas(x); - char *buf = canvas_makefilename(canvas,filename->name,0,0); - int cr = strcmp(format->name, "cr")==0; - if (!cr && *format->name) error("canvas_write: unknown flag: %s", format->name); - t_binbuf *b = canvas_writetobinbuf(x); - if (b) { - if (binbuf_write(b, buf, "", cr)) error("%s: write failed", filename->name); - binbuf_free(b); - } - free(buf); -} - -/* ------ functions to save and restore canvases (patches) recursively. ----*/ - -/* save to a binbuf, called recursively; cf. canvas_savetofile() which saves the document, and is only called on root canvases. */ -void canvas_savecontainerto(t_canvas *x, t_binbuf *b) { - /* have to go to original binbuf to find out how we were named. */ - t_binbuf *bz = binbuf_new(); - t_symbol *patchsym = &s_; - if (x->binbuf) { - binbuf_addbinbuf(bz, x->binbuf); - patchsym = atom_getsymbolarg(1, binbuf_getnatom(bz), binbuf_getvec(bz)); - binbuf_free(bz); - } - int x1=x->screenx1, xs=x->screenx2-x1; - int y1=x->screeny1, ys=x->screeny2-y1; - binbuf_addv(b,"ttiiii","#N","canvas",x1,y1,xs,ys); - if (x->dix->canvas && !x->env) { /* subpatch */ - binbuf_addv(b, "si;", (patchsym != &s_ ? patchsym: gensym("(subpatch)")), x->havewindow); - } else { /* root or abstraction */ - binbuf_addv(b, "i;", (int)x->font); - canvas_savedeclarationsto(x, b); - } -} - -static void canvas_savecoordsto(t_canvas *x, t_binbuf *b) { - /* if everything is the default, skip saving this line */ - if (!x->gop && x->x1==0 && x->y1==0 && x->x2==1 && x->y2==1 && x->pixwidth==0 && x->pixheight==0) return; - /* if we have a graph-on-parent rectangle, we're new style. The format is arranged so - that old versions of Pd can at least do something with it. - otherwise write in 0.38-compatible form. */ - binbuf_addv(b,"ttffffffi","#X","coords", x->x1,x->y1,x->x2,x->y2, (float)x->pixwidth,(float)x->pixheight, x->gop?x->hidetext?2:1:0); - if (x->goprect) binbuf_addv(b, "ff", (float)x->xmargin, (float)x->ymargin); - binbuf_addv(b,";"); -} - -/* get the index of a gobj in a canvas. If y is zero, return the total number of objects. */ -int canvas_oldindex(t_canvas *x, t_gobj *y) { - int i=0; - canvas_each(y2,x) {if (y2==y) break; else i++;} - return i; -} - -static void canvas_saveto(t_canvas *x, t_binbuf *b) { - canvas_savecontainerto(x,b); - canvas_each(y,x) gobj_save(y, b); - canvas_wires_each(oc,t,x) { - int from = canvas_oldindex(x,t.from); - int to = canvas_oldindex(x,t.to); - binbuf_addv(b, "ttiiii;","#X","connect", from, t.outlet, to, t.inlet); - appendix_save(oc,b); - } - canvas_savecoordsto(x,b); -} - -/* call this recursively to collect all the template names for a canvas or for the selection. */ -static void canvas_collecttemplatesfor(t_canvas *x, int *ntemplatesp, t_symbol ***templatevecp) { - canvas_each(y,x) { - if (y->_class==scalar_class) { - t_scalar *z = (t_scalar *)y; - canvas_addtemplatesforscalar(z->t, z->v, ntemplatesp, templatevecp); - } else if (y->_class==canvas_class) { - canvas_collecttemplatesfor((t_canvas *)y, ntemplatesp, templatevecp); - } - } -} - -/* save the templates needed by a canvas to a binbuf. */ -static void canvas_savetemplatesto(t_canvas *x, t_binbuf *b) { - t_symbol **templatevec = (t_symbol **)getbytes(0); - int ntemplates = 0; - canvas_collecttemplatesfor(x, &ntemplates, &templatevec); - for (int i=0; i < ntemplates; i++) { - t_template *t = template_findbyname(templatevec[i]); - if (!t) { - bug("canvas_savetemplatesto"); - continue; - } - /* drop "pd-" prefix from template symbol to print */ - binbuf_addv(b,"ttt","#N","struct",templatevec[i]->name+3); - for (int j=0; j<t->n; j++) { - t_symbol *type; - switch (t->vec[j].type) { - case DT_FLOAT: type = &s_float; break; - case DT_SYMBOL: type = &s_symbol; break; - case DT_ARRAY: type = gensym("array"); break; - case DT_CANVAS: type = &s_list; break; - default: type = &s_float; bug("canvas_write"); - } - binbuf_addv(b,"ss",type,t->vec[j].name); - if (t->vec[j].type == DT_ARRAY) binbuf_addv(b, "t", t->vec[j].arraytemplate->name + 3); - } - binbuf_addsemi(b); - } -} - -/* save a "root" canvas to a file; cf. canvas_saveto() which saves the body (and which is called recursively.) */ -static void canvas_savetofile(t_canvas *x, t_symbol *filename, t_symbol *dir) { - t_binbuf *b = binbuf_new(); - int dsp_status = canvas_suspend_dsp(); - canvas_savetemplatesto(x, b); - canvas_saveto(x, b); - if (!binbuf_write(b, filename->name, dir->name, 0)) { - /* if not an abstraction, reset title bar and directory */ - if (!x->dix->canvas) canvas_rename(x, filename, dir); - post("saved to: %s/%s", dir->name, filename->name); - canvas_reload(filename,dir,x); - } - binbuf_free(b); - canvas_resume_dsp(dsp_status); -} - -/////////////////////////////////////////////////////////////////////////// -// from g_io.c - -/* graphical inlets and outlets, both for control and signals. */ -/* iohannes added multiple samplerates support in vinlet/voutlet */ - -extern "C" void signal_setborrowed(t_signal *sig, t_signal *sig2); -extern "C" void signal_makereusable(t_signal *sig); -extern "C" void inlet_sethelp(t_inlet* i,t_symbol* s); - -/* ------------------------- vinlet -------------------------- */ -t_class *vinlet_class; - -struct t_vinlet : t_object { - t_canvas *canvas; - t_inlet *inlet; - int bufsize; - t_float *buf; /* signal buffer; zero if not a signal */ - t_float *endbuf; - t_float *fill; - t_float *read; - int hop; - /* if not reblocking, the next slot communicates the parent's inlet signal from the prolog to the DSP routine: */ - t_signal *directsignal; - t_resample updown; /* IOhannes */ -}; - -static void *vinlet_new(t_symbol *s) { - t_vinlet *x = (t_vinlet *)pd_new(vinlet_class); - x->canvas = canvas_getcurrent(); - x->inlet = canvas_addinlet(x->canvas,x,0,s); - x->bufsize = 0; - x->buf = 0; - outlet_new(x, 0); - return x; -} - -static void vinlet_bang(t_vinlet *x) {x->outlet->send();} -static void vinlet_pointer(t_vinlet *x, t_gpointer *v) {x->outlet->send(v);} -static void vinlet_float(t_vinlet *x, t_float v) {x->outlet->send(v);} -static void vinlet_symbol(t_vinlet *x, t_symbol *v) {x->outlet->send(v);} -static void vinlet_list( t_vinlet *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send( argc,argv);} -static void vinlet_anything(t_vinlet *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(s,argc,argv);} - -static void vinlet_free(t_vinlet *x) { - canvas_rminlet(x->canvas, x->inlet); - resample_free(&x->updown); -} - -t_inlet *vinlet_getit(t_pd *x) { - if (pd_class(x) != vinlet_class) bug("vinlet_getit"); - return ((t_vinlet *)x)->inlet; -} - -/* ------------------------- signal inlet -------------------------- */ -int vinlet_issignal(t_vinlet *x) {return x->buf!=0;} - -t_int *vinlet_perform(t_int *w) { - PERFORM3ARGS(t_vinlet *,x, t_float *,out, int,n); - t_float *in = x->read; - while (n--) *out++ = *in++; - if (in == x->endbuf) in = x->buf; - x->read = in; - return w+4; -} -/* tb: vectorized */ -t_int *vinlet_perf8(t_int *w) { - PERFORM3ARGS(t_vinlet *,x, t_float *,out, int,n); - t_float *in = x->read; - for (; n; n -= 8, in += 8, out += 8) { - out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; - out[4] = in[4]; out[5] = in[5]; out[6] = in[6]; out[7] = in[7]; - } - if (in == x->endbuf) in = x->buf; - x->read = in; - return w+4; -} -/* T.Grill: SIMD version */ -t_int *vinlet_perfsimd(t_int *w) { - PERFORM3ARGS(t_vinlet *,x, t_float *,out, int,n); - t_float *in = x->read; - copyvec_simd(out,in,n); - if (in == x->endbuf) in = x->buf; - x->read = in; - return w+4; -} -static void vinlet_dsp(t_vinlet *x, t_signal **sp) { - if (!x->buf) return; /* no buffer means we're not a signal inlet */ - t_signal *outsig = sp[0]; - if (x->directsignal) signal_setborrowed(sp[0], x->directsignal); - else { - const int vecsize = outsig->vecsize; - /* if the outsig->v is aligned the x->read will also be... */ - if(vecsize&7) dsp_add(vinlet_perform, 3, x, outsig->v,vecsize); - else if(SIMD_CHECK1(outsig->n,outsig->v)) - dsp_add(vinlet_perfsimd, 3, x, outsig->v,vecsize); - else dsp_add(vinlet_perf8, 3, x, outsig->v,vecsize); - x->read = x->buf; - } -} -/* prolog code: loads buffer from parent patch */ -t_int *vinlet_doprolog(t_int *w) { - PERFORM3ARGS(t_vinlet *,x, t_float *,in, int,n); - t_float *out = x->fill; - if (out == x->endbuf) { - t_float *f1 = x->buf, *f2 = x->buf + x->hop; - int nshift = x->bufsize - x->hop; - out -= x->hop; - while (nshift--) *f1++ = *f2++; - } - while (n--) *out++ = *in++; - x->fill = out; - return w+4; -} - -extern "C" int inlet_getsignalindex(t_inlet *x); - -/* set up prolog DSP code */ -void vinlet_dspprolog(t_vinlet *x, t_signal **parentsigs, int myvecsize, int calcsize, int phase, int period, -int frequency, int downsample, int upsample, int reblock, int switched) { - t_signal *insig; - x->updown.downsample = downsample; - x->updown.upsample = upsample; - /* if the "reblock" flag is set, arrange to copy data in from the parent. */ - if (reblock) { - int parentvecsize, bufsize, oldbufsize, prologphase; - int re_parentvecsize; /* resampled parentvectorsize: IOhannes */ - /* this should never happen: */ - if (!x->buf) return; - /* the prolog code counts from 0 to period-1; the - phase is backed up by one so that AFTER the prolog code - runs, the "fill" phase is in sync with the "read" phase. */ - prologphase = (phase - 1) & (period - 1); - if (parentsigs) { - insig = parentsigs[inlet_getsignalindex(x->inlet)]; - parentvecsize = insig->vecsize; - re_parentvecsize = parentvecsize * upsample / downsample; - } else { - insig = 0; - parentvecsize = 1; - re_parentvecsize = 1; - } - bufsize = max(re_parentvecsize,myvecsize); - oldbufsize = x->bufsize; - if (bufsize != oldbufsize) { - t_float *buf = x->buf; - buf = (t_float *)resizealignedbytes(buf,oldbufsize * sizeof(*buf), bufsize * sizeof(*buf)); - memset((char *)buf, 0, bufsize * sizeof(*buf)); - x->bufsize = bufsize; - x->endbuf = buf + bufsize; - x->buf = buf; - } - if (parentsigs) { - /* IOhannes { */ - x->hop = period * re_parentvecsize; - x->fill = x->endbuf - (x->hop - prologphase * re_parentvecsize); - if (upsample * downsample == 1) - dsp_add(vinlet_doprolog, 3, x, insig->v, re_parentvecsize); - else { - resamplefrom_dsp(&x->updown, insig->v, parentvecsize, re_parentvecsize, x->updown.method); - dsp_add(vinlet_doprolog, 3, x, x->updown.v, re_parentvecsize); - } - /* } IOhannes */ - /* if the input signal's reference count is zero, we have to free it here because we didn't in ugen_doit(). */ - if (!insig->refcount) signal_makereusable(insig); - } else memset((char *)x->buf, 0, bufsize * sizeof(*x->buf)); - x->directsignal = 0; - } else { - /* no reblocking; in this case our output signal is "borrowed" and merely needs to be pointed to the real one. */ - x->directsignal = parentsigs[inlet_getsignalindex(x->inlet)]; - } -} - -static void *vinlet_newsig(t_symbol *s) { - t_vinlet *x = (t_vinlet *)pd_new(vinlet_class); - x->canvas = canvas_getcurrent(); - x->inlet = canvas_addinlet(x->canvas,x,&s_signal,s); - x->endbuf = x->buf = (t_float *)getalignedbytes(0); - x->bufsize = 0; - x->directsignal = 0; - outlet_new(x, &s_signal); - resample_init(&x->updown); - /* this should be thought over: it might prove hard to provide consistency between labeled up- & downsampling methods - maybe indices would be better... - up till now we provide several upsampling methods and 1 single downsampling method (no filtering !) */ - if (s) { - char c=*s->name; - switch(c) { - case'h':case'H':x->updown.method=RESAMPLE_HOLD; break; /* up: sample and hold */ - case'l':case'L':x->updown.method=RESAMPLE_LINEAR; break; /* up: linear interpolation */ - case'b':case'B':x->updown.method=RESAMPLE_BLOCK; break; /* down: ignore the 2nd half of the block */ - default: x->updown.method=RESAMPLE_ZERO; /* up: zero-padding */ - } - } - return x; -} - -static void vinlet_setup() { - t_class *c = vinlet_class = class_new2("inlet",vinlet_new,vinlet_free,sizeof(t_vinlet),CLASS_NOINLET,"S"); - class_addcreator2("inlet~",vinlet_newsig,"S"); - class_addbang( c, vinlet_bang); - class_addpointer( c, vinlet_pointer); - class_addfloat( c, vinlet_float); - class_addsymbol( c, vinlet_symbol); - class_addlist( c, vinlet_list); - class_addanything(c, vinlet_anything); - class_addmethod2( c, vinlet_dsp,"dsp",""); - class_sethelpsymbol(c, gensym("pd")); -} - -/* ------------------------- voutlet -------------------------- */ - -t_class *voutlet_class; - -struct t_voutlet : t_object { - t_canvas *canvas; - t_outlet *parentoutlet; - int bufsize; - t_float *buf; /* signal buffer; zero if not a signal */ - t_float *endbuf; - t_float *empty; /* next to read out of buffer in epilog code */ - t_float *write; /* next to write in to buffer */ - int hop; /* hopsize */ - /* vice versa from the inlet, if we don't block, this holds the - parent's outlet signal, valid between the prolog and the dsp setup functions. */ - t_signal *directsignal; - /* and here's a flag indicating that we aren't blocked but have to do a copy (because we're switched). */ - char justcopyout; - t_resample updown; /* IOhannes */ -}; - -static void *voutlet_new(t_symbol *s) { - t_voutlet *x = (t_voutlet *)pd_new(voutlet_class); - x->canvas = canvas_getcurrent(); - x->parentoutlet = canvas_addoutlet(x->canvas,x,0); - inlet_new(x,x,0,0); - x->bufsize = 0; - x->buf = 0; - return x; -} - -static void voutlet_bang( t_voutlet *x) {x->parentoutlet->send( );} -static void voutlet_pointer( t_voutlet *x, t_gpointer *v) {x->parentoutlet->send(v);} -static void voutlet_float( t_voutlet *x, t_float v) {x->parentoutlet->send(v);} -static void voutlet_symbol( t_voutlet *x, t_symbol *v) {x->parentoutlet->send(v);} -static void voutlet_list( t_voutlet *x, t_symbol *s, int argc, t_atom *argv) {x->parentoutlet->send( argc,argv);} -static void voutlet_anything(t_voutlet *x, t_symbol *s, int argc, t_atom *argv) {x->parentoutlet->send(s,argc,argv);} - -static void voutlet_free(t_voutlet *x) {canvas_rmoutlet(x->canvas, x->parentoutlet); resample_free(&x->updown);} -t_outlet *voutlet_getit(t_pd *x) { - if (pd_class(x) != voutlet_class) bug("voutlet_getit"); - return ((t_voutlet *)x)->parentoutlet; -} - -int voutlet_issignal(t_voutlet *x) {return x->buf!=0;} - -/* LATER optimize for non-overlapped case where the "+=" isn't needed */ -t_int *voutlet_perform(t_int *w) { - PERFORM3ARGS(t_voutlet *,x, t_float *,in, int,n); - t_float *out = x->write, *outwas = out, *end = x->endbuf; - while (n--) { - *out++ += *in++; - if (out == end) out = x->buf; - } - outwas += x->hop; - if (outwas >= end) outwas = x->buf; - x->write = outwas; - return w+4; -} -/* epilog code for blocking: write buffer to parent patch */ -static t_int *voutlet_doepilog(t_int *w) { - PERFORM3ARGS(t_voutlet *,x, t_float *,out, int,n); - t_float *in = x->empty; - if (x->updown.downsample != x->updown.upsample) out = x->updown.v; /* IOhannes */ - for (; n--; in++) *out++ = *in, *in = 0; - if (in == x->endbuf) in = x->buf; - x->empty = in; - return w+4; -} - -/* IOhannes { */ -static t_int *voutlet_doepilog_resampling(t_int *w) { - PERFORM2ARGS(t_voutlet *,x, int,n); - t_float *in = x->empty; - t_float *out = x->updown.v; /* IOhannes */ - for (; n--; in++) *out++ = *in, *in = 0; - if (in == x->endbuf) in = x->buf; - x->empty = in; - return w+3; -} -/* } IOhannes */ -extern "C" int outlet_getsignalindex(t_outlet *x); - -/* prolog for outlets -- store pointer to the outlet on the parent, which, if "reblock" is false, will want to refer - back to whatever we see on our input during the "dsp" method called later. */ -void voutlet_dspprolog(t_voutlet *x, t_signal **parentsigs, int myvecsize, int calcsize, int phase, int period, -int frequency, int downsample, int upsample, int reblock, int switched) { - x->updown.downsample=downsample; x->updown.upsample=upsample; /* IOhannes */ - x->justcopyout = (switched && !reblock); - if (reblock) { - x->directsignal = 0; - } else { - if (!parentsigs) bug("voutlet_dspprolog"); - x->directsignal = parentsigs[outlet_getsignalindex(x->parentoutlet)]; - } -} - -static void voutlet_dsp(t_voutlet *x, t_signal **sp) { - if (!x->buf) return; - t_signal *insig = sp[0]; - if (x->justcopyout) dsp_add_copy(insig->v, x->directsignal->v, insig->n); - else if (x->directsignal) { - /* if we're just going to make the signal available on the parent patch, hand it off to the parent signal. */ - /* this is done elsewhere--> sp[0]->refcount++; */ - signal_setborrowed(x->directsignal, sp[0]); - } else dsp_add(voutlet_perform, 3, x, insig->v, insig->n); -} - -/* set up epilog DSP code. If we're reblocking, this is the - time to copy the samples out to the containing object's outlets. - If we aren't reblocking, there's nothing to do here. */ -void voutlet_dspepilog(t_voutlet *x, t_signal **parentsigs, -int myvecsize, int calcsize, int phase, int period, int frequency, int downsample, int upsample, int reblock, int switched) { - if (!x->buf) return; /* this shouldn't be necesssary... */ - x->updown.downsample=downsample; - x->updown.upsample=upsample; /* IOhannes */ - if (reblock) { - t_signal *outsig; - int parentvecsize, bufsize, oldbufsize; - int re_parentvecsize; /* IOhannes */ - int bigperiod, epilogphase, blockphase; - if (parentsigs) { - outsig = parentsigs[outlet_getsignalindex(x->parentoutlet)]; - parentvecsize = outsig->vecsize; - re_parentvecsize = parentvecsize * upsample / downsample; - } else { - outsig = 0; - parentvecsize = 1; - re_parentvecsize = 1; - } - bigperiod = myvecsize/re_parentvecsize; /* IOhannes */ - if (!bigperiod) bigperiod = 1; - epilogphase = phase & (bigperiod - 1); - blockphase = (phase + period - 1) & (bigperiod - 1) & (- period); - bufsize = re_parentvecsize; /* IOhannes */ - if (bufsize < myvecsize) bufsize = myvecsize; - if (bufsize != (oldbufsize = x->bufsize)) { - t_float *buf = x->buf; - buf = (t_float *)resizealignedbytes(buf,oldbufsize * sizeof(*buf),bufsize * sizeof(*buf)); - memset((char *)buf, 0, bufsize * sizeof(*buf)); - x->bufsize = bufsize; - x->endbuf = buf + bufsize; - x->buf = buf; - } - /* IOhannes: { */ - if (re_parentvecsize * period > bufsize) bug("voutlet_dspepilog"); - x->write = x->buf + re_parentvecsize * blockphase; - if (x->write == x->endbuf) x->write = x->buf; - if (period == 1 && frequency > 1) x->hop = re_parentvecsize / frequency; - else x->hop = period * re_parentvecsize; - /* } IOhannes */ - if (parentsigs) { - /* set epilog pointer and schedule it */ - /* IOhannes { */ - x->empty = x->buf + re_parentvecsize * epilogphase; - if (upsample*downsample==1) - dsp_add(voutlet_doepilog, 3, x, outsig->v, re_parentvecsize); - else { - dsp_add(voutlet_doepilog_resampling, 2, x, re_parentvecsize); - resampleto_dsp(&x->updown, outsig->v, re_parentvecsize, parentvecsize, x->updown.method); - } - /* } IOhannes */ - } - } - /* if we aren't blocked but we are switched, the epilog code just - copies zeros to the output. In this case the blocking code actually jumps over the epilog if the block is running. */ - else if (switched) { - if (parentsigs) { - t_signal *outsig = parentsigs[outlet_getsignalindex(x->parentoutlet)]; - dsp_add_zero(outsig->v, outsig->n); - } - } -} - -static void *voutlet_newsig(t_symbol *s) { - t_voutlet *x = (t_voutlet *)pd_new(voutlet_class); - x->canvas = canvas_getcurrent(); - x->parentoutlet = canvas_addoutlet(x->canvas,x,&s_signal); - inlet_new(x,x,&s_signal,&s_signal); - x->endbuf = x->buf = (t_float *)getalignedbytes(0); - x->bufsize = 0; - resample_init(&x->updown); - /* this should be though over: - * it might prove hard to provide consistency between labeled up- & downsampling methods - * maybe indeces would be better... - * up till now we provide several upsampling methods and 1 single downsampling method (no filtering !) */ - if (s) { - char c=*s->name; - switch(c) { - case 'h': case 'H': x->updown.method=RESAMPLE_HOLD; break; /* up: sample and hold */ - case 'l': case 'L': x->updown.method=RESAMPLE_LINEAR; break; /* up: linear interpolation */ - case 'b': case 'B': x->updown.method=RESAMPLE_BLOCK; break; /* down: ignore the 2nd half of the block */ - default: x->updown.method=RESAMPLE_ZERO; /* up: zero-padding */ - } - } - return x; -} - -static void voutlet_setup() { - t_class *c = voutlet_class = class_new2("outlet",voutlet_new,voutlet_free,sizeof(t_voutlet),CLASS_NOINLET,"S"); - class_addcreator2("outlet~",voutlet_newsig,"S"); - class_addbang( c, voutlet_bang); - class_addpointer( c, voutlet_pointer); - class_addfloat( c, (t_method)voutlet_float); - class_addsymbol( c, voutlet_symbol); - class_addlist( c, voutlet_list); - class_addanything(c, voutlet_anything); - class_addmethod2( c, voutlet_dsp, "dsp", ""); - class_sethelpsymbol(c, gensym("pd")); -} - -/* This file defines the "scalar" object, which is not a text object, just a - "gobj". Scalars have templates which describe their structures, which can contain numbers, sublists, and arrays. - IOhannes changed the canvas_restore, so that it might accept $args as well (like "pd $0_test") - so you can make multiple & distinguishable templates; added Krzysztof Czajas fix to avoid crashing... */ -t_class *scalar_class; - -void word_init(t_word *wp, t_template *t, t_gpointer *gp) { - t_dataslot *datatypes = t->vec; - for (int i=0; i < t->n; i++, datatypes++, wp++) { - int type = datatypes->type; - if (type == DT_FLOAT) wp->w_float = 0; - else if (type == DT_SYMBOL) wp->w_symbol = &s_symbol; - else if (type == DT_ARRAY) wp->w_array = array_new(datatypes->arraytemplate, gp); - else if (type == DT_CANVAS) { - /* LATER test this and get it to work */ - wp->w_canvas = canvas_new(0,0,0,0); - } - } -} - -void word_restore(t_word *wp, t_template *t, int argc, t_atom *argv) { - t_dataslot *datatypes = t->vec; - for (int i=0; i<t->n; i++, datatypes++, wp++) { - int type = datatypes->type; - if (type == DT_FLOAT) { - float f=0; - if (argc) {f = atom_getfloat(argv); argv++; argc--;} - wp->w_float = f; - } else if (type == DT_SYMBOL) { - t_symbol *s=&s_; - if (argc) {s = atom_getsymbol(argv); argv++; argc--;} - wp->w_symbol = s; - } - } - if (argc) post("warning: word_restore: extra arguments"); -} - -void word_free(t_word *wp, t_template *t) { - t_dataslot *dt = t->vec; - for (int i=0; i<t->n; i++, dt++) { - if (dt->type == DT_ARRAY) pd_free(wp[i].w_array); - else if (dt->type == DT_CANVAS) pd_free(wp[i].w_canvas); - } -} - -static void gpointer_setcanvas(t_gpointer *gp, t_canvas *canvas, t_scalar *x); -static void gpointer_setarray(t_gpointer *gp, t_array *array, t_word *w); -static t_word *gpointer_word(t_gpointer *gp) {return gp->o->_class == array_class ? gp->w : gp->scalar->v;} -static t_canvas *gpointer_getcanvas(t_gpointer *gp) { - if (gp->o->_class != array_class) return gp->canvas; - return 0; /* FIXME */ -} -static t_scalar *gpointer_getscalar(t_gpointer *gp) { - if (gp->o->_class != array_class) return gp->scalar; - return 0; -} - -/* make a new scalar and add to the canvas. We create a "gp" here which will be used for array items to point back here. - This gp doesn't do reference counting or "validation" updates though; the parent won't go away without the contained - arrays going away too. The "gp" is copied out by value in the word_init() routine so we can throw our copy away. */ -t_scalar *scalar_new(t_canvas *owner, t_symbol *tsym) { - t_gpointer gp; - gpointer_init(&gp); - t_template *t = template_findbyname(tsym); - TEMPLATE_CHECK(tsym,0) - t_scalar *x = (t_scalar *)getbytes(sizeof(t_scalar) + (t->n - 1) * sizeof(*x->v)); - x->_class = scalar_class; - x->t = tsym; - gpointer_setcanvas(&gp, owner, x); - word_init(x->v, t, &gp); - return x; -} - -/* Pd method to create a new scalar, add it to a canvas, and initialize it from the message arguments. */ -int canvas_readscalar(t_canvas *x, int natoms, t_atom *vec, int *p_nextmsg, int selectit); -static void canvas_scalar(t_canvas *canvas, t_symbol *classname, t_int argc, t_atom *argv) { - t_symbol *tsym = canvas_makebindsym(atom_getsymbolarg(0, argc, argv)); - if (!template_findbyname(tsym)) {error("%s: no such template", atom_getsymbolarg(0, argc, argv)->name); return;} - int nextmsg; - t_binbuf *b = binbuf_new(); - binbuf_restore(b, argc, argv); - canvas_readscalar(canvas, binbuf_getnatom(b), binbuf_getvec(b), &nextmsg, 0); - binbuf_free(b); -} - -static void scalar_getbasexy(t_scalar *x, float *basex, float *basey) { - t_template *t = template_findbyname(x->t); - *basex = template_getfloat(t,&s_x,x->v,0); - *basey = template_getfloat(t,&s_y,x->v,0); -} - -/* -static void scalar_displace(t_gobj *z, t_canvas *canvas, int dx, int dy) { - t_scalar *x = (t_scalar *)z; - t_symbol *tsym = x->t; - t_template *t = template_findbyname(tsym); - t_symbol *zz; - int xonset, yonset, xtype, ytype, gotx, goty; - TEMPLATE_CHECK(tsym,) - gotx = template_find_field(t,&s_x,&xonset,&xtype,&zz); - if (gotx && (xtype != DT_FLOAT)) gotx = 0; - goty = template_find_field(t,&s_y,&yonset,&ytype,&zz); - if (goty && (ytype != DT_FLOAT)) goty = 0; - if (gotx) *(t_float *)(((char *)(x->v)) + xonset) += dx * (canvas_pixelstox(canvas, 1) - canvas_pixelstox(canvas, 0)); - if (goty) *(t_float *)(((char *)(x->v)) + yonset) += dy * (canvas_pixelstoy(canvas, 1) - canvas_pixelstoy(canvas, 0)); - scalar_redraw(x, canvas); -}*/ - -static void scalar_vis(t_gobj *z, t_canvas *owner, int vis) { - t_scalar *x = (t_scalar *)z; - t_template *t = template_findbyname(x->t); - t_canvas *templatecanvas = template_findcanvas(t); - float basex, basey; - scalar_getbasexy(x, &basex, &basey); - /* if we don't know how to draw it, make a small rectangle */ - if (!templatecanvas) { - if (vis) { - int x1 = canvas_xtopixels(owner, basex); - int y1 = canvas_ytopixels(owner, basey); - sys_vgui(".x%lx.c create rectangle %d %d %d %d -tags scalar%lx\n", - (long)canvas_getcanvas(owner), x1-1, y1-1, x1+1, y1+1, (long)x); - } else sys_vgui(".x%lx.c delete scalar%lx\n", (long)canvas_getcanvas(owner), (long)x); - return; - } - //canvas_each(y,templatecanvas) pd_getparentwidget(y)->w_parentvisfn(y,owner,x->v,t,basex,basey,vis); - //sys_unqueuegui(x); -} - -static void scalar_doredraw(t_gobj *client, t_canvas *canvas) { - scalar_vis(client, canvas, 0); - scalar_vis(client, canvas, 1); -} - -void scalar_redraw(t_scalar *x, t_canvas *canvas) { - //if (canvas_isvisible(canvas)) sys_queuegui(x, canvas, scalar_doredraw); -} - -#if 0 -int scalar_doclick(t_word *data, t_template *t, t_scalar *sc, t_array *ap, t_canvas *owner, -float xloc, float yloc, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_canvas *templatecanvas = template_findcanvas(t); - float basex = template_getfloat(t,&s_x,data,0); - float basey = template_getfloat(t,&s_y,data,0); - canvas_each(y,templatecanvas) { - int hit = pd_getparentwidget(y)->w_parentclickfn(y, owner, data, t, sc, ap, basex+xloc, basey+yloc, - xpix, ypix, shift, alt, dbl, doit); - if (hit) return hit; - }*/ - return 0; -} -#endif - -static int scalar_click(t_gobj *z, t_canvas *owner, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_scalar *x = (t_scalar *)z; - t_template *t = template_findbyname(x->t); - return scalar_doclick(x->v, t, x, 0, owner, 0, 0, xpix, ypix, shift, alt, dbl, doit); -} - -void canvas_writescalar(t_symbol *tsym, t_word *w, t_binbuf *b, int amarrayelement); - -static void scalar_save(t_gobj *z, t_binbuf *b) { - t_scalar *x = (t_scalar *)z; - t_binbuf *b2 = binbuf_new(); - canvas_writescalar(x->t, x->v, b2, 0); - binbuf_addv(b,"tt","#X","scalar"); - binbuf_addbinbuf(b, b2); - binbuf_addsemi(b); - binbuf_free(b2); -} - -/* -static void scalar_properties(t_gobj *z, t_canvas *owner) { - t_scalar *x = (t_scalar *)z; - char *buf, buf2[80]; - int bufsize; - t_binbuf *b; - b = canvas_writetobinbuf(owner, 0); - binbuf_gettext(b, &buf, &bufsize); - binbuf_free(b); - buf = realloc2(buf,bufsize+1); - buf[bufsize] = 0; - sprintf(buf2, "pdtk_data_dialog %%s {"); - sys_gui(buf); - sys_gui("}\n"); - free(buf); -} -*/ - -static void scalar_free(t_scalar *x) { - t_template *t = template_findbyname(x->t); - TEMPLATE_CHECK(x->t,) - word_free(x->v, t); - /* the "size" field in the class is zero, so Pd doesn't try to free us automatically (see pd_free()) */ - free(x); -} - -static void g_scalar_setup() { - scalar_class = class_new2("scalar",0,scalar_free,0,CLASS_GOBJ,""); - class_setsavefn(scalar_class, scalar_save); -} - -void array_redraw(t_array *a, t_canvas *canvas); - -/* -This file contains text objects you would put in a canvas to define a -template. Templates describe objects of type "array" (g_array.c) and "scalar" (g_scalar.c). */ -/* the structure of a "struct" object (also the obsolete "gtemplate" you get when using the name "template" in a box.) */ -struct t_gtemplate : t_object { - t_template *t; - t_canvas *owner; - t_symbol *sym; - t_gtemplate *next; - int argc; - t_atom *argv; -}; - -static void template_conformarray(t_template *tfrom, t_template *tto, int *conformaction, t_array *a); -static void template_conformcanvas(t_template *tfrom, t_template *tto, int *conformaction, t_canvas *canvas); -static t_class *gtemplate_class; -static t_class *template_class; - -/* there's a pre-defined "float" template. LATER should we bind this to a symbol such as "pd-float"??? */ - -/* return true if two dataslot definitions match */ -static int dataslot_matches(t_dataslot *ds1, t_dataslot *ds2, int nametoo) { - return (!nametoo || ds1->name == ds2->name) && ds1->type == ds2->type && - (ds1->type != DT_ARRAY || ds1->arraytemplate == ds2->arraytemplate); -} - -/* -- templates, the active ingredient in gtemplates defined below. ------- */ - -static t_template *template_new(t_symbol *tsym, int argc, t_atom *argv) { - t_template *x = (t_template *)pd_new(template_class); - x->n = 0; - x->vec = (t_dataslot *)getbytes(0); - while (argc > 0) { - int newtype, oldn, newn; - t_symbol *newname, *newarraytemplate = &s_, *newtypesym; - if (argc < 2 || argv[0].a_type != A_SYMBOL || argv[1].a_type != A_SYMBOL) goto bad; - newtypesym = argv[0].a_symbol; - newname = argv[1].a_symbol; - if (newtypesym == &s_float) newtype = DT_FLOAT; - else if (newtypesym == &s_symbol) newtype = DT_SYMBOL; - else if (newtypesym == &s_list) newtype = DT_CANVAS; - else if (newtypesym == gensym("array")) { - if (argc < 3 || argv[2].a_type != A_SYMBOL) {error("array lacks element template or name"); goto bad;} - newarraytemplate = canvas_makebindsym(argv[2].a_symbol); - newtype = DT_ARRAY; - argc--; - argv++; - } else {error("%s: no such type", newtypesym->name); goto bad;} - newn = (oldn = x->n) + 1; - x->vec = realloc2(x->vec,newn); - x->n = newn; - x->vec[oldn].type = newtype; - x->vec[oldn].name = newname; - x->vec[oldn].arraytemplate = newarraytemplate; - bad: - argc -= 2; argv += 2; - } - x->sym = tsym; - if (tsym->name) pd_bind(x,x->sym); - return x; -} - -int template_size(t_template *x) {return x->n * sizeof(t_word);} - -int template_find_field(t_template *x, t_symbol *name, int *p_onset, int *p_type, t_symbol **p_arraytype) { - if (!x) {bug("template_find_field"); return 0;} - for (int i = 0; i<x->n; i++) if (x->vec[i].name == name) { - if (p_onset) *p_onset = i*sizeof(t_word); - if (p_type) *p_type = x->vec[i].type; - if (p_arraytype) *p_arraytype = x->vec[i].arraytemplate; - return 1; - } - return 0; -} - -#define ERR(msg,ret) do {\ - if (loud) error("%s.%s: "msg, x->sym->name, fieldname->name);\ - return ret;} while(0); -static t_float template_getfloat(t_template *x, t_symbol *fieldname, t_word *wp, int loud) { - int onset, type; t_symbol *arraytype; - if (!template_find_field(x, fieldname, &onset, &type, &arraytype)) ERR("no such field",0); - if (type != DT_FLOAT) ERR("not a number",0); - return *(t_float *)(((char *)wp) + onset); -} -static t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname, t_word *wp, int loud) { - int onset, type; t_symbol *arraytype; - if (!template_find_field(x, fieldname, &onset, &type, &arraytype)) ERR("no such field",&s_); - if (type != DT_SYMBOL) ERR("not a symbol",&s_); - return *(t_symbol **)(((char *)wp) + onset); -} -static void template_setfloat(t_template *x, t_symbol *fieldname, t_word *wp, t_float f, int loud) { - int onset, type; t_symbol *arraytype; - if (!template_find_field(x, fieldname, &onset, &type, &arraytype)) ERR("no such field",); - if (type != DT_FLOAT) ERR("not a number",); - *(t_float *)(((char *)wp) + onset) = f; -} -static void template_setsymbol(t_template *x, t_symbol *fieldname, t_word *wp, t_symbol *s, int loud) { - int onset, type; t_symbol *arraytype; - if (!template_find_field(x, fieldname, &onset, &type, &arraytype)) ERR("no such field",); - if (type != DT_SYMBOL) ERR("not a symbol",); - *(t_symbol **)(((char *)wp) + onset) = s; -} -#undef ERR - -/* stringent check to see if a "saved" template, x2, matches the current -one (x1). It's OK if x1 has additional scalar elements but not (yet) -arrays or lists. This is used for reading in "data files". */ -static int template_match(t_template *x1, t_template *x2) { - if (x1->n < x2->n) return 0; - for (int i=x2->n; i < x1->n; i++) - if (x1->vec[i].type == DT_ARRAY || x1->vec[i].type == DT_CANVAS) return 0; - if (x2->n > x1->n) post("add elements..."); - for (int i=0; i < x2->n; i++) if (!dataslot_matches(&x1->vec[i], &x2->vec[i], 1)) return 0; - return 1; -} - -/* --------------- CONFORMING TO CHANGES IN A TEMPLATE ------------ */ - -/* the following functions handle updating scalars to agree with changes -in their template. The old template is assumed to be the "installed" one -so we can delete old items; but making new ones we have to avoid scalar_new -which would make an old one whereas we will want a new one (but whose array -elements might still be old ones.) - LATER deal with graphics updates too... */ - -/* conform the word vector of a scalar to the new template */ -static void template_conformwords(t_template *tfrom, t_template *tto, int *conformaction, t_word *wfrom, t_word *wto) { - for (int i=0; i<tto->n; i++) { - if (conformaction[i] >= 0) { - /* we swap the two, in case it's an array or list, so that when "wfrom" is deleted the old one gets cleaned up. */ - t_word wwas = wto[i]; - wto[i] = wfrom[conformaction[i]]; - wfrom[conformaction[i]] = wwas; - } - } -} - -/* conform a scalar, recursively conforming sublists and arrays */ -static t_scalar *template_conformscalar(t_template *tfrom, t_template *tto, int *conformaction, t_canvas *canvas, t_scalar *scfrom) { - t_scalar *x; - t_template *scalartemplate; - /* possibly replace the scalar */ - if (scfrom->t == tfrom->sym) { - t_gpointer gp; - /* see scalar_new() for comment about the gpointer. */ - gpointer_init(&gp); - x = (t_scalar *)getbytes(sizeof(t_scalar) + (tto->n - 1) * sizeof(*x->v)); - x->_class = scalar_class; - x->t = tfrom->sym; - gpointer_setcanvas(&gp, canvas, x); - /* Here we initialize to the new template, but array and list elements will still belong to old template. */ - word_init(x->v, tto, &gp); - template_conformwords(tfrom, tto, conformaction, scfrom->v, x->v); - /* replace the old one with the new one in the list */ - canvas->boxes->remove_by_value(scfrom); - canvas->boxes->add(x); - pd_free(scfrom); - scalartemplate = tto; - } else { - x = scfrom; - scalartemplate = template_findbyname(x->t); - } - /* convert all array elements and sublists */ - for (int i=0; i < scalartemplate->n; i++) { - t_dataslot *ds = scalartemplate->vec + i; - if (ds->type == DT_CANVAS) template_conformcanvas(tfrom, tto, conformaction, x->v[i].w_canvas); - if (ds->type == DT_ARRAY) template_conformarray( tfrom, tto, conformaction, x->v[i].w_array); - } - return x; -} - -/* conform an array, recursively conforming sublists and arrays */ -static void template_conformarray(t_template *tfrom, t_template *tto, int *conformaction, t_array *a) { - t_template *scalartemplate = 0; - if (a->tsym == tfrom->sym) { - /* the array elements must all be conformed */ - int oldelemsize = sizeof(t_word) * tfrom->n; - int newelemsize = sizeof(t_word) * tto->n; - char *newarray = (char *)getbytes(newelemsize * a->n); - char *oldarray = a->vec; - if (a->elemsize != oldelemsize) bug("template_conformarray"); - for (int i=0; i<a->n; i++) { - t_word *wp = (t_word *)(newarray + newelemsize*i); - word_init(wp, tto, &a->gp); - template_conformwords(tfrom, tto, conformaction, (t_word *)(oldarray + oldelemsize*i), wp); - word_free((t_word *)(oldarray + oldelemsize*i), tfrom); - } - scalartemplate = tto; - a->vec = newarray; - free(oldarray); - } else scalartemplate = template_findbyname(a->tsym); - /* convert all arrays and sublist fields in each element of the array */ - for (int i=0; i<a->n; i++) { - t_word *wp = (t_word *)(a->vec + sizeof(t_word) * a->n * i); - for (int j=0; j < scalartemplate->n; j++) { - t_dataslot *ds = scalartemplate->vec + j; - if (ds->type == DT_CANVAS) template_conformcanvas(tfrom, tto, conformaction, wp[j].w_canvas); - if (ds->type == DT_ARRAY) template_conformarray( tfrom, tto, conformaction, wp[j].w_array); - } - } -} - -/* this routine searches for every scalar in the canvas that belongs - to the "from" template and makes it belong to the "to" template. Descend canvases recursively. - We don't handle redrawing here; this is to be filled in LATER... */ -t_array *garray_getarray(t_garray *x); -static void template_conformcanvas(t_template *tfrom, t_template *tto, int *conformaction, t_canvas *canvas) { - canvas_each(g,canvas) { - t_class *c = g->_class; - /* what's the purpose of the assignment here?... consult original code */ - if (c==scalar_class) g = template_conformscalar(tfrom, tto, conformaction, canvas, (t_scalar *)g); - else if (c==canvas_class) template_conformcanvas(tfrom, tto, conformaction, (t_canvas *)g); - else if (c==garray_class) template_conformarray(tfrom, tto, conformaction, garray_getarray((t_garray *)g)); - } -} - -/* globally conform all scalars from one template to another */ -void template_conform(t_template *tfrom, t_template *tto) { - int nto = tto->n, nfrom = tfrom->n, doit = 0; - int *conformaction = (int *)getbytes(sizeof(int) * nto); - int *conformedfrom = (int *)getbytes(sizeof(int) * nfrom); - for (int i=0; i< nto; i++) conformaction[i] = -1; - for (int i=0; i<nfrom; i++) conformedfrom[i] = 0; - for (int i=0; i < nto; i++) { - t_dataslot *dataslot = &tto->vec[i]; - for (int j=0; j<nfrom; j++) { - t_dataslot *dataslot2 = &tfrom->vec[j]; - if (dataslot_matches(dataslot, dataslot2, 1)) { - conformaction[i] = j; - conformedfrom[j] = 1; - } - } - } - for (int i=0; i<nto; i++) if (conformaction[i] < 0) { - t_dataslot *dataslot = &tto->vec[i]; - for (int j=0; j<nfrom; j++) - if (!conformedfrom[j] && dataslot_matches(dataslot, &tfrom->vec[j], 0)) { - conformaction[i] = j; - conformedfrom[j] = 1; - } - } - if (nto != nfrom) doit = 1; - else for (int i=0; i<nto; i++) if (conformaction[i] != i) doit = 1; - if (doit) { - post("conforming template '%s' to new structure", tfrom->sym->name); - for (int i=0; i<nto; i++) post("... %d", conformaction[i]); - foreach(gl,windowed_canvases) template_conformcanvas(tfrom, tto, conformaction, gl->first); - } - free(conformaction); - free(conformedfrom); -} - -t_template *template_findbyname(t_symbol *s) {return (t_template *)pd_findbyclass(s, template_class);} - -t_canvas *template_findcanvas(t_template *t) { - if (!t) bug("template_findcanvas"); - t_gtemplate *gt = t->list; - if (!gt) return 0; - return gt->owner; - /* return ((t_canvas *)pd_findbyclass(t->sym, canvas_class)); */ -} - -void template_notify(t_template *t, t_symbol *s, int argc, t_atom *argv) {if (t->list) t->list->outlet->send(s,argc,argv);} - -/* bash the first of (argv) with a pointer to a scalar, and send on - to template as a notification message */ -static void template_notifyforscalar(t_template *t, t_canvas *owner, t_scalar *sc, t_symbol *s, int argc, t_atom *argv) { - t_gpointer gp; - gpointer_init(&gp); - gpointer_setcanvas(&gp, owner, sc); - SETPOINTER(argv, &gp); - template_notify(t, s, argc, argv); - gpointer_unset(&gp); -} - -/* call this when reading a patch from a file to declare what templates - we'll need. If there's already a template, check if it matches. - If it doesn't it's still OK as long as there are no "struct" (gtemplate) - objects hanging from it; we just conform everyone to the new template. - If there are still struct objects belonging to the other template, we're - in trouble. LATER we'll figure out how to conform the new patch's objects - to the pre-existing struct. */ -static void *template_usetemplate(void *dummy, t_symbol *s, int argc, t_atom *argv) { - t_symbol *tsym = canvas_makebindsym(atom_getsymbolarg(0, argc, argv)); - t_template *x = (t_template *)pd_findbyclass(tsym, template_class); - if (!argc) return 0; - argc--; argv++; - if (x) { - t_template *y = template_new(&s_, argc, argv); - /* If the new template is the same as the old one, there's nothing to do. */ - if (!template_match(x, y)) { /* Are there "struct" objects upholding this template? */ - if (x->list) { - error("%s: template mismatch", tsym->name); - } else { - template_conform(x, y); - pd_free(x); - t_template *y2 = template_new(tsym, argc, argv); - y2->list = 0; - } - } - pd_free(y); - } else template_new(tsym, argc, argv); - return 0; -} - -/* here we assume someone has already cleaned up all instances of this. */ -void template_free(t_template *x) { - if (*x->sym->name) pd_unbind(x,x->sym); - free(x->vec); -} - -/* ---------------- gtemplates. One per canvas. ----------- */ - -/* "Struct": an object that searches for, and if necessary creates, -a template (above). Other objects in the canvas then can give drawing -instructions for the template. The template doesn't go away when the -"struct" is deleted, so that you can replace it with another one to add new fields, for example. */ -static void *gtemplate_donew(t_symbol *sym, int argc, t_atom *argv) { - t_gtemplate *x = (t_gtemplate *)pd_new(gtemplate_class); - t_template *t = template_findbyname(sym); - x->owner = canvas_getcurrent(); - x->next = 0; - x->sym = sym; - x->argc = argc; - x->argv = (t_atom *)getbytes(argc * sizeof(t_atom)); - for (int i=0; i<argc; i++) x->argv[i] = argv[i]; - /* already have a template by this name? */ - if (t) { - x->t = t; - /* if it's already got a "struct" object we - just tack this one to the end of the list and leave it there. */ - if (t->list) { - t_gtemplate *x2, *x3; - for (x2 = x->t->list; (x3 = x2->next); x2 = x3) {} - x2->next = x; - post("template %s: warning: already exists.", sym->name); - } else { - /* if there's none, we just replace the template with our own and conform it. */ - t_template *y = template_new(&s_, argc, argv); - //canvas_redrawallfortemplate(t, 2); - /* Unless the new template is different from the old one, there's nothing to do. */ - if (!template_match(t, y)) { - /* conform everyone to the new template */ - template_conform(t, y); - pd_free(t); - t = template_new(sym, argc, argv); - } - pd_free(y); - t->list = x; - //canvas_redrawallfortemplate(t, 1); - } - } else { - /* otherwise make a new one and we're the only struct on it. */ - x->t = t = template_new(sym, argc, argv); - t->list = x; - } - outlet_new(x,0); - return x; -} - -static void *gtemplate_new(t_symbol *s, int argc, t_atom *argv) { - t_symbol *sym = atom_getsymbolarg(0, argc, argv); - if (argc >= 1) {argc--; argv++;} - return (gtemplate_donew(canvas_makebindsym(sym), argc, argv)); -} - -/* old version (0.34) -- delete 2003 or so */ -static void *gtemplate_new_old(t_symbol *s, int argc, t_atom *argv) { - t_symbol *sym = canvas_makebindsym(canvas_getcurrent()->name); - static int warned; - if (!warned) { - post("warning -- 'template' (%s) is obsolete; replace with 'struct'", sym->name); - warned = 1; - } - return gtemplate_donew(sym, argc, argv); -} - -t_template *gtemplate_get(t_gtemplate *x) {return x->t;} - -static void gtemplate_free(t_gtemplate *x) { - /* get off the template's list */ - t_template *t = x->t; - if (x == t->list) { - //canvas_redrawallfortemplate(t, 2); - if (x->next) { - /* if we were first on the list, and there are others on the list, make a new template corresponding - to the new first-on-list and replace the existing template with it. */ - t_template *z = template_new(&s_, x->next->argc, x->next->argv); - template_conform(t, z); - pd_free(t); - pd_free(z); - z = template_new(x->sym, x->next->argc, x->next->argv); - z->list = x->next; - for (t_gtemplate *y=z->list; y ; y=y->next) y->t=z; - } else t->list = 0; - //canvas_redrawallfortemplate(t, 1); - } else { - t_gtemplate *x2, *x3; - for (x2=t->list; (x3=x2->next); x2=x3) if (x==x3) {x2->next=x3->next; break;} - } - free(x->argv); -} - -/* --------------- FIELD DESCRIPTORS (NOW CALLED SLOT) ---------------------- */ -/* a field descriptor can hold a constant or a variable's name; in the latter case, - it's the name of a field in the template we belong to. LATER, we might want to cache the offset - of the field so we don't have to search for it every single time we draw the object. -*/ -/* note: there is also t_dataslot which plays a similar role. could they be merged someday? */ - -struct _slot { - char type; /* LATER consider removing this? */ - char var; - union { - t_float f; /* the field is a constant float */ - t_symbol *s; /* the field is a constant symbol */ - t_symbol *varsym; /* the field is variable and this is the name */ - }; - float min,max; - float scrmin,scrmax; /* min and max screen values */ - float quantum; /* quantization in value */ -}; - -static void slot_setfloat_const( t_slot *fd, float f) { - fd->type = A_FLOAT; fd->var = 0; fd->f = f; fd->min = fd->max = fd->scrmin = fd->scrmax = fd->quantum = 0;} -static void slot_setsymbol_const(t_slot *fd, t_symbol *s) { - fd->type = A_SYMBOL; fd->var = 0; fd->s = s; fd->min = fd->max = fd->scrmin = fd->scrmax = fd->quantum = 0;} - -static void slot_setfloat_var(t_slot *fd, t_symbol *s) { - char *s1, *s2, *s3; - fd->type = A_FLOAT; - fd->var = 1; - if (!(s1 = strchr(s->name, '(')) || !(s2 = strchr(s->name, ')')) || s1>s2) { - fd->varsym = s; - fd->min = fd->max = fd->scrmin = fd->scrmax = fd->quantum = 0; - } else { - fd->varsym = symprintf("%.*s",s1-s->name,s->name); - t_int got = sscanf(s1, "(%f:%f)(%f:%f)(%f)", &fd->min, &fd->max, &fd->scrmin, &fd->scrmax, &fd->quantum); - if (got < 2) goto fail; - if (got == 3 || (got < 4 && strchr(s2, '('))) goto fail; - if (got < 5 && (s3 = strchr(s2, '(')) && strchr(s3+1, '(')) goto fail; - if (got == 4) fd->quantum = 0; - else if (got == 2) { - fd->quantum = 0; - fd->scrmin = fd->min; - fd->scrmax = fd->max; - } - return; - fail: - error("parse error: %s", s->name); - fd->min = fd->scrmin = fd->max = fd->scrmax = fd->quantum = 0; - } -} - -#define CLOSED 1 -#define BEZ 2 -#define NOMOUSE 4 -#define A_ARRAY 55 /* LATER decide whether to enshrine this in m_pd.h */ - -static void slot_setfloatarg(t_slot *fd, int argc, t_atom *argv) { - if (argc <= 0) slot_setfloat_const(fd, 0); - else if (argv->a_type == A_SYMBOL) slot_setfloat_var( fd, argv->a_symbol); - else slot_setfloat_const(fd, argv->a_float); -} -static void slot_setsymbolarg(t_slot *fd, int argc, t_atom *argv) { - if (argc <= 0) slot_setsymbol_const(fd, &s_); - else if (argv->a_type == A_SYMBOL) { - fd->type = A_SYMBOL; - fd->var = 1; - fd->varsym = argv->a_symbol; - fd->min = fd->max = fd->scrmin = fd->scrmax = fd->quantum = 0; - } else slot_setsymbol_const(fd, &s_); -} -static void slot_setarrayarg(t_slot *fd, int argc, t_atom *argv) { - if (argc <= 0) slot_setfloat_const(fd, 0); - else if (argv->a_type == A_SYMBOL) { - fd->type = A_ARRAY; - fd->var = 1; - fd->varsym = argv->a_symbol; - } else slot_setfloat_const(fd, argv->a_float); -} - -/* getting and setting values via slots -- note confusing names; the above are setting up the slot itself. */ - -/* convert a variable's value to a screen coordinate via its slot */ -static t_float slot_cvttocoord(t_slot *f, float val) { - float coord, extreme, div; - if (f->max == f->min) return val; - div = (f->scrmax - f->scrmin)/(f->max - f->min); - coord = f->scrmin + (val - f->min) * div; - extreme = f->scrmin<f->scrmax ? f->scrmin : f->scrmax; if (coord<extreme) coord = extreme; - extreme = f->scrmin>f->scrmax ? f->scrmin : f->scrmax; if (coord>extreme) coord = extreme; - return coord; -} - -/* read a variable via slot and convert to screen coordinate */ -static t_float slot_getcoord(t_slot *f, t_template *t, t_word *wp, int loud) { - if (f->type!=A_FLOAT) {if (loud) error("symbolic data field used as number"); return 0;} - if (f->var) return slot_cvttocoord(f, template_getfloat(t, f->varsym, wp, loud)); - return f->f; -} -static t_float slot_getfloat(t_slot *f, t_template *t, t_word *wp, int loud) { - if (f->type!=A_FLOAT) {if (loud) error("symbolic data field used as number"); return 0;} - if (f->var) return template_getfloat(t, f->varsym, wp, loud); - return f->f; -} -static t_symbol *slot_getsymbol(t_slot *f, t_template *t, t_word *wp, int loud) { - if (f->type!=A_SYMBOL) {if (loud) error("numeric data field used as symbol"); return &s_;} - if (f->var) return template_getsymbol(t, f->varsym, wp, loud); - return f->s; -} - -/* convert from a screen coordinate to a variable value */ -static float slot_cvtfromcoord(t_slot *f, float coord) { - if (f->scrmax == f->scrmin) return coord; - else { - float div = (f->max - f->min)/(f->scrmax - f->scrmin); - float extreme; - float val = f->min + (coord - f->scrmin) * div; - if (f->quantum != 0) val = ((int)((val/f->quantum) + 0.5)) * f->quantum; - extreme = f->min<f->max ? f->min : f->max; if (val<extreme) val=extreme; - extreme = f->min>f->max ? f->min : f->max; if (val>extreme) val=extreme; - return val; - } - } - -static void slot_setcoord(t_slot *f, t_template *t, t_word *wp, float coord, int loud) { - if (f->type == A_FLOAT && f->var) { - float val = slot_cvtfromcoord(f, coord); - template_setfloat(t, f->varsym, wp, val, loud); - } else { - if (loud) error("attempt to set constant or symbolic data field to a number"); - } -} - -#define FIELDSET(T,F,D) if (argc) slot_set##T##arg(&x->F,argc--,argv++); \ - else slot_setfloat_const(&x->F,D); - -/* curves belong to templates and describe how the data in the template are to be drawn. - The coordinates of the curve (and other display features) can be attached to fields in the template. */ - -t_class *curve_class; - -/* includes polygons too */ -struct t_curve : t_object { - int flags; /* CLOSED and/or BEZ and/or NOMOUSE */ - t_slot fillcolor, outlinecolor, width, vis; - int npoints; - t_slot *vec; - t_canvas *canvas; -}; - -static void *curve_new(t_symbol *classsym, t_int argc, t_atom *argv) { - t_curve *x = (t_curve *)pd_new(curve_class); - char *classname = classsym->name; - int flags = 0; - x->canvas = canvas_getcurrent(); - if (classname[0] == 'f') {classname += 6; flags |= CLOSED;} else classname += 4; - slot_setfloat_const(&x->vis, 1); - if (classname[0] == 'c') flags |= BEZ; - while (1) { - t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); - if (!strcmp(firstarg->name,"-v") && argc > 1) { - slot_setfloatarg(&x->vis, 1, argv+1); - argc -= 2; argv += 2; - } else - if (!strcmp(firstarg->name,"-x")) { - flags |= NOMOUSE; - argc -= 1; argv += 1; - } else break; - } - x->flags = flags; - if (flags&CLOSED&&argc) slot_setfloatarg( &x->fillcolor, argc--,argv++); - else slot_setfloat_const(&x->fillcolor, 0); - FIELDSET(float,outlinecolor,0); - FIELDSET(float,width,1); - if (argc < 0) argc = 0; - int nxy = argc + (argc&1); - x->npoints = nxy>>1; - x->vec = (t_slot *)getbytes(nxy * sizeof(t_slot)); - t_slot *fd = x->vec; - for (int i=0; i<argc; i++, fd++, argv++) slot_setfloatarg(fd, 1, argv); - if (argc & 1) slot_setfloat_const(fd, 0); - return x; -} - -static void curve_float(t_curve *x, t_floatarg f) { - if (x->vis.type != A_FLOAT || x->vis.var) {error("global vis/invis for a template with variable visibility"); return;} - int viswas = x->vis.f!=0; - if ((f!=0 && viswas) || (f==0 && !viswas)) return; - canvas_redrawallfortemplatecanvas(x->canvas, 2); - slot_setfloat_const(&x->vis, f!=0); - canvas_redrawallfortemplatecanvas(x->canvas, 1); -} - -static int rangecolor(int n) {return n*9/255;} - -static void numbertocolor(int n, char *s) { - n = (int)max(n,0); - sprintf(s, "#%2.2x%2.2x%2.2x", rangecolor(n/100), rangecolor((n/10)%10), rangecolor(n%10)); -} - -static void curve_vis(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, float basex, float basey, int vis) { - t_curve *x = (t_curve *)z; - int n = x->npoints; - t_slot *f = x->vec; - if (!slot_getfloat(&x->vis, t, data, 0)) return; - if (vis) { - if (n > 1) { - int flags = x->flags; - char outline[20], fill[20]; - int pix[200]; - if (n > 100) n = 100; - /* calculate the pixel values before we start printing out the TK message so that - "error" printout won't be interspersed with it. Only show up to 100 points so we don't - have to allocate memory here. */ - for (int i=0; i<n; i++, f += 2) { - pix[2*i ] = canvas_xtopixels(canvas, basex + slot_getcoord(f+0, t, data, 1)); - pix[2*i+1] = canvas_ytopixels(canvas, basey + slot_getcoord(f+1, t, data, 1)); - } - numbertocolor((int)slot_getfloat(&x->outlinecolor, t, data, 1), outline); - if (flags & CLOSED) { - numbertocolor((int)slot_getfloat(&x->fillcolor, t, data, 1), fill); - //sys_vgui(".x%lx.c create polygon\\\n", (long)canvas_getcanvas(canvas)); - } else sys_vgui(".x%lx.c create line\\\n", (long)canvas_getcanvas(canvas)); - for (int i=0; i<n; i++) sys_vgui("%d %d\\\n", pix[2*i], pix[2*i+1]); - sys_vgui("-width %f\\\n", max(slot_getfloat(&x->width, t, data, 1),1.0f)); - if (flags & CLOSED) sys_vgui("-fill %s -outline %s\\\n", fill, outline); - else sys_vgui("-fill %s\\\n", outline); - if (flags & BEZ) sys_vgui("-smooth 1\\\n"); - sys_vgui("-tags curve%lx\n", (long)data); - } else post("warning: curves need at least two points to be graphed"); - } else { - if (n > 1) sys_vgui(".x%lx.c delete curve%lx\n", (long)canvas_getcanvas(canvas), (long)data); - } -} - -static struct { - int field; - float xcumulative, xbase, xper; - float ycumulative, ybase, yper; - t_canvas *canvas; - t_scalar *scalar; - t_array *array; - t_word *wp; - t_template *t; - t_gpointer gpointer; -} cm; - -/* LATER protect against the template changing or the scalar disappearing probably by attaching a gpointer here ... */ -#if 0 -static void curve_motion(void *z, t_floatarg dx, t_floatarg dy) { - t_curve *x = (t_curve *)z; - t_slot *f = x->vec + cm.field; - t_atom at; - if (!gpointer_check(&curve_motion_gpointer, 0)) {post("curve_motion: scalar disappeared"); return;} - cm.xcumulative += dx; - cm.ycumulative += dy; - if (f[0].var && dx!=0) slot_setcoord(f, cm.t, cm.wp, cm.xbase + cm.xcumulative*cm.xper, 1); - if (f[1].var && dy!=0) slot_setcoord(f+1, cm.t, cm.wp, cm.ybase + cm.ycumulative*cm.yper, 1); - /* LATER figure out what to do to notify for an array? */ - if (cm.scalar) template_notifyforscalar(cm.t, cm.canvas, cm.scalar, gensym("change"), 1, &at); - if (cm.scalar) gobj_changed(cm.scalar,0); else gobj_changed(cm.array,0); -} -#endif - -int iabs(int a) {return a<0?-a:a;} - -static int curve_click(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, t_scalar *sc, -t_array *ap, float basex, float basey, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_curve *x = (t_curve *)z; - int bestn = -1; - int besterror = 0x7fffffff; - t_slot *f = x->vec; - if (!slot_getfloat(&x->vis, t, data, 0)) return 0; - for (int i=0; i<x->npoints; i++, f += 2) { - int xval = (int)slot_getcoord(f , t, data, 0), xloc = canvas_xtopixels(canvas, basex + xval); - int yval = (int)slot_getcoord(f+1, t, data, 0), yloc = canvas_ytopixels(canvas, basey + yval); - int xerr = iabs(xloc-xpix); - int yerr = iabs(yloc-ypix); - if (!f->var && !(f+1)->var) continue; - if (yerr > xerr) xerr = yerr; - if (xerr < besterror) { - cm.xbase = xval; - cm.ybase = yval; - besterror = xerr; - bestn = i; - } - } - if (besterror > 10) return 0; - if (doit) { - cm.xper = canvas_pixelstox(canvas, 1) - canvas_pixelstox(canvas, 0); - cm.yper = canvas_pixelstoy(canvas, 1) - canvas_pixelstoy(canvas, 0); - cm.xcumulative = cm.ycumulative = 0; - cm.canvas = canvas; - cm.scalar = sc; - cm.array = ap; - cm.wp = data; - cm.field = 2*bestn; - cm.t = t; - if (cm.scalar) gpointer_setcanvas(&cm.gpointer, cm.canvas, cm.scalar); - else gpointer_setarray(&cm.gpointer, cm.array, cm.wp); - /* canvas_grab(canvas, z, curve_motion, 0, xpix, ypix); */ - } - return 1; -} - -t_class *plot_class; - -struct t_plot : t_object { - t_canvas *canvas; - t_slot outlinecolor, width, xloc, yloc, xinc, style; - t_slot data, xpoints, ypoints, wpoints; - t_slot vis; - t_slot scalarvis; /* true if drawing the scalar at each point */ -}; - -static void *plot_new(t_symbol *classsym, t_int argc, t_atom *argv) { - t_plot *x = (t_plot *)pd_new(plot_class); - int defstyle = PLOTSTYLE_POLY; - x->canvas = canvas_getcurrent(); - slot_setfloat_var(&x->xpoints,&s_x); - slot_setfloat_var(&x->ypoints,&s_y); - slot_setfloat_var(&x->wpoints, gensym("w")); - slot_setfloat_const(&x->vis, 1); - slot_setfloat_const(&x->scalarvis, 1); - while (1) { - const char *f = atom_getsymbolarg(0, argc, argv)->name; - argc--; argv++; - if (!strcmp(f, "curve") || !strcmp(f, "-c")) defstyle = PLOTSTYLE_BEZ; - else if (!strcmp(f,"-v") &&argc>0) {slot_setfloatarg(&x->vis, 1,argv+1);argc--;argv++;} - else if (!strcmp(f,"-vs")&&argc>0) {slot_setfloatarg(&x->scalarvis,1,argv+1);argc--;argv++;} - else if (!strcmp(f,"-x") &&argc>0) {slot_setfloatarg(&x->xpoints, 1,argv+1);argc--;argv++;} - else if (!strcmp(f,"-y") &&argc>0) {slot_setfloatarg(&x->ypoints, 1,argv+1);argc--;argv++;} - else if (!strcmp(f,"-w") &&argc>0) {slot_setfloatarg(&x->wpoints, 1,argv+1);argc--;argv++;} - else break; - } - FIELDSET(array,data,1); - FIELDSET(float,outlinecolor,0); - FIELDSET(float,width,1); - FIELDSET(float,xloc,1); - FIELDSET(float,yloc,1); - FIELDSET(float,xinc,1); - FIELDSET(float,style,defstyle); - return x; -} - -void plot_float(t_plot *x, t_floatarg f) { - int viswas; - if (x->vis.type != A_FLOAT || x->vis.var) {error("global vis/invis for a template with variable visibility"); return;} - viswas = x->vis.f!=0; - if ((f!=0 && viswas) || (f==0 && !viswas)) return; - canvas_redrawallfortemplatecanvas(x->canvas, 2); - slot_setfloat_const(&x->vis, f!=0); - canvas_redrawallfortemplatecanvas(x->canvas, 1); -} - -struct t_pelote { - t_symbol *elemtsym; - t_array *array; - float linewidth; - float xloc; - float xinc; - float yloc; - float style; - float vis; - float scalarvis; -}; - -/* get everything we'll need from the owner template of the array being - plotted. Not used for garrays, but see below */ -static int plot_readownertemplate(t_plot *x, t_word *data, t_template *ownertemplate, t_pelote *out) { - int arrayonset, type; - t_symbol *elemtsym; - t_array *array; - if (x->data.type != A_ARRAY || !x->data.var) {error("needs an array field"); return -1;} - if (!template_find_field(ownertemplate, x->data.varsym, &arrayonset, &type, &elemtsym)) { - error("%s: no such field", x->data.varsym->name); - return -1; - } - if (type != DT_ARRAY) {error("%s: not an array", x->data.varsym->name); return -1;} - array = *(t_array **)(((char *)data) + arrayonset); -#define SLUT(FIELD) slot_getfloat(&x->FIELD, ownertemplate, data, 1); - out->linewidth = SLUT(width); - out->xloc = SLUT(xloc); - out->xinc = SLUT(xinc); - out->yloc = SLUT(yloc); - out->style = SLUT(style); - out->vis = SLUT(vis); - out->scalarvis = SLUT(scalarvis); -#undef SLUT - out->elemtsym = elemtsym; - out->array = array; - return 0; -} - -/* get everything else you could possibly need about a plot, - either for plot's own purposes or for plotting a "garray" */ -static int array_getfields(t_symbol *elemtsym, t_canvas **elemtemplatecanvasp, -t_template **elemtemplatep, int *elemsizep, t_slot *xslot, t_slot *yslot, t_slot *wslot, -int *xonsetp, int *yonsetp, int *wonsetp) { - int type; - t_symbol *dummy, *varname; - t_canvas *elemtemplatecanvas = 0; - /* the "float" template is special in not having to have a canvas; - template_findbyname is hardwired to return a predefined template. */ - t_template *elemtemplate = template_findbyname(elemtsym); - if (!elemtemplate) {error("%s: no such template", elemtsym->name); return -1;} - if (!(elemtsym==&s_float || (elemtemplatecanvas = template_findcanvas(elemtemplate)))) { - error("%s: no canvas for this template", elemtsym->name); - return -1; - } - *elemtemplatecanvasp = elemtemplatecanvas; - *elemtemplatep = elemtemplate; - *elemsizep = elemtemplate->n * sizeof(t_word); -#define FOO(f,name,onset) \ - varname = f && f->var ? f->varsym : gensym(name); \ - if (!template_find_field(elemtemplate,varname,&onset,&type,&dummy) || type!=DT_FLOAT) onset=-1; - FOO(yslot,"y",*yonsetp) - FOO(xslot,"x",*xonsetp) - FOO(wslot,"w",*wonsetp) -#undef FOO - return 0; -} - -static void plot_vis(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, float basex, float basey, int tovis) { - t_plot *x = (t_plot *)z; - int elemsize, yonset, wonset, xonset; - t_canvas *elemtemplatecanvas; - t_template *elemtemplate; - float xsum, yval; - t_pelote p; - if (plot_readownertemplate(x,data,t,&p)) return; - t_slot *xslot = &x->xpoints, *yslot = &x->ypoints, *wslot = &x->wpoints; - if (!p.vis) return; - if (array_getfields(p.elemtsym,&elemtemplatecanvas,&elemtemplate,&elemsize,xslot,yslot,wslot,&xonset,&yonset,&wonset)) return; - int nelem = p.array->n; - char *elem = (char *)p.array->vec; - if (tovis) { - if (p.style == PLOTSTYLE_POINTS) { - float minyval = 1e20, maxyval = -1e20; - int ndrawn = 0; - xsum = basex + p.xloc; - for (int i=0; i<nelem; i++) { - float yval; - int ixpix, inextx; - if (xonset >= 0) { - float usexloc = basex + p.xloc + *(float *)((elem + elemsize*i) + xonset); - ixpix = canvas_xtopixels(canvas, slot_cvttocoord(xslot, usexloc)); - inextx = ixpix + 2; - } else { - ixpix = canvas_xtopixels(canvas, slot_cvttocoord(xslot, xsum)); xsum += p.xinc; - inextx = canvas_xtopixels(canvas, slot_cvttocoord(xslot, xsum)); - } - yval = yonset>=0 ? p.yloc + *(float *)((elem + elemsize*i) + yonset) : 0; - if (yval > maxyval) maxyval = yval; - if (yval < minyval) minyval = yval; - if (i == nelem-1 || inextx != ixpix) { - sys_vgui(".x%lx.c create rectangle %d %d %d %d -fill black -width 0 -tags plot%lx\n", - (long)canvas_getcanvas(canvas), ixpix, - (int) canvas_ytopixels(canvas, basey + slot_cvttocoord(yslot, minyval)), inextx, - (int)(canvas_ytopixels(canvas, basey + slot_cvttocoord(yslot, maxyval))+p.linewidth), - (long)data); - ndrawn++; - minyval = 1e20; - maxyval = -1e20; - } - } - } else { - char outline[20]; - int lastpixel = -1, ndrawn = 0; - float yval = 0, wval = 0; - int ixpix = 0; - /* draw the trace */ - numbertocolor((int)slot_getfloat(&x->outlinecolor, t, data, 1), outline); - if (wonset >= 0) { - /* found "w" field which controls linewidth. The trace is a filled polygon with 2n points. */ - //sys_vgui(".x%lx.c create polygon \\\n", (long)canvas_getcanvas(canvas)); - xsum = p.xloc; -#define FOO float usexloc = xonset>=0 ? p.xloc+*(float *)(elem+elemsize*i+xonset) : xsum; \ - float yval = yonset>=0 ? *(float *)(elem+elemsize*i+yonset) : 0; \ - wval = *(float *)(elem+elemsize*i+wonset); \ - float xpix = canvas_xtopixels(canvas, basex + slot_cvttocoord(xslot, usexloc)); \ - ixpix = int(roundf(xpix)); \ - float w = slot_cvttocoord(wslot,wval); - for (int i=0; i<nelem; i++) { - xsum+=p.xinc; FOO; - if (xonset>=0 || ixpix!=lastpixel) { - sys_vgui("%d %f \\\n", ixpix, canvas_ytopixels(canvas, basey + slot_cvttocoord(yslot,yval+p.yloc) - w)); - ndrawn++;} - lastpixel = ixpix;} - lastpixel = -1; - for (int i=nelem-1; i>=0; i--) { - xsum-=p.xinc; FOO; - if (xonset>=0 || ixpix!=lastpixel) { - sys_vgui("%d %f \\\n", ixpix, canvas_ytopixels(canvas, basey + p.yloc + slot_cvttocoord(yslot,yval)+w)); - ndrawn++;} - lastpixel = ixpix;} -#undef FOO - /* TK will complain if there aren't at least 3 points. There should be at least two already. */ - if (ndrawn < 4) { - int y = int(slot_cvttocoord(yslot, yval)); - int w = int(slot_cvttocoord(wslot, wval)); - sys_vgui("%d %f %d %f\\\n", - ixpix + 10, canvas_ytopixels(canvas, basey + p.yloc + y + w), - ixpix + 10, canvas_ytopixels(canvas, basey + p.yloc + y - w));} - sys_vgui(" -width 1 -fill %s -outline %s", outline, outline); - if (p.style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1"); - sys_vgui("-tags plot%lx\n", (long)data); - } else if (p.linewidth>0) { - /* no "w" field. If the linewidth is positive, draw a segmented line with the - requested width; otherwise don't draw the trace at all. */ - sys_vgui(".x%lx.c create line \\\n", (long)canvas_getcanvas(canvas)); - xsum = p.xloc; - for (int i=0; i<nelem; i++) { - float usexloc = xonset>=0 ? p.xloc+*(float *)(elem+elemsize*i+xonset) : xsum; if (xonset>=0) xsum+=int(p.xinc); - float yval = yonset>=0 ? *(float *)(elem+elemsize*i+yonset) : 0; - float xpix = canvas_xtopixels(canvas, basex + slot_cvttocoord(xslot, usexloc)); - ixpix = (int)roundf(xpix); - if (xonset >= 0 || ixpix != lastpixel) { - sys_vgui("%d %f \\\n", ixpix, canvas_ytopixels(canvas, basey + p.yloc + slot_cvttocoord(yslot, yval))); - ndrawn++; - } - lastpixel = ixpix; - } - /* TK will complain if there aren't at least 2 points... */ - if (ndrawn == 0) sys_vgui("0 0 0 0 \\\n"); - else if (ndrawn == 1) sys_vgui("%d %f \\\n", ixpix + 10, - canvas_ytopixels(canvas, basey + p.yloc + slot_cvttocoord(yslot, yval))); - sys_vgui("-width %f -fill %s -smooth %d -tags plot%lx",p.linewidth,outline,p.style==PLOTSTYLE_BEZ,(long)data); - } - } - /* We're done with the outline; now draw all the points. */ - if (p.scalarvis) { - int xsum = int(p.xloc); - for (int i=0; i<nelem; i++) { - //float usexloc = xonset>=0 ? basex + xloc + *(float *)(elem+elemsize*i+xonset) : basex+xsum; - if (xonset>=0) xsum+=int(p.xinc); - yval = yonset>=0 ? *(float *)(elem+elemsize*i+yonset) : 0; - //float useyloc = basey + yloc + slot_cvttocoord(yslot, yval); - /*canvas_each(y,elemtemplatecanvas) pd_getparentwidget(y)->w_parentvisfn(y, canvas, - (t_word *)(elem+elemsize*i), elemtemplate, usexloc, useyloc, tovis);*/ - } - } - } else { - /* un-draw the individual points */ - /* if (scalarvis) for (int i=0; i<nelem; i++) canvas_each(y,elemtemplatecanvas) - pd_getparentwidget(y)->w_parentvisfn(y, canvas, (t_word *)(elem+elemsize*i), elemtemplate,0,0,0);*/ - /* and then the trace */ - sys_vgui(".x%lx.c delete plot%lx\n", (long)canvas_getcanvas(canvas), (long)data); - } -} - -// could be merged with array_doclick -static int plot_click(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, t_scalar *sc, -t_array *ap, float basex, float basey, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_plot *x = (t_plot *)z; - t_pelote p; - if (plot_readownertemplate(x,data,t,&p)) return 0; - if (!p.vis) return 0; - return array_doclick(p.array,canvas,sc,ap,p.elemtsym,p.linewidth,basex+p.xloc,p.xinc, - basey+p.yloc,p.scalarvis,&x->xpoints,&x->ypoints,&x->wpoints,xpix,ypix,shift,alt,dbl,doit); -} - -/* ---------------- drawnumber: draw a number (or symbol) ---------------- */ -/* drawnumbers draw numeric fields at controllable locations, with controllable color and label. - invocation: (drawnumber|drawsymbol) [-v <visible>] variable x y color label */ - -t_class *drawnumber_class; - -#define DRAW_SYMBOL 1 - -struct t_drawnumber : t_object { - t_slot value, xloc, yloc, color, vis; - t_symbol *label; - int flags; - t_canvas *canvas; -}; - -static void *drawnumber_new(t_symbol *classsym, t_int argc, t_atom *argv) { - t_drawnumber *x = (t_drawnumber *)pd_new(drawnumber_class); - char *classname = classsym->name; - int flags = 0; - if (classname[4] == 's') flags |= DRAW_SYMBOL; - x->flags = flags; - slot_setfloat_const(&x->vis, 1); - x->canvas = canvas_getcurrent(); - while (1) { - t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); - if (!strcmp(firstarg->name,"-v") && argc > 1) { - slot_setfloatarg(&x->vis, 1, argv+1); - argc -= 2; argv += 2; - } else break; - } - if (flags & DRAW_SYMBOL) { - if (argc) slot_setsymbolarg( &x->value,argc--,argv++); - else slot_setsymbol_const(&x->value,&s_); - } else FIELDSET(float,value, 0); - FIELDSET(float,xloc,0); - FIELDSET(float,yloc,0); - FIELDSET(float,color,1); - if (argc) x->label = atom_getsymbolarg(0, argc, argv); else x->label = &s_; - return x; -} - -void drawnumber_float(t_drawnumber *x, t_floatarg f) { - if (x->vis.type != A_FLOAT || x->vis.var) {error("global vis/invis for a template with variable visibility"); return;} - int viswas = x->vis.f!=0; - if ((f != 0 && viswas) || (f == 0 && !viswas)) return; - canvas_redrawallfortemplatecanvas(x->canvas, 2); - slot_setfloat_const(&x->vis, f!=0); - canvas_redrawallfortemplatecanvas(x->canvas, 1); -} - -static void drawnumber_vis(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, float basex, float basey, int vis) { - t_drawnumber *x = (t_drawnumber *)z; - if (!slot_getfloat(&x->vis, t, data, 0)) return; - if (vis) { - t_atom at; - int xloc = canvas_xtopixels(canvas, basex + slot_getcoord(&x->xloc, t, data, 0)); - int yloc = canvas_ytopixels(canvas, basey + slot_getcoord(&x->yloc, t, data, 0)); - char colorstring[20]; - numbertocolor((int)slot_getfloat(&x->color, t, data, 1), colorstring); - if (x->flags & DRAW_SYMBOL) SETSYMBOL(&at, slot_getsymbol(&x->value, t, data, 0)); - else SETFLOAT( &at, slot_getfloat( &x->value, t, data, 0)); - std::ostringstream buf; - buf << x->label->name; - atom_ostream(&at,buf); - sys_vgui(".x%lx.c create text %d %d -anchor nw -fill %s -text {%s}", - (long)canvas_getcanvas(canvas), xloc, yloc, colorstring, buf.str().data()); - sys_vgui(" -font {Courier 42} -tags drawnumber%lx\n", (long)data); /*sys_hostfontsize(canvas_getfont(canvas))*/ - } else sys_vgui(".x%lx.c delete drawnumber%lx\n", (long)canvas_getcanvas(canvas), (long)data); -} - -static struct { - float ycumulative; - t_canvas *canvas; - t_scalar *scalar; - t_array *array; - t_word *wp; - t_template *t; - t_gpointer gpointer; - int symbol; - int firstkey; -} dn; - -/* LATER protect against the template changing or the scalar disappearing probably by attaching a gpointer here ... */ -#if 0 -static void drawnumber_motion(void *z, t_floatarg dx, t_floatarg dy) { - t_drawnumber *x = (t_drawnumber *)z; - t_slot *f = &x->value; - t_atom at; - if (!gpointer_check(&dn.gpointer, 0)) {post("drawnumber_motion: scalar disappeared"); return;} - if (dn.symbol) {post("drawnumber_motion: symbol"); return;} - dn.ycumulative -= dy; - template_setfloat(dn.t, f->varsym, dn.wp, dn.ycumulative, 1); - if (dn.scalar) gobj_changed(dn.scalar); else gobj_changed(dn.array); -} -#endif - -static void drawnumber_key(void *z, t_floatarg fkey) { - //t_drawnumber *x = (t_drawnumber *)z; - int key = (int)fkey; - if (!gpointer_check(&dn.gpointer, 0)) {post("drawnumber_motion: scalar disappeared"); return;} - if (!key) return; - if (dn.symbol) { - /* key entry for a symbol field... has to be rewritten in Tcl similarly to TextBox for edition of [drawsymbol] */ - // template_getsymbol(dn.t, f->varsym, dn.wp, 1)->name; - } else { - /* key entry for a numeric field... same here... [drawnumber] */ - //t_slot *f = &x->value; - //float newf; - //if (sscanf(sbuf, "%g", &newf) < 1) newf = 0; - //template_setfloat(dn.t, f->varsym, dn.wp, newf, 1); - //t_atom at; - //if (dn.scalar) template_notifyforscalar(dn.t, dn.canvas, dn.scalar, gensym("change"), 1, &at); - //if (dn.scalar) gobj_changed(dn.scalar,0); else gobj_changed(dn.array,0); - } -} - -#if 0 -static int drawnumber_click(t_gobj *z, t_canvas *canvas, t_word *data, t_template *t, t_scalar *sc, t_array *ap, float basex, float basey, int xpix, int ypix, int shift, int alt, int dbl, int doit) { - t_drawnumber *x = (t_drawnumber *)z; - int x1, y1, x2, y2; - drawnumber_getrect(z, canvas, data, t, basex, basey, &x1, &y1, &x2, &y2); - if (xpix >= x1 && xpix <= x2 && ypix >= y1 && ypix <= y2 - && x->value.var && slot_getfloat(&x->vis, t, data, 0)) { - if (doit) { - dn.canvas = canvas; - dn.wp = data; - dn.t = t; - dn.scalar = sc; - dn.array = ap; - dn.firstkey = 1; - dn.ycumulative = slot_getfloat(&x->value, t, data, 0); - dn.symbol = (x->flags & DRAW_SYMBOL)!=0; - if (dn.scalar) - gpointer_setcanvas(&dn.gpointer, dn.canvas, dn.scalar); - else gpointer_setarray(&dn.gpointer, dn.array, dn.wp); - /* canvas_grab(glist, z, drawnumber_motion, drawnumber_key, xpix, ypix); */ - } - return 1; - } else return 0; -} -#endif - -static void drawnumber_free(t_drawnumber *x) {} - -static void g_template_setup() { - template_class = class_new2("template",0,template_free,sizeof(t_template),CLASS_PD,""); - class_addmethod2(pd_canvasmaker._class, template_usetemplate, "struct", "*"); - gtemplate_class = class_new2("struct",gtemplate_new,gtemplate_free,sizeof(t_gtemplate),CLASS_NOINLET,"*"); - class_addcreator2("template",gtemplate_new_old,"*"); - - curve_class = class_new2("drawpolygon",curve_new,0,sizeof(t_curve),0,"*"); - class_setdrawcommand(curve_class); - class_addcreator2("drawcurve", curve_new,"*"); - class_addcreator2("filledpolygon",curve_new,"*"); - class_addcreator2("filledcurve", curve_new,"*"); - class_addfloat(curve_class, curve_float); - plot_class = class_new2("plot",plot_new,0,sizeof(t_plot),0,"*"); - class_setdrawcommand(plot_class); - class_addfloat(plot_class, plot_float); - drawnumber_class = class_new2("drawnumber",drawnumber_new,drawnumber_free,sizeof(t_drawnumber),0,"*"); - class_setdrawcommand(drawnumber_class); - class_addfloat(drawnumber_class, drawnumber_float); - class_addcreator2("drawsymbol",drawnumber_new,"*"); -} - -/* ------------- gpointers - safe pointing --------------- */ - -/* call this to verify that a pointer is fresh, i.e., that it either points to real data or to the head of a list, - and that in either case the object hasn't disappeared since this pointer was generated. Unless "headok" is set, - the routine also fails for the head of a list. */ -int gpointer_check(const t_gpointer *gp, int headok) { - if (!gp->o) return 0; - if (gp->o->_class == array_class) return 1; - return headok || gp->scalar; -} - -/* get the template for the object pointer to. Assumes we've already checked freshness. Returns 0 if head of list. */ -static t_symbol *gpointer_gettsym(const t_gpointer *gp) { - if (gp->o->_class == array_class) return gp->array->tsym; - t_scalar *sc = gp->scalar; - return sc ? sc->t : 0; -} - -/* copy a pointer to another, assuming the second one hasn't yet been initialized. New gpointers should be initialized - either by this routine or by gpointer_init below. */ -void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto) { - *gpto = *gpfrom; - if (gpto && gpto->o) gpto->o->refcount++; else bug("gpointer_copy"); -} - -void gpointer_unset(t_gpointer *gp) { - if (gp->scalar) { - if (!--gp->o->refcount) pd_free(gp->o); - gp->o=0; - gp->scalar=0; - } -} - -static void gpointer_setcanvas(t_gpointer *gp, t_canvas *o, t_scalar *x) { - gpointer_unset(gp); - gp->o=o; gp->scalar = x; gp->o->refcount++; -} -static void gpointer_setarray(t_gpointer *gp, t_array *o, t_word *w) { - gpointer_unset(gp); - gp->o=o; gp->w = w; gp->o->refcount++; -} - -void gpointer_init(t_gpointer *gp) { - gp->o = 0; - gp->scalar = 0; -} - -/* ---------------------- pointers ----------------------------- */ - -static t_class *ptrobj_class; - -struct t_typedout { - t_symbol *type; - t_outlet *outlet; -}; - -struct t_ptrobj : t_object { - t_gpointer gp; - t_typedout *typedout; - int ntypedout; - t_outlet *otherout; - t_outlet *bangout; -}; - -static void *ptrobj_new(t_symbol *classname, int argc, t_atom *argv) { - t_ptrobj *x = (t_ptrobj *)pd_new(ptrobj_class); - t_typedout *to; - gpointer_init(&x->gp); - x->typedout = to = (t_typedout *)getbytes(argc * sizeof (*to)); - x->ntypedout = argc; - for (int n=argc; n--; to++) { - to->outlet = outlet_new(x,&s_pointer); - to->type = canvas_makebindsym(atom_getsymbol(argv++)); - } - x->otherout = outlet_new(x,&s_pointer); - x->bangout = outlet_new(x,&s_bang); - pointerinlet_new(x,&x->gp); - return x; -} - -static void ptrobj_traverse(t_ptrobj *x, t_symbol *s) { - t_canvas *canvas = (t_canvas *)pd_findbyclass(s, canvas_class); - if (canvas) gpointer_setcanvas(&x->gp, canvas, 0); - else error("list '%s' not found", s->name); -} - -static void ptrobj_vnext(t_ptrobj *x, float f) { - t_gpointer *gp = &x->gp; - int wantselected = f!=0; - if (!gp->o) {error("next: no current pointer"); return;} - if (gp->o->_class == array_class) {error("next: lists only, not arrays"); return;} - t_canvas *canvas = gp->canvas; - if (wantselected) {error("next: next-selected unsupported in desiredata"); return;} - /* if (wantselected && !canvas_isvisible(canvas)) {error("next: next-selected only works for a visible window"); return;} */ - t_gobj *gobj = gp->scalar; - if (!gobj) gobj = canvas->boxes->first(); - else gobj = gobj->next(); - while (gobj && (gobj->_class != scalar_class || wantselected)) gobj = gobj->next(); - if (gobj) { - t_typedout *to = x->typedout; - t_scalar *sc = (t_scalar *)gobj; - gp->scalar = sc; - for (int n = x->ntypedout; n--; to++) - if (to->type == sc->t) {to->outlet->send(&x->gp); return;} - x->otherout->send(&x->gp); - } else { - gpointer_unset(gp); - x->bangout->send(); - } -} - -static void ptrobj_next(t_ptrobj *x) {ptrobj_vnext(x, 0);} - -static void ptrobj_sendwindow(t_ptrobj *x, t_symbol *s, int argc, t_atom *argv) { - if (!gpointer_check(&x->gp, 1)) {error("bang: empty pointer"); return;} - t_canvas *canvas = gpointer_getcanvas(&x->gp); - if (argc && argv->a_type == A_SYMBOL) pd_typedmess(canvas_getcanvas(canvas), argv->a_symbol, argc-1, argv+1); - else error("send-window: no message?"); -} - -static void ptrobj_bang(t_ptrobj *x) { - t_typedout *to = x->typedout; - if (!gpointer_check(&x->gp, 1)) {error("bang: empty pointer"); return;} - t_symbol *tsym = gpointer_gettsym(&x->gp); - for (int n=x->ntypedout; n--; to++) if (to->type == tsym) {to->outlet->send(&x->gp); return;} - x->otherout->send(&x->gp); -} - -static void ptrobj_pointer(t_ptrobj *x, t_gpointer *gp) { - gpointer_unset(&x->gp); - gpointer_copy(gp, &x->gp); - ptrobj_bang(x); -} - -static void ptrobj_rewind(t_ptrobj *x) { - if (!gpointer_check(&x->gp, 1)) {error("rewind: empty pointer"); return;} - if (x->gp.o->_class == array_class) {error("rewind: sorry, unavailable for arrays"); return;} - gpointer_setcanvas(&x->gp, x->gp.canvas, 0); - ptrobj_bang(x); -} - -static void ptrobj_free(t_ptrobj *x) { - free(x->typedout); - gpointer_unset(&x->gp); -} - -/* ---------------------- get ----------------------------- */ - -static t_class *get_class; -struct t_getvariable { - t_symbol *sym; - t_outlet *outlet; -}; -struct t_get : t_object { - t_symbol *tsym; - int nout; - t_getvariable *variables; -}; -static void *get_new(t_symbol *why, int argc, t_atom *argv) { - t_get *x = (t_get *)pd_new(get_class); - x->tsym = canvas_makebindsym(atom_getsymbolarg(0, argc, argv)); - if (argc) argc--, argv++; - t_getvariable *sp = x->variables = (t_getvariable *)getbytes(argc * sizeof (*x->variables)); - x->nout = argc; - for (int i=0; i < argc; i++, sp++) { - sp->sym = atom_getsymbolarg(i, argc, argv); - sp->outlet = outlet_new(x,0); - /* LATER connect with the template and set the outlet's type correctly. - We can't yet guarantee that the template is there before we hit this routine. */ - } - return x; -} - -static void get_pointer(t_get *x, t_gpointer *gp) { - int nitems = x->nout; - t_template *t = template_findbyname(x->tsym); - t_getvariable *vp; - TEMPLATE_CHECK(x->tsym,) - if (!gpointer_check(gp, 0)) {error("stale or empty pointer"); return;} - t_word *vec = gpointer_word(gp); - vp = x->variables + nitems-1; - for (int i=nitems-1; i>=0; i--, vp--) { - int onset, type; - t_symbol *arraytype; - if (template_find_field(t, vp->sym, &onset, &type, &arraytype)) { - if (type == DT_FLOAT ) vp->outlet->send( *(t_float *)(((char *)vec) + onset)); - else if (type == DT_SYMBOL) vp->outlet->send(*(t_symbol **)(((char *)vec) + onset)); - else error("%s.%s is not a number or symbol", t->sym->name, vp->sym->name); - } else error("%s.%s: no such field", t->sym->name, vp->sym->name); - } -} - -static void get_free(t_get *x) {free(x->variables);} - -/* ---------------------- set ----------------------------- */ - -static t_class *set_class; - -struct t_setvariable { - t_symbol *sym; - union word w; -}; - -struct t_set : t_object { - t_gpointer gp; - t_symbol *tsym; - int nin; - int issymbol; - t_setvariable *variables; -}; - -static void *set_new(t_symbol *why, int argc, t_atom *argv) { - t_set *x = (t_set *)pd_new(set_class); - if (argc && (argv[0].a_type == A_SYMBOL) && !strcmp(argv[0].a_symbol->name,"-symbol")) { - x->issymbol = 1; - argc--; - argv++; - } - else x->issymbol = 0; - x->tsym = canvas_makebindsym(atom_getsymbolarg(0, argc, argv)); - if (argc) argc--, argv++; - t_setvariable *sp = x->variables = (t_setvariable *)getbytes(argc * sizeof (*x->variables)); - x->nin = argc; - if (argc) { - for (int i=0; i<argc; i++, sp++) { - sp->sym = atom_getsymbolarg(i, argc, argv); - if (x->issymbol) sp->w.w_symbol = &s_; - else sp->w.w_float = 0; - if (i) { - if (x->issymbol) symbolinlet_new(x,&sp->w.w_symbol); - else floatinlet_new(x, &sp->w.w_float); - } - } - } - pointerinlet_new(x,&x->gp); - gpointer_init(&x->gp); - return x; -} - -static void set_bang(t_set *x) { - int nitems = x->nin; - t_template *t = template_findbyname(x->tsym); - t_gpointer *gp = &x->gp; - TEMPLATE_CHECK(x->tsym,) - if (!gpointer_check(gp, 0)) {error("empty pointer"); return;} - if (gpointer_gettsym(gp) != x->tsym) { - error("%s: got wrong template (%s)",x->tsym->name,gpointer_gettsym(gp)->name); - return; - } - if (!nitems) return; - t_word *vec = gpointer_word(gp); - t_setvariable *vp=x->variables; - if (x->issymbol) for (int i=0; i<nitems; i++,vp++) template_setsymbol(t, vp->sym, vec, vp->w.w_symbol, 1); - else for (int i=0; i<nitems; i++,vp++) template_setfloat(t, vp->sym, vec, vp->w.w_float, 1); - scalar_redraw(gp->scalar, gpointer_getcanvas(gp)); /* but ought to use owner_array->gp.scalar */ -} - -static void set_float(t_set *x, t_float f) { - if (x->nin && !x->issymbol) {x->variables[0].w.w_float = f; set_bang(x);} - else error("type mismatch or no field specified"); -} -static void set_symbol(t_set *x, t_symbol *s) { - if (x->nin && x->issymbol) {x->variables[0].w.w_symbol = s; set_bang(x);} - else error("type mismatch or no field specified"); -} - -static void set_free(t_set *x) { - free(x->variables); - gpointer_unset(&x->gp); -} - -/* ---------------------- elem ----------------------------- */ - -static t_class *elem_class; - -struct t_elem : t_object { - t_symbol *tsym; - t_symbol *fieldsym; - t_gpointer gp; - t_gpointer gparent; -}; - -static void *elem_new(t_symbol *tsym, t_symbol *fieldsym) { - t_elem *x = (t_elem *)pd_new(elem_class); - x->tsym = canvas_makebindsym(tsym); - x->fieldsym = fieldsym; - gpointer_init(&x->gp); - gpointer_init(&x->gparent); - pointerinlet_new(x,&x->gparent); - outlet_new(x,&s_pointer); - return x; -} - -static void elem_float(t_elem *x, t_float f) { - int indx = (int)f, nitems, onset; - t_symbol *fieldsym = x->fieldsym, *elemtsym; - t_template *t = template_findbyname(x->tsym); - t_template *elemtemplate; - t_gpointer *gparent = &x->gparent; - t_array *array; - int elemsize, type; - if (!gpointer_check(gparent, 0)) {error("empty pointer"); return;} - if (gpointer_gettsym(gparent) != x->tsym) { - error("%s: got wrong template (%s)", x->tsym->name, gpointer_gettsym(gparent)->name); - return; - } - t_word *w = gpointer_word(gparent); - TEMPLATE_CHECK(x->tsym,) - if (!template_find_field(t, fieldsym, &onset, &type, &elemtsym)) { - error("couldn't find array field %s", fieldsym->name); - return; - } - if (type != DT_ARRAY) {error("element: field %s not of type array", fieldsym->name); return;} - if (!(elemtemplate = template_findbyname(elemtsym))) { - error("couldn't find field template %s", elemtsym->name); - return; - } - elemsize = elemtemplate->n * sizeof(t_word); - array = *(t_array **)(((char *)w) + onset); - nitems = array->n; - if (indx < 0) indx = 0; - if (indx >= nitems) indx = nitems-1; - gpointer_setarray(&x->gp, array, (t_word *)&array->vec[indx*elemsize]); - x->outlet->send(&x->gp); -} - -static void elem_free(t_elem *x, t_gpointer *gp) { - gpointer_unset(&x->gp); - gpointer_unset(&x->gparent); -} - -/* ---------------------- getsize ----------------------------- */ - -static t_class *getsize_class; - -struct t_getsize : t_object { - t_symbol *tsym; - t_symbol *fieldsym; -}; - -static void *getsize_new(t_symbol *tsym, t_symbol *fieldsym) { - t_getsize *x = (t_getsize *)pd_new(getsize_class); - x->tsym = canvas_makebindsym(tsym); - x->fieldsym = fieldsym; - outlet_new(x,&s_float); - return x; -} - -static void getsize_pointer(t_getsize *x, t_gpointer *gp) { - int onset, type; - t_symbol *fieldsym = x->fieldsym, *elemtsym; - t_template *t = template_findbyname(x->tsym); - TEMPLATE_CHECK(x->tsym,) - if (!template_find_field(t, fieldsym, &onset, &type, &elemtsym)) { - error("couldn't find array field %s", fieldsym->name); - return; - } - if (type != DT_ARRAY) {error("field %s not of type array", fieldsym->name); return;} - if (!gpointer_check(gp, 0)) {error("stale or empty pointer"); return;} - if (gpointer_gettsym(gp) != x->tsym) { - error("%s: got wrong template (%s)", x->tsym->name, gpointer_gettsym(gp)->name); - return; - } - t_word *w = gpointer_word(gp); - t_array *array = *(t_array **)(((char *)w) + onset); - x->outlet->send(float(array->n)); -} - -/* ---------------------- setsize ----------------------------- */ - -static t_class *setsize_class; - -struct t_setsize : t_object { - t_symbol *tsym; - t_symbol *fieldsym; - t_gpointer gp; -}; - -static void *setsize_new(t_symbol *tsym, t_symbol *fieldsym, t_floatarg newsize) { - t_setsize *x = (t_setsize *)pd_new(setsize_class); - x->tsym = canvas_makebindsym(tsym); - x->fieldsym = fieldsym; - gpointer_init(&x->gp); - pointerinlet_new(x,&x->gp); - return x; -} - -static void setsize_float(t_setsize *x, t_float f) { - int onset, type; - t_template *t = template_findbyname(x->tsym); - int newsize = (int)f; - t_gpointer *gp = &x->gp; - if (!gpointer_check(&x->gp, 0)) {error("empty pointer"); return;} - if (gpointer_gettsym(&x->gp) != x->tsym) { - error("%s: got wrong template (%s)", x->tsym->name, gpointer_gettsym(&x->gp)->name); - return; - } - t_word *w = gpointer_word(gp); - TEMPLATE_CHECK(x->tsym,) - t_symbol *elemtsym; - if (!template_find_field(t, x->fieldsym, &onset, &type, &elemtsym)) { - error("couldn't find array field %s", x->fieldsym->name); - return; - } - if (type != DT_ARRAY) {error("field %s not of type array", x->fieldsym->name); return;} - t_template *elemtemplate = template_findbyname(elemtsym); - if (!elemtemplate) { - error("couldn't find field template %s", elemtsym->name); - return; - } - int elemsize = elemtemplate->n * sizeof(t_word); - t_array *array = *(t_array **)(((char *)w) + onset); - if (elemsize != array->elemsize) bug("setsize_gpointer"); - int nitems = array->n; - if (newsize < 1) newsize = 1; - if (newsize == nitems) return; - - /* here there was something to erase the array before resizing it */ - - /* now do the resizing and, if growing, initialize new scalars */ - array->vec = (char *)resizealignedbytes(array->vec, elemsize * nitems, elemsize * newsize); - array->n = newsize; - if (newsize > nitems) { - char *newelem = &array->vec[nitems*elemsize]; - int nnew = newsize - nitems; - while (nnew--) { - word_init((t_word *)newelem, elemtemplate, gp); - newelem += elemsize; - } - } - gobj_changed(gpointer_getscalar(gp),0); -} - -static void setsize_free(t_setsize *x) {gpointer_unset(&x->gp);} - -/* ---------------------- append ----------------------------- */ - -static t_class *append_class; - -struct t_appendvariable { - t_symbol *sym; - t_float f; -}; - -struct t_append : t_object { - t_gpointer gp; - t_symbol *tsym; - int nin; - t_appendvariable *variables; -}; - -static void *append_new(t_symbol *why, int argc, t_atom *argv) { - t_append *x = (t_append *)pd_new(append_class); - x->tsym = canvas_makebindsym(atom_getsymbolarg(0, argc, argv)); - if (argc) argc--, argv++; - x->variables = (t_appendvariable *)getbytes(argc * sizeof (*x->variables)); - x->nin = argc; - if (argc) { - t_appendvariable *sp = x->variables; - for (int i=0; i<argc; i++, sp++) { - sp->sym = atom_getsymbolarg(i, argc, argv); - sp->f = 0; - if (i) floatinlet_new(x,&sp->f); - } - } - pointerinlet_new(x,&x->gp); - outlet_new(x,&s_pointer); - gpointer_init(&x->gp); - return x; -} - -static void append_float(t_append *x, t_float f) { - int nitems = x->nin; - t_template *t = template_findbyname(x->tsym); - t_gpointer *gp = &x->gp; - TEMPLATE_CHECK(x->tsym,) - if (!gp->o) {error("no current pointer"); return;} - if (gp->o->_class == array_class) {error("lists only, not arrays"); return;} - t_canvas *canvas = gp->canvas; - if (!nitems) return; - x->variables[0].f = f; - t_scalar *sc = scalar_new(canvas,x->tsym); - if (!sc) {error("%s: couldn't create scalar", x->tsym->name); return;} - canvas->boxes->add(sc); - gobj_changed(sc,0); - gp->scalar = sc; - t_word *vec = sc->v; - t_appendvariable *vp=x->variables; - for (int i=0; i<nitems; i++,vp++) template_setfloat(t, vp->sym, vec, vp->f, 1); - scalar_redraw(sc, canvas); - x->outlet->send(gp); -} - -static void append_free(t_append *x) { - free(x->variables); - gpointer_unset(&x->gp); -} - -/* ---------------------- sublist ----------------------------- */ - -static t_class *sublist_class; - -struct t_sublist : t_object { - t_symbol *tsym; - t_symbol *fieldsym; - t_gpointer gp; -}; - -static void *sublist_new(t_symbol *tsym, t_symbol *fieldsym) { - t_sublist *x = (t_sublist *)pd_new(sublist_class); - x->tsym = canvas_makebindsym(tsym); - x->fieldsym = fieldsym; - gpointer_init(&x->gp); - outlet_new(x,&s_pointer); - return x; -} - -static void sublist_pointer(t_sublist *x, t_gpointer *gp) { - t_symbol *dummy; - t_template *t = template_findbyname(x->tsym); - int onset, type; - TEMPLATE_CHECK(x->tsym,) - if (!gpointer_check(gp, 0)) {error("stale or empty pointer"); return;} - if (!template_find_field(t, x->fieldsym, &onset, &type, &dummy)) { - error("couldn't find field %s", x->fieldsym->name); - return; - } - if (type != DT_CANVAS) {error("field %s not of type list", x->fieldsym->name); return;} - t_word *w = gpointer_word(gp); - gpointer_setcanvas(&x->gp, *(t_canvas **)(((char *)w) + onset), 0); - x->outlet->send(&x->gp); -} - -static void sublist_free(t_sublist *x, t_gpointer *gp) {gpointer_unset(&x->gp);} - -static void g_traversal_setup() { - t_class *c = ptrobj_class = class_new2("pointer",ptrobj_new,ptrobj_free,sizeof(t_ptrobj),0,"*"); - class_addmethod2(c, ptrobj_traverse,"traverse", "s"); - class_addmethod2(c, ptrobj_next,"next",""); - class_addmethod2(c, ptrobj_vnext,"vnext","F"); - class_addmethod2(c, ptrobj_sendwindow,"send-window","*"); - class_addmethod2(c, ptrobj_rewind, "rewind",""); - class_addpointer(c, ptrobj_pointer); - class_addbang(c, ptrobj_bang); - get_class = class_new2("get",get_new,get_free,sizeof(t_get),0,"*"); - class_addpointer(get_class, get_pointer); - set_class = class_new2("set",set_new,set_free,sizeof(t_set),0,"*"); - class_addfloat(set_class, set_float); - class_addsymbol(set_class, set_symbol); - class_addbang(set_class, set_bang); - elem_class = class_new2("element",elem_new,elem_free,sizeof(t_elem),0,"SS"); - class_addfloat(elem_class, elem_float); - getsize_class = class_new2("getsize",getsize_new,0,sizeof(t_getsize),0,"SS"); - class_addpointer(getsize_class, getsize_pointer); - setsize_class = class_new2("setsize",setsize_new,setsize_free,sizeof(t_setsize),0,"SSFF"); - class_addfloat(setsize_class, setsize_float); - append_class = class_new2("append",append_new,append_free,sizeof(t_append),0,"*"); - class_addfloat(append_class, append_float); - sublist_class = class_new2("sublist",sublist_new,sublist_free,sizeof(t_sublist),0,"SS"); - class_addpointer(sublist_class, sublist_pointer); -} - -/*EXTERN*/ void canvas_savecontainerto(t_canvas *x, t_binbuf *b); - -struct t_iemgui : t_object { - t_canvas *canvas; - int h,w; - int ldx,ldy; - int isa; /* bit 0: loadinit; bit 20: scale */ - int font_style, fontsize; - int fcol,bcol,lcol; /* foreground, background, label colors */ - t_symbol *snd,*rcv,*lab; /* send, receive, label symbols */ -}; - -struct t_bng : t_iemgui { - int count; - int ftbreak; /* flash time break (ms) */ - int fthold; /* flash time hold (ms) */ -}; - -struct t_slider : t_iemgui { - t_float val; - t_float min,max; - int steady; - int is_log; - int orient; -}; - -struct t_radio : t_iemgui { - int on, on_old; - int change; - int number; - t_atom at[2]; - int orient; - int oldstyle; -}; - -struct t_toggle : t_iemgui { - float on; - float nonzero; -}; - -struct t_cnv : t_iemgui { - t_atom at[3]; - int vis_w, vis_h; -}; - -struct t_vu : t_iemgui { - int led_size; - int peak,rms; - float fp,fr; - int scale; -}; - -struct t_nbx : t_iemgui { - double val; - double min,max; - double k; - char buf[32]; - int log_height; - int change; - int is_log; -}; - -struct t_foo { int argc; t_atom *argv; t_binbuf *b; }; -static int pd_pickle(t_foo *foo, const char *fmt, ...); -static int pd_savehead(t_binbuf *b, t_iemgui *x, const char *name); - -static t_class *radio_class, *slider_class; -static t_symbol *sym_hdl, *sym_hradio, *sym_vdl, *sym_vradio, *sym_vsl, *sym_vslider; - -t_class *dummy_class; -/*static*/ t_class *text_class; -static t_class *mresp_class; -static t_class *message_class; -static t_class *gatom_class; - -void canvas_text(t_canvas *gl, t_symbol *s, int argc, t_atom *argv) { - t_text *x = (t_text *)pd_new(text_class); - x->binbuf = binbuf_new(); - x->x = atom_getintarg(0, argc, argv); - x->y = atom_getintarg(1, argc, argv); - if (argc > 2) binbuf_restore(x->binbuf, argc-2, argv+2); - canvas_add(gl,x); - pd_set_newest(x); -} - -void canvas_getargs(int *argcp, t_atom **argvp) { - t_canvasenvironment *e = canvas_getenv(canvas_getcurrent()); - *argcp = e->argc; - *argvp = e->argv; -} - -static void canvas_objtext(t_canvas *gl, int xpix, int ypix, t_binbuf *b, int index=-1) { - t_text *x=0; - int argc, n; - t_atom *argv; - char *s; - newest = 0; - binbuf_gettext(b,&s,&n); - pd_pushsym(gl); - canvas_getargs(&argc, &argv); - binbuf_eval(b, &pd_objectmaker, argc, argv); - if (binbuf_getnatom(b)) { - if (!newest) { - char *s = binbuf_gettext2(b); - error("couldn't create %s",s); - free(s); - } else if (!(x = pd_checkobject(newest))) { - char *s = binbuf_gettext2(b); - error("didn't return a patchable object: %s",s); - free(s); - } - } - /* make a "broken object", that is, one that should appear with a dashed contour. */ - if (!x) { - x = (t_text *)pd_new(dummy_class); - pd_set_newest(x); - } - x->binbuf = b; - x->x = xpix; - x->y = ypix; - canvas_add(gl,x,index); - if (x->_class== vinlet_class) canvas_resortinlets(canvas_getcanvas(gl)); - if (x->_class==voutlet_class) canvas_resortoutlets(canvas_getcanvas(gl)); - pd_popsym(gl); -} - -void canvas_obj(t_canvas *gl, t_symbol *s, int argc, t_atom *argv) { - t_binbuf *b = binbuf_new(); - if (argc >= 2) { - binbuf_restore(b, argc-2, argv+2); - canvas_objtext(gl, atom_getintarg(0, argc, argv), atom_getintarg(1, argc, argv), b); - } else canvas_objtext(gl,0,0,b); -} - -void canvas_objfor(t_canvas *gl, t_text *x, int argc, t_atom *argv) { - x->binbuf = binbuf_new(); - x->x = atom_getintarg(0, argc, argv); - x->y = atom_getintarg(1, argc, argv); - if (argc > 2) binbuf_restore(x->binbuf, argc-2, argv+2); - canvas_add(gl,x); -} - -struct t_mresp : t_pd { - t_outlet *outlet; -}; -struct t_message : t_text { - t_mresp mresp; - t_canvas *canvas; -}; - -/* where is mresp_pointer ? */ -static void mresp_bang(t_mresp *x) {x->outlet->send();} -static void mresp_float( t_mresp *x, t_float v) {x->outlet->send(v);} -static void mresp_symbol( t_mresp *x, t_symbol *v) {x->outlet->send(v);} -static void mresp_list(t_mresp *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send( argc,argv);} -static void mresp_anything(t_mresp *x, t_symbol *s, int argc, t_atom *argv) {x->outlet->send(s,argc,argv);} - -static void message_bang(t_message *x) { binbuf_eval(x->binbuf,&x->mresp,0,0);} -static void message_float(t_message *x, t_float f) {t_atom at; SETFLOAT(&at, f); binbuf_eval(x->binbuf,&x->mresp,1,&at);} -static void message_symbol(t_message *x, t_symbol *s) {t_atom at; SETSYMBOL(&at, s); binbuf_eval(x->binbuf,&x->mresp,1,&at);} -static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv){binbuf_eval(x->binbuf, &x->mresp, argc, argv);} -static void message_add2(t_message *x, t_symbol *s, int argc, t_atom *argv){binbuf_add(x->binbuf, argc, argv); gobj_changed(x,"binbuf");} -static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv) {binbuf_clear(x->binbuf); message_add2(x,s,argc,argv);} -static void message_add(t_message *x, t_symbol *s, int argc, t_atom *argv) -{binbuf_add(x->binbuf, argc, argv); binbuf_addsemi(x->binbuf); gobj_changed(x,"binbuf");} -static void message_addcomma(t_message *x) -{t_atom a; SETCOMMA(&a); binbuf_add(x->binbuf, 1, &a); gobj_changed(x,"binbuf");} -static void message_adddollar(t_message *x, t_floatarg f) -{t_atom a; SETDOLLAR(&a, f<0?0:(int)f); binbuf_add(x->binbuf, 1, &a); gobj_changed(x,"binbuf");} -//static void message_adddollsym(t_message *x, t_symbol *s) -//{t_atom a; SETDOLLSYM(&a, s); binbuf_add(x->binbuf, 1, &a); gobj_changed(x,"binbuf");} - -static void message_adddollsym(t_message *x, t_symbol *s) { - t_atom a; - SETDOLLSYM(&a, symprintf("$%s",s->name)); - binbuf_add(x->binbuf, 1, &a); - gobj_changed(x,"binbuf"); -} - -static void message_addsemi(t_message *x) {message_add(x,0,0,0);} - -void canvas_msg(t_canvas *gl, t_symbol *s, int argc, t_atom *argv) { - t_message *x = (t_message *)pd_new(message_class); - x->mresp._class = mresp_class; - x->mresp.outlet = outlet_new(x,&s_float); - x->binbuf = binbuf_new(); - x->canvas = gl; - pd_set_newest(x); - if (argc > 1) { - x->x = atom_getintarg(0, argc, argv); - x->y = atom_getintarg(1, argc, argv); - if (argc > 2) binbuf_restore(x->binbuf, argc-2, argv+2); - } else { - x->x = 0; - x->y = 0; - } - canvas_add(gl,x); -} - -struct t_gatom : t_text { - t_atom atom; /* this holds the value and the type */ - t_canvas *canvas; /* owning canvas */ - t_float max,min; - t_symbol *label; /* symbol to show as label next to box */ - t_symbol *rcv; - t_symbol *snd; - char wherelabel; /* 0-3 for left, right, up, down */ - t_symbol *expanded_to; /* snd after $0, $1, ... expansion */ - short width; -}; - -/* prepend "-" as necessary to avoid empty strings, so we can use them in Pd messages. - A more complete solution would be to introduce some quoting mechanism; - but then we'd be much more complicated. */ -static t_symbol *gatom_escapit(t_symbol *s) { - if (!s || !*s->name) return gensym("-"); - if (*s->name == '-') { - char shmo[1000]; - snprintf(shmo,1000,"-%s",s->name); - shmo[999] = 0; - return gensym(shmo); - } - else return s; -} - -/* undo previous operation: strip leading "-" if found. */ -static t_symbol *gatom_unescapit(t_symbol *s) { - if (*s->name == '-') return gensym(s->name+1); - return s; -} - -static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv) { - t_atom oldatom = x->atom; - if (!argc) return; - if (x->atom.a_type == A_FLOAT) { - SETFLOAT( &x->atom,atom_getfloat(argv)); if (x->atom.a_float !=oldatom.a_float ) gobj_changed(x,"atom"); - } else if (x->atom.a_type == A_SYMBOL) { - SETSYMBOL(&x->atom,atom_getsymbol(argv)); if (x->atom.a_symbol!=oldatom.a_symbol) gobj_changed(x,"atom"); - } -} - -static void gatom_bang(t_gatom *x) { - t_symbol *s = x->expanded_to; - t_outlet *o = x->outlet; - if (x->atom.a_type == A_FLOAT) { - if (o) o->send(x->atom.a_float); - if (*s->name && s->thing) {if (x->snd == x->rcv) goto err; pd_float(s->thing, x->atom.a_float);} - } else if (x->atom.a_type == A_SYMBOL) { - if (o) o->send(x->atom.a_symbol); - if (*s->name && s->thing) {if (x->snd == x->rcv) goto err; pd_symbol(s->thing, x->atom.a_symbol);} - } - return; -err: - error("%s: atom with same send/receive name (infinite loop)", x->snd->name); -} - -static void gatom_float(t_gatom *x, t_float f) {t_atom at; SETFLOAT( &at, f); gatom_set(x, 0, 1, &at); gatom_bang(x);} -static void gatom_symbol(t_gatom *x, t_symbol *s) {t_atom at; SETSYMBOL(&at, s); gatom_set(x, 0, 1, &at); gatom_bang(x);} - -static void gatom_reload(t_gatom *x, t_symbol *sel, int argc, t_atom *argv) { - int width; t_float wherelabel; - t_symbol *rcv,*snd; - if (!pd_scanargs(argc,argv,"ifffaaa",&width,&x->min,&x->max,&wherelabel,&x->label,&rcv,&snd)) return; - gobj_changed(x,0); - SET(label,gatom_unescapit(x->label)); - if (x->min>=x->max) {SET(min,0); SET(max,0);} - CLAMP(width,1,80); - SET(width,width); - SET(wherelabel,(int)wherelabel&3); - if (x->rcv) pd_unbind(x, canvas_realizedollar(x->canvas, x->rcv)); - SET(rcv,gatom_unescapit(rcv)); - if (x->rcv) pd_bind( x, canvas_realizedollar(x->canvas, x->rcv)); - SET(snd,gatom_unescapit(snd)); - SET(expanded_to,canvas_realizedollar(x->canvas, x->snd)); -} - -/* We need a list method because, since there's both an "inlet" and a - "nofirstin" flag, the standard list behavior gets confused. */ -static void gatom_list(t_gatom *x, t_symbol *s, int argc, t_atom *argv) { - if (!argc) gatom_bang(x); - else if (argv->a_type == A_FLOAT) gatom_float(x, argv->a_w.w_float); - else if (argv->a_type == A_SYMBOL) gatom_symbol(x, argv->a_w.w_symbol); - else error("gatom_list: need float or symbol"); -} - -void canvas_atom(t_canvas *gl, t_atomtype type, int argc, t_atom *argv) { - t_gatom *x = (t_gatom *)pd_new(gatom_class); - if (type == A_FLOAT) {SET(width, 5); SETFLOAT(&x->atom, 0);} - else {SET(width,10); SETSYMBOL(&x->atom, &s_symbol);} - x->canvas = gl; - SET(min,0); - SET(max,0); - SET(wherelabel,0); - SET(label,0); - SET(rcv,0); - SET(snd,0); - x->expanded_to = &s_; //??? - x->binbuf = binbuf_new(); - binbuf_add(x->binbuf, 1, &x->atom); - SET(x,atom_getintarg(0, argc, argv)); - SET(y,atom_getintarg(1, argc, argv)); - inlet_new(x,x,0,0); - outlet_new(x, type == A_FLOAT ? &s_float: &s_symbol); - if (argc>2) gatom_reload(x,&s_,argc-2,argv+2); - canvas_add(gl,x); - pd_set_newest(x); -} - -void canvas_floatatom( t_canvas *gl, t_symbol *s, int argc, t_atom *argv) {canvas_atom(gl, A_FLOAT, argc, argv);} -void canvas_symbolatom(t_canvas *gl, t_symbol *s, int argc, t_atom *argv) {canvas_atom(gl, A_SYMBOL, argc, argv);} -static void gatom_free(t_gatom *x) {if (x->rcv) pd_unbind(x, canvas_realizedollar(x->canvas, x->rcv));} - -extern "C" void text_save(t_gobj *z, t_binbuf *b) { - t_text *x = (t_text *)z; - t_canvas *c = (t_canvas *)z; /* in case it is */ - if (x->_class == message_class) { - binbuf_addv(b,"ttii","#X","msg", (t_int)x->x, (t_int)x->y); - binbuf_addbinbuf(b, x->binbuf); - } else if (x->_class == gatom_class) { - t_gatom *g = (t_gatom *)x; - t_symbol *sel = g->atom.a_type==A_SYMBOL? gensym("symbolatom") : gensym("floatatom"); - binbuf_addv(b,"tsii","#X", sel, (t_int)x->x, (t_int)x->y); - binbuf_addv(b,"iffi", (t_int)g->width, g->min, g->max, (t_int)g->wherelabel); - binbuf_addv(b,"sss", gatom_escapit(g->label), gatom_escapit(g->rcv), gatom_escapit(g->snd)); - } else if (x->_class == text_class) { - binbuf_addv(b, "ttii","#X","text", (t_int)x->x, (t_int)x->y); - binbuf_addbinbuf(b, x->binbuf); - } else { - if (zgetfn(x,gensym("saveto")) && !(x->_class==canvas_class && (canvas_isabstraction(c) || canvas_istable(c)))) { - mess1(x,gensym("saveto"),b); - binbuf_addv(b,"ttii","#X","restore", (t_int)x->x, (t_int)x->y); - } else { - binbuf_addv(b,"ttii","#X","obj", (t_int)x->x, (t_int)x->y); - } - if (x->binbuf) binbuf_addbinbuf(b, x->binbuf); /*else bug("binbuf missing at #X restore !!!");*/ - } - binbuf_addv(b, ";"); -} - -static t_binbuf *canvas_cut_wires(t_canvas *x, t_gobj *o) { - t_binbuf *buf = binbuf_new(); - canvas_wires_each(oc,t,x) { - if ((o==t.from) != (o==t.to)) - binbuf_addv(buf,"ttiiii;","#X","connect", t.from->dix->index, t.outlet, t.to->dix->index, t.inlet); - } - return buf; -} -static void canvas_paste_wires(t_canvas *x, t_binbuf *buf) { - pd_bind(x,gensym("#X")); - binbuf_eval(buf,0,0,0); - pd_unbind(x,gensym("#X")); -} - -static void text_setto(t_text *x, t_canvas *canvas, char *buf, int bufsize) { - if (x->_class == message_class || x->_class == gatom_class || x->_class == text_class) { - binbuf_text(x->binbuf, buf, bufsize); - gobj_changed(x,"binbuf"); - pd_set_newest(x); - return; - } - t_binbuf *b = binbuf_new(); - binbuf_text(b, buf, bufsize); - int natom1 = binbuf_getnatom(x->binbuf); t_atom *vec1 = binbuf_getvec(x->binbuf); - int natom2 = binbuf_getnatom(b); t_atom *vec2 = binbuf_getvec(b); - /* special case: if pd args change just pass the message on. */ - if (natom1 >= 1 && natom2 >= 1 && - vec1[0].a_type == A_SYMBOL && vec1[0].a_symbol == s_pd && - vec2[0].a_type == A_SYMBOL && vec2[0].a_symbol == s_pd) { - typedmess(x,gensym("rename"),natom2-1,vec2+1); - binbuf_free(x->binbuf); - x->binbuf = b; - pd_set_newest(x); /* fake object creation, for simplicity of client */ - } else { - int xwas=x->x, ywas=x->y; - int backupi = x->dix->index; - t_binbuf *buf = canvas_cut_wires(canvas_getcanvas(canvas),x); - canvas_delete(canvas,x); - canvas_objtext(canvas,xwas,ywas,b,backupi); - t_pd *backup = newest; - post("backupi=%d newest->index=%ld",backupi,((t_object *)newest)->dix->index); - if (newest && pd_class(newest) == canvas_class) canvas_loadbang((t_canvas *)newest); - canvas_paste_wires(canvas_getcanvas(canvas), buf); - newest = backup; - } -} - -t_object *symbol2opointer(t_symbol *s) { - t_text *o; - if (sscanf(s->name,"x%lx",(long*)&o)<1) {error("expected object-id"); return 0;} - if (!object_table->exists(o)) {error("%s target is not a currently valid pointer",s->name); return 0;} - if ((object_table->get(o)&1)==0) { - error("%s target is zombie? object_table says '%ld'",s->name,object_table->get(o)); - return 0; - } - if (!o->_class->patchable) {error("%s target not a patchable object",s->name); return 0;} - return o; -} - -t_object *atom2opointer(t_atom *a) {return symbol2opointer(atom_getsymbol(a));} - -static void canvas_text_setto(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - t_text *o = atom2opointer(&argv[0]); if (!o) return; - char str[4096]; - for (int i=0; i<argc-1; i++) str[i] = atom_getint(argv+i+1); - str[argc-1]=0; - text_setto(o,x,str,argc-1); -} - -static void canvas_object_moveto(t_canvas *x, t_symbol *name, t_floatarg px, t_floatarg py) { - t_text *o = symbol2opointer(name); if (!o) return; - o->x=(int)px; gobj_changed(o,"x"); - o->y=(int)py; gobj_changed(o,"y"); -} -static void canvas_object_delete(t_canvas *x, t_symbol *name) { - t_text *o = symbol2opointer(name); if (!o) return; - fprintf(stderr,"canvas_object_delete %p\n",o); - canvas_delete(x,o); -} - -static void canvas_object_get_tips(t_canvas *x, t_symbol *name) { - t_text *o = symbol2opointer(name); if (!o) return; - std::ostringstream foo; - if (o->_class->firstin) foo << o->_class->firsttip->name; - int n = obj_ninlets(x); - for (int i=!!o->_class->firstin; i<n; i++) foo << " " << inlet_tip(o->inlet,i); - sys_mgui(o,"tips=","S",foo.str().data()); -} - -extern "C" void open_via_helppath(const char *name, const char *dir); -static void canvas_object_help(t_canvas *x, t_symbol *name) { - t_text *o = symbol2opointer(name); if (!o) return; - const char *hn = class_gethelpname(o->_class); - bool suffixed = strcmp(hn+strlen(hn)-3, ".pd")==0; - char *buf; - asprintf(&buf,"%s%s",hn,suffixed?"":".pd"); - open_via_helppath(buf, o->_class->externdir->name); - free(buf); -} - -static void canvas_reorder_last(t_canvas *x, int dest) { - int i = x->boxes->last()->dix->index; - t_gobj *foo = x->boxes->get(i); - x->boxes->remove(i); - fprintf(stderr,"canvas_reorder_last(x=%p,dest=%d) i=%d\n",x,dest,i); - fprintf(stderr,"foo=%p\n",foo); - if (!foo) {bug("couldn't remove box #%d",i); return;} - foo->dix->index = dest; - x->boxes->add(foo); -} - -/* this supposes that $2=#X */ -static void canvas_object_insert(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - if (argc<1) {error("not enough args"); return;} - if (argv[0].a_type != A_FLOAT) {error("$1 must be float"); return;} - int i = atom_getint(argv); - if (argv[2].a_type != A_SYMBOL) {error("$2 must be symbol"); return;} - s = argv[2].a_symbol; - pd_typedmess(x,s,argc-3,argv+3); - canvas_reorder_last(x,i); -/*err: pd_popsym(x);*/ -} - -static void g_text_setup() { - t_class *c; - text_class = class_new2("text", 0,0,sizeof(t_text),CLASS_NOINLET|CLASS_PATCHABLE,0); - dummy_class = class_new2("dummy",0,0,sizeof(t_text),CLASS_NOINLET|CLASS_PATCHABLE,0); - - c = mresp_class = class_new2("messresponder",0,0,sizeof(t_text),CLASS_PD,""); - class_addbang( c, mresp_bang); - class_addfloat( c, (t_method) mresp_float); - class_addsymbol( c, mresp_symbol); - class_addlist( c, mresp_list); - class_addanything(c, mresp_anything); - - c = message_class = class_new2("message",0,0,sizeof(t_message),CLASS_PATCHABLE,""); - class_addbang(c, message_bang); - class_addfloat(c, message_float); - class_addsymbol(c, message_symbol); - class_addlist(c, message_list); - class_addanything(c, message_list); - class_addmethod2(c, message_set, "set","*"); - class_addmethod2(c, message_add, "add","*"); - class_addmethod2(c, message_add2,"add2","*"); - class_addmethod2(c, message_addcomma, "addcomma", ""); - class_addmethod2(c, message_addsemi, "addsemi", ""); - class_addmethod2(c, message_adddollar, "adddollar", "f"); - class_addmethod2(c, message_adddollsym, "adddollsym","s"); - - c = gatom_class = class_new2("gatom",0,gatom_free,sizeof(t_gatom),CLASS_NOINLET|CLASS_PATCHABLE,""); - class_addbang(c, gatom_bang); - class_addfloat(c, gatom_float); - class_addsymbol(c, gatom_symbol); - class_addlist(c, gatom_list); - class_addmethod2(c, gatom_set, "set","*"); - class_addmethod2(c, gatom_reload, "reload","*"); -} - -static int iemgui_color_hex[]= { - 0xfcfcfc, 0xa0a0a0, 0x404040, 0xfce0e0, 0xfce0c0, 0xfcfcc8, 0xd8fcd8, 0xd8fcfc, 0xdce4fc, 0xf8d8fc, - 0xe0e0e0, 0x7c7c7c, 0x202020, 0xfc2828, 0xfcac44, 0xe8e828, 0x14e814, 0x28f4f4, 0x3c50fc, 0xf430f0, - 0xbcbcbc, 0x606060, 0x000000, 0x8c0808, 0x583000, 0x782814, 0x285014, 0x004450, 0x001488, 0x580050 -}; - -static int iemgui_clip_size(int size) {return max(8,size);} - -int convert_color2(int x) { - return ~ (((0xfc0000&x)>>6) | ((0xfc00&x)>>4) | ((0xfc&x)>>2)); -} - -static int convert_color(int x) { - if (x>=0) return iemgui_color_hex[x%30]; - x=~x; - return ((x&0x3f000)<<6) | ((x&0xfc0)<<4) | ((x&0x3f)<<2); -} - -static void iemgui_send(t_iemgui *x, t_symbol *s) { - SET(snd,canvas_realizedollar(x->canvas, s)); - if (x->snd==s_empty) SET(snd,0); -} - -static void iemgui_receive(t_iemgui *x, t_symbol *s) { - t_symbol *rcv = canvas_realizedollar(x->canvas, s); - if (rcv==s_empty) rcv=0; - if (rcv==x->rcv) return; - if(x->rcv) pd_unbind(x,x->rcv); - SET(rcv,rcv); - if(x->rcv) pd_bind(x,x->rcv); -} - -static void iemgui_label(t_iemgui *x, t_symbol *s) { - SET(lab,s==s_empty?0:s); -} -static void iemgui_label_pos(t_iemgui *x, t_float ldx, t_float ldy) { - SET(ldx,(int)ldx); - SET(ldy,(int)ldy); -} -static void iemgui_label_font(t_iemgui *x, t_symbol *s, int ac, t_atom *av) { - SET(fontsize,max(4,(int)atom_getintarg(1, ac, av))); - SET(font_style,atom_getintarg(0, ac, av)); -} -static void iemgui_delta(t_iemgui *x, t_symbol *s, int ac, t_atom *av) { - SET(x,x->x+(int)atom_getintarg(0, ac, av)); - SET(y,x->y+(int)atom_getintarg(1, ac, av)); -} -static void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av) { - SET(x,x->x+(int)atom_getintarg(0, ac, av)); - SET(y,x->y+(int)atom_getintarg(1, ac, av)); -} - -static int iemgui_compatible_col(int i) {return i>=0 ? iemgui_color_hex[i%30] : (~i)&0xffffff;} - -static void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av) { - int i=0; - SET(bcol,iemgui_compatible_col(atom_getintarg(i++, ac, av))); - if(ac > 2) SET(fcol,iemgui_compatible_col(atom_getintarg(i++, ac, av))); - SET(lcol,iemgui_compatible_col(atom_getintarg(i++, ac, av))); -} - -#define NEXT p=va_arg(val,void*); /*printf("p=%p\n",p);*/ -int pd_vscanargs(int argc, t_atom *argv, const char *fmt, va_list val) { - int optional=0; - int i,j=0; - for (i=0; fmt[i]; i++) { - switch (fmt[i]) { - case 0: error("too many args"); return 0; - case '*': goto break1; /* rest is any type */ - case 'F': case 'f': case 'd': case 'i': case 'c': case 'b': - if (!IS_A_FLOAT(argv,j)) {error("expected float in $%d",i+1); return 0;} - j++; break; - case 'S': case 's': - if (!IS_A_SYMBOL(argv,j)) {error("expected symbol in $%d",i+1); return 0;} - j++; break; - case '?': break; - case 'a': - if (!IS_A_FLOAT(argv,j) && !IS_A_SYMBOL(argv,j)) {error("expected float or symbol in $%d",i+1); return 0;} - j++; break; - case ';': optional=1; break; - default: error("bad format string"); return 0; - } - } - if (j<argc && !optional) {error("not enough args"); return 0;} -break1: - i=0; - for (int j=0; fmt[j] || i<argc; j++) { - void *p; - switch (fmt[j]) { - case ';': continue; /*ignore*/ - case '*': goto break2; - case '?': case 'F': case 'S': break; /* skip */ /* what are those for, again? */ - case 'd': NEXT; *(double*)p = atom_getfloatarg(i,argc,argv); break; - case 'f': NEXT; *(float*)p = atom_getfloatarg(i,argc,argv); break; - case 'i': NEXT; *(int*)p = atom_getintarg(i,argc,argv); break; - case 'b': NEXT; *(int*)p = !!atom_getintarg(i,argc,argv); break; /* 0 or 1 */ - case 'c': NEXT; *(int*)p = convert_color(atom_getintarg(i,argc,argv)); break; /* IEM-style 8:8:8 colour */ - case 's': NEXT; *(t_symbol**)p=atom_getsymbolarg(i,argc,argv); break; - case 'a': NEXT; /* send-symbol, receive-symbol, or IEM-style label */ - if (IS_A_SYMBOL(argv,i)) - *(t_symbol**)p = atom_getsymbolarg(i,argc,argv); - if (*(t_symbol**)p == s_empty) *(t_symbol**)p = 0; - else if (IS_A_FLOAT(argv,i)) { - char str[80]; - sprintf(str, "%d", (int)atom_getintarg(i,argc,argv)); - *(t_symbol**)p = gensym(str); - } - break; - default: post("WARNING: bug using pd_scanargs()"); return 0; /* hmm? */ - } - i++; - } -break2: - return 1; -} - -/* exceptionally we're using pointers for each of the args even though - we are saving. this is so we can copy+paste pd_scanargs lines almost - directly. in the future, this could be merged with pd_scanargs and - made declarative, by storing a list of &(0->blah) relative offsets - into each struct... -*/ -int pd_vsaveargs(t_binbuf *b, const char *fmt, va_list val) { - t_atom a; - int i; - for (i=0; ; i++) { - switch (fmt[i]) { - case 0: goto break2; - case ';': continue; /* skip */ - case '?': case 'F': case 'S': break; /* skip */ - case 'd': SETFLOAT(&a,*(va_arg(val,double*))); break; - case 'f': SETFLOAT(&a,*(va_arg(val,float *))); break; - case 'i': SETFLOAT(&a,*(va_arg(val, int *))); break; - case 'b': SETFLOAT(&a,!!*(va_arg(val,int *))); break; - case 'c': /* colour, from IEM format to RGB 8:8:8 format */ - SETFLOAT(&a,convert_color2(*(va_arg(val, int *)))); break; - case 'a': - case 's': { t_symbol *s = *(va_arg(val,t_symbol**)); - SETSYMBOL(&a,s?s:s_empty); } break; - default: post("WARNING: bug using pd_saveargs()"); goto err; /* WHAT? */ - } - binbuf_add(b,1,&a); - } -break2: - binbuf_addv(b, ";"); - return 1; -err: - post("WARNING: pd_saveargs failed; fmt=%s, i=%d",fmt,i); - return 0; -} - -int pd_scanargs(int argc, t_atom *argv, const char *fmt, ...) { - int i; - va_list val; - va_start(val,fmt); - i=pd_vscanargs(argc,argv,fmt,val); - va_end(val); - return i; -} - -int pd_saveargs(t_binbuf *b, const char *fmt, ...) { - int i; - va_list val; - va_start(val,fmt); - i=pd_vsaveargs(b,fmt,val); - va_end(val); - return i; -} - -int pd_pickle(t_foo *foo, const char *fmt, ...) { - va_list val; - va_start(val,fmt); - int r = foo->b ? - pd_vsaveargs(foo->b,fmt,val) : - pd_vscanargs(foo->argc,foo->argv,fmt,val); - va_end(val); - return r; -} - -static int pd_savehead(t_binbuf *b, t_iemgui *x, const char *name) { - binbuf_addv(b, "ttiit","#X","obj", (t_int)x->x, (t_int)x->y, name); - return 1; -} - -void pd_upload(t_gobj *self) { - long alive = (long)object_table->get(self) & 1; - if (!alive) { - sys_mgui(self,"delete",""); - pd_free_zombie(self); - return; - } - t_binbuf *b = binbuf_new(); - t_class *c = self->_class; - t_text *x = (t_text *)self; - if (c==canvas_class) { - /* just the "#N canvas" line, not the contents */ - canvas_savecontainerto((t_canvas *)self,b); - canvas_savecoordsto((t_canvas *)self,b); /* this may be too early */ - binbuf_addv(b, "ttii", "#X","restore", (t_int)x->x, (t_int)x->y); - if (x->binbuf) { - //pd_print(x,"pd_upload"); - binbuf_addbinbuf(b, x->binbuf); - } else { - /*bug("binbuf missing at #X restore !!!");*/ - } - binbuf_addv(b, ";"); - } else { /* this was outside of the "else" for a while. why? I don't remember */ - c->savefn(self,b); - } - int n; - char *s; - appendix_save(self,b); - binbuf_gettext(b,&s,&n); - if (s[n-1]=='\n') n--; - if (c->patchable) { - sys_vgui("change x%lx x%lx %d {%.*s} %d %d %d\n",(long)self,(long)self->dix->canvas,self->dix->index,n,s, - obj_ninlets((t_text *)self), obj_noutlets((t_text *)self), x->_class!=dummy_class); - } else { - sys_vgui("change x%lx x%lx %d {%.*s}\n",(long)self,(long)self->dix->canvas,self->dix->index,n,s); - } - binbuf_free(b); - free(s); - if (c==canvas_class) { - t_canvas *can = (t_canvas *)self; - sys_mgui(self,"name=","s",can->name); - sys_mgui(self,"folder=","s",canvas_getenv(can)->dir); - sys_mgui(self,"havewindow=","i",can->havewindow); - } - if (c==gatom_class) { - t_gatom *g = (t_gatom *)x; - if (g->atom.a_type==A_SYMBOL) sys_mgui(g,"set","s",g->atom.a_symbol); - else sys_mgui(g,"set","f",g->atom.a_float); - } - if (object_table->exists(self)) { - object_table->set(self,object_table->get(self)|2); /* has been uploaded */ - } else post("object_table is broken"); -} - -void sys_mgui(void *self_, const char *sel, const char *fmt, ...) { - t_gobj *self = (t_gobj *)self_; - char buf[4096]; - int i=0, n=sizeof(buf); - va_list val; - va_start(val,fmt); - i+=snprintf(buf+i,n-i,"x%lx %s", (long)self, sel); - if (i>=n) goto over; - while (*fmt) { - switch (*fmt) { - case 'f': case 'd': i+=snprintf(buf+i,n-i," %f",va_arg(val,double)); break; - case 'i': i+=snprintf(buf+i,n-i," %d",va_arg(val,int)); break; - case 'p': i+=snprintf(buf+i,n-i," x%lx",(long)va_arg(val,void*)); break; - /* - case 's': i+=snprintf(buf+i,n-i," \"%s\"",va_arg(val,t_symbol *)->name); break; - case 'S': i+=snprintf(buf+i,n-i," \"%s\"",va_arg(val,const char *)); break; - */ - case 's': i+=snprintf(buf+i,n-i," {%s}",va_arg(val,t_symbol *)->name); break; - case 'S': i+=snprintf(buf+i,n-i," {%s}",va_arg(val,const char *)); break; - } - if (i>=n) goto over; - fmt++; - } - va_end(val); - i+=snprintf(buf+i,n-i,"\n"); - if (i>=n) goto over; - sys_gui(buf); - return; -over: - post("sys_mgui: can't send: buffer overflow"); - abort(); -} - -static void iemgui_subclass (t_class *c) { - class_addmethod2(c, iemgui_delta, "delta","*"); - class_addmethod2(c, iemgui_pos, "pos","*"); - class_addmethod2(c, iemgui_color, "color","*"); - class_addmethod2(c, iemgui_send, "send","S"); - class_addmethod2(c, iemgui_receive, "receive","S"); - class_addmethod2(c, iemgui_label, "label","S"); - class_addmethod2(c, iemgui_label_pos, "label_pos","ff"); - class_addmethod2(c, iemgui_label_font, "label_font","*"); -} - -t_symbol *pd_makebindsym(t_pd *x) {return symprintf(".x%lx",(long)x);} - -t_iemgui *iemgui_new(t_class *qlass) { - t_iemgui *x = (t_iemgui *)pd_new(qlass); - x->canvas = canvas_getcurrent(); - x->w = x->h = 15; - x->ldx=0; - x->ldy=-6; - x->isa=0; - x->font_style = 0; - x->fontsize = 8; - x->snd = 0; - x->rcv = 0; - x->lab = s_empty; - x->bcol = 0xffffff; - x->fcol = 0x000000; - x->lcol = 0x000000; - pd_bind(x,pd_makebindsym(x)); - return x; -} - -static void iemgui_constrain(t_iemgui *x) { - SET(fontsize,max(x->fontsize,4)); - SET(h,iemgui_clip_size(x->h)); - SET(w,iemgui_clip_size(x->w)); -} - -void iemgui_init(t_iemgui *x, t_floatarg f) {SET(isa,(x->isa&~1)|!!f);} - -void binbuf_update(t_iemgui *x, t_symbol *qlass, int argc, t_atom *argv) { - t_binbuf *buf = x->binbuf; - if (!buf) return; - binbuf_clear(buf); - t_atom foo; - SETSYMBOL(&foo,qlass); - binbuf_add(buf,1,&foo); - binbuf_add(buf,argc,argv); -} - -static /*bool*/ int iemgui_loadbang (t_iemgui *self) { - return !sys_noloadbang && self->isa&1; -} - -static /*bool*/ int iemgui_forward (t_iemgui *self) { - return !self->snd || !self->rcv || self->snd != self->rcv; -} - -static t_class *bng_class; - -static void bng_check_minmax(t_bng *x) { - if(x->ftbreak > x->fthold) { - int h = x->ftbreak; - SET(ftbreak,x->fthold); - SET(fthold,h); - } - SET(ftbreak,max(x->ftbreak,10)); - SET(fthold ,max(x->fthold, 50)); -} - -static void bng_set(t_bng *x) { - SET(count,x->count+1); - sys_mgui(x,"bang","i",x->count); -} - -static void bng_bout2(t_bng *x) { - x->outlet->send(); - if(x->snd && x->snd->thing) pd_bang(x->snd->thing); -} - -static void bng_bang(t_bng *x) { - bng_set(x); - x->outlet->send(); - if(x->snd && x->snd->thing && iemgui_forward(x)) pd_bang(x->snd->thing); -} -static void bng_bang2 (t_bng *x) { {bng_set(x); bng_bout2(x);}} -static void bng_loadbang(t_bng *x) {if(iemgui_loadbang(x)) {bng_set(x); bng_bout2(x);}} - -static void bng_size(t_bng *x, t_symbol *s, int ac, t_atom *av) { - SET(w,iemgui_clip_size((int)atom_getintarg(0, ac, av))); - SET(h,x->w); -} - -static void bng_flashtime(t_bng *x, t_symbol *s, int ac, t_atom *av) { - SET(ftbreak,atom_getintarg(0, ac, av)); - SET(fthold ,atom_getintarg(1, ac, av)); - bng_check_minmax(x); -} - -static int bng_pickle(t_bng *x, t_foo *foo) { - return pd_pickle(foo,"iiiiaaaiiiiccc",&x->w,&x->fthold,&x->ftbreak,&x->isa,&x->snd,&x->rcv,&x->lab, - &x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->fcol,&x->lcol); -} - -static void bng_savefn(t_bng *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,"bng"); bng_pickle(x,&foo); -} - -static void bng_reload(t_bng *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym("bng"),argc,argv); - if (!bng_pickle(x,&foo)) return; - SET(h,x->w); - bng_check_minmax(x); - iemgui_constrain(x); - if (x->rcv) pd_bind(x,x->rcv); -} - -static void *bng_new(t_symbol *s, int argc, t_atom *argv) { - t_bng *x = (t_bng *)iemgui_new(bng_class); - SET(ftbreak,250); - SET(fthold,50); - SET(count,0); - bng_check_minmax(x); - outlet_new(x, &s_bang); - if (argc) bng_reload(x,0,argc,argv); - return x; -} - -static void iemgui_free(t_iemgui *x) { - if(x->rcv) pd_unbind(x,x->rcv); -} - -static t_class *toggle_class; - -static void toggle_action(t_toggle *x) { - x->outlet->send(x->on); - if(x->snd && x->snd->thing) pd_float(x->snd->thing, x->on); -} - -static void toggle_bang(t_toggle *x) {SET(on,x->on?0.0:x->nonzero); toggle_action(x);} -static void toggle_set(t_toggle *x, t_floatarg f) {SET(on,f); if(f) SET(nonzero,f);} -static void toggle_float(t_toggle *x, t_floatarg f) {toggle_set(x,f);if(iemgui_forward(x)) toggle_action(x);} -static void toggle_fout (t_toggle *x, t_floatarg f) {toggle_set(x,f); toggle_action(x);} -static void toggle_loadbang(t_toggle *x) {if(iemgui_loadbang(x)) toggle_fout(x, (float)x->on);} -static void toggle_nonzero(t_toggle *x, t_floatarg f) {if (f) SET(nonzero,f);} - -static void toggle_size(t_toggle *x, t_symbol *s, int ac, t_atom *av) { - SET(w,iemgui_clip_size((int)atom_getintarg(0, ac, av))); - SET(h,x->w); -} - -static int toggle_pickle(t_toggle *x, t_foo *foo) { - return pd_pickle(foo,"iiaaaiiiicccf;f",&x->w,&x->isa,&x->snd,&x->rcv,&x->lab, - &x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->fcol,&x->lcol,&x->on,&x->nonzero); -} - -static void toggle_savefn(t_toggle *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,"tgl"); toggle_pickle(x,&foo); -} - -static void toggle_reload(t_toggle *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym("tgl"),argc,argv); - if (!toggle_pickle(x,&foo)) return; - SET(h,x->w); - SET(on,x->isa&1 && x->on ? x->nonzero : 0.0); - SET(nonzero,argc==14 && IS_A_FLOAT(argv,13) ? atom_getfloatarg(13, argc, argv) : 1.0); - if (!x->nonzero) SET(nonzero,1.0); - iemgui_constrain(x); - if (x->rcv) pd_bind(x,x->rcv); -} - -static void *toggle_new(t_symbol *s, int argc, t_atom *argv) { - t_toggle *x = (t_toggle *)iemgui_new(toggle_class); - SET(on,0.0); - SET(nonzero,1.0); - outlet_new(x, &s_float); - if (argc) toggle_reload(x,0,argc,argv); - return x; -} - -static void radio_set(t_radio *x, t_floatarg f) { - int i=(int)f; - int old=x->on_old; - CLAMP(i,0,x->number-1); - if(x->on!=old) SET(on_old,x->on); - SET(on,i); - if(x->on!=old) SET(on_old,old); -} - -static void radio_send2(t_radio *x, float a, float b) { - SETFLOAT(x->at,a); - SETFLOAT(x->at+1,b); - x->outlet->send(2,x->at); - if(x->snd && x->snd->thing) pd_list(x->snd->thing, &s_list, 2, x->at); -} - -static void radio_send(t_radio *x, float a) { - x->outlet->send(a); - if(x->snd && x->snd->thing) pd_float(x->snd->thing,a); -} - -static void radio_bang(t_radio *x) { - if (x->oldstyle) { - if(x->change && x->on!=x->on_old) radio_send2(x,x->on_old,0.0); - SET(on_old,x->on); - radio_send2(x,x->on,1.0); - } else { - radio_send(x,x->on); - } -} - -static void radio_fout2(t_radio *x, t_floatarg f, int forwardonly) { - int i=(int)f; - CLAMP(i,0,x->number-1); - if (x->oldstyle) { - /* compatibility with earlier "hdial" behavior */ - if(x->change && i!=x->on_old && (!forwardonly || iemgui_forward(x))) radio_send2(x,x->on_old,0.0); - SET(on_old,x->on); - SET(on,i); - SET(on_old,x->on); - radio_send2(x,x->on,1.0); - if (!forwardonly || iemgui_forward(x)) radio_send2(x,x->on,1.0); - } else { - SET(on,i); - if (!forwardonly || iemgui_forward(x)) radio_send(x,x->on); - SET(on_old,x->on); - } -} - -static void radio_fout (t_radio *x, t_floatarg f) {radio_fout2(x,f,0);} -static void radio_float(t_radio *x, t_floatarg f) {radio_fout2(x,f,1);} -static void radio_loadbang(t_radio *x) {if(iemgui_loadbang(x)) radio_bang(x);} -static void radio_orient(t_radio *x,t_floatarg v) {SET(orient,!!v); -post("v=%f, !!v=%d, orient=%d",v,!!v,x->orient);} - -static void radio_number(t_radio *x, t_floatarg num) { - int n=(int)num; - CLAMP(n,1,128); - if (n != x->number) { - SET(number,n); - CLAMP(x->on,0,x->number-1); gobj_changed(x,"on"); - SET(on_old,x->on); - } -} - -static void radio_size(t_radio *x, t_float size) { - SET(w,iemgui_clip_size((int)size)); - SET(h,x->w); -} - -static void radio_double_change(t_radio *x) {SET(change,1);} -static void radio_single_change(t_radio *x) {SET(change,0);} - -static int radio_pickle(t_radio *x, t_foo *foo) { - return pd_pickle(foo, "ibiiaaaiiiiccci",&x->w,&x->change,&x->isa,&x->number,&x->snd,&x->rcv,&x->lab, - &x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->fcol,&x->lcol,&x->on); -} - -static t_symbol *radio_flavor(t_radio *x) { - return x->orient?x->oldstyle?sym_vdl:sym_vradio:x->oldstyle?sym_hdl:sym_hradio; -} - -static void radio_savefn(t_radio *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,radio_flavor(x)->name); - radio_pickle(x,&foo); -} - -static void radio_reload(t_radio *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,radio_flavor(x),argc,argv); - if (!radio_pickle(x,&foo)) return; - iemgui_constrain(x); - if (x->rcv) pd_bind(x,x->rcv); - gobj_changed(x,0); -} - -static void *radio_new(t_symbol *s, int argc, t_atom *argv) { - t_radio *x = (t_radio *)iemgui_new(radio_class); - SET(on_old,0); - SET(on,0); - SET(number,8); - SET(change,1); - if (s==sym_hdl) {SET(orient,0); SET(oldstyle,1);} else - if (s==sym_vdl) {SET(orient,1); SET(oldstyle,1);} else - if (s==sym_hradio) {SET(orient,0); SET(oldstyle,0);} else - if (s==sym_vradio) {SET(orient,1); SET(oldstyle,0);} - SET(on,x->isa&1 ? x->on : 0); - SET(on_old,x->on); - outlet_new(x, &s_list); - if (argc) radio_reload(x,0,argc,argv); - return x; -} - -#define IEM_SL_DEFAULTSIZE 128 -#define IEM_SL_MINSIZE 2 - -static void slider_check_width(t_slider *x, int w) { - double l = (double)(x->orient ? x->h : x->w)-1; - int m = (int)(l*100); - if(w < IEM_SL_MINSIZE) w = IEM_SL_MINSIZE; - if (x->orient) SET(h,w); else SET(w,w); - if(x->val > m) SET(val,m); -} - -static void slider_check_minmax(t_slider *x) { - double min=x->min, max=x->max; - if(x->is_log) { - if(min == 0.0 && max == 0.0) max = 1.0; - if(max > 0.0) { if (min<=0.0) min = 0.01*max; } - else { if (min >0.0) max = 0.01*min; } - } - SET(min,min); - SET(max,max); -} - -// the value/centipixel ratio -static double slider_ratio (t_slider *x) { - double diff = x->is_log ? log(x->max/x->min) : (x->max-x->min); - return diff / (double)(x->orient ? (x->h-1) : (x->w-1)); -} - -static void slider_set(t_slider *x, t_floatarg f) { - if(x->min > x->max) CLAMP(f,x->max,x->min); - else CLAMP(f,x->min,x->max); - SET(val,floor(100.0 * (x->is_log ? log(f/x->min) : (f-x->min)) / slider_ratio(x) + 0.5)); -} - -static void slider_bang(t_slider *x) { - double t = (double)x->val * slider_ratio(x) * 0.01; - double out = x->is_log ? x->min*exp(t) : x->min+t; - if (fabs(out) < 1.0e-10) out = 0.0; - x->outlet->send(out); - if(x->snd && x->snd->thing) pd_float(x->snd->thing, out); -} - -static void slider_size(t_slider *x, t_symbol *s, int ac, t_atom *av) { - int a = atom_getintarg(0,ac,av); - int b = ac>1 ? atom_getintarg(1,ac,av) : 0; - if (x->orient) { - SET(w,iemgui_clip_size(a)); - if(ac>1) slider_check_width(x,b); - } else { - slider_check_width(x,a); - if(ac>1) SET(h,iemgui_clip_size(b)); - } -} - -static void slider_range(t_slider *x, t_float min, t_float max) -{SET(min,min); SET(max,max); slider_check_minmax(x);} -static void slider_lin(t_slider *x) {SET(is_log,0); slider_check_minmax(x);} -static void slider_log(t_slider *x) {SET(is_log,1); slider_check_minmax(x);} -static void slider_steady(t_slider *x, t_floatarg f) {SET(steady,!!f);} -static void slider_float(t_slider *x, t_floatarg f) {slider_set(x,f);if(iemgui_forward(x))slider_bang(x);} -static void slider_loadbang(t_slider *x) {if(iemgui_loadbang(x)) slider_bang(x);} -static void slider_orient(t_slider *x,t_floatarg v) {SET(orient,!!v);} - -static int slider_pickle(t_slider *x, t_foo *foo) { - return pd_pickle(foo, "iiffbiaaaiiiicccf;b", - &x->w,&x->h,&x->min,&x->max,&x->is_log,&x->isa,&x->snd,&x->rcv,&x->lab, - &x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->fcol,&x->lcol,&x->val,&x->steady); -} - -static void slider_savefn(t_slider *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,(char *)(x->orient?"vsl":"hsl")); slider_pickle(x,&foo); -} - -static void slider_reload(t_slider *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym((char *)(x->orient?"vsl":"hsl")),argc,argv); - if (!slider_pickle(x,&foo)) return; -//this is wrong because it should happen when loading a file but not when loading from properties: - SET(val,x->isa&1 ? x->val : 0); -//end wrong. - iemgui_constrain(x); - slider_check_minmax(x); - slider_check_width(x, x->orient ? x->h : x->w); - if(x->rcv) pd_bind(x,x->rcv); - gobj_changed(x,0); -} - -static void *slider_new(t_symbol *s, int argc, t_atom *argv) { - t_slider *x = (t_slider *)iemgui_new(slider_class); - SET(orient,s==sym_vslider||s==sym_vsl); - SET(is_log,0); - SET(min,0.0); - SET(steady,1); - SET(max,(double)(IEM_SL_DEFAULTSIZE-1)); - if (x->orient) SET(h,IEM_SL_DEFAULTSIZE); else SET(w,IEM_SL_DEFAULTSIZE); - outlet_new(x, &s_float); - if (argc) slider_reload(x,0,argc,argv); - return x; -} - -static t_class *nbx_class; - -static void nbx_clip(t_nbx *x) {CLAMP(x->val,x->min,x->max);} - -static int nbx_check_minmax(t_nbx *x) { - double min=x->min, max=x->max; - int val=(int)x->val; - if(x->is_log) { - if(min==0.0 && max==0.0) max = 1.0; - if(max>0.0 && min<=0.0) min = 0.01*max; - if(max<=0.0 && min>0.0) max = 0.01*min; - } else if (min>max) swap(min,max); - SET(min,min); - SET(max,max); - CLAMP(x->val,x->min,x->max); - SET(k,x->is_log ? exp(log(x->max/x->min)/(double)(x->log_height)) : 1.0); - return x->val!=val; -} - -static void nbx_bang(t_nbx *x) { - x->outlet->send(x->val); - if(x->snd && x->snd->thing) pd_float(x->snd->thing, x->val); -} -static void nbx_set(t_nbx *x, t_floatarg f) {SET(val,f); nbx_clip(x);} -static void nbx_float(t_nbx *x, t_floatarg f) {nbx_set(x, f); if(iemgui_forward(x)) nbx_bang(x);} -static void nbx_log_height(t_nbx *x, t_floatarg lh) { - SET(log_height,max(10,(int)lh)); - SET(k,x->is_log ? exp(log(x->max/x->min)/(double)(x->log_height)) : 1.0); -} -static void nbx_size(t_nbx *x, t_symbol *s, int ac, t_atom *av) { - SET(w,max(1,(int)atom_getintarg(0, ac, av))); - if(ac > 1) SET(h,max(8,(int)atom_getintarg(1, ac, av))); -} -static void nbx_range(t_nbx *x, t_float min, t_float max) {SET(min,min); SET(max,max); nbx_check_minmax(x);} -static void nbx_lin(t_nbx *x) {SET(is_log,0); } -static void nbx_log(t_nbx *x) {SET(is_log,1); nbx_check_minmax(x);} -static void nbx_loadbang(t_nbx *x) {if(iemgui_loadbang(x)) nbx_bang(x);} -static void nbx_list(t_nbx *x, t_symbol *s, int ac, t_atom *av) { - if (!IS_A_FLOAT(av,0)) return; - nbx_set(x, atom_getfloatarg(0, ac, av)); - nbx_bang(x); -} -static int nbx_pickle(t_nbx *x, t_foo *foo) { - return pd_pickle(foo,"iiddbiaaaiiiicccd;i", - &x->w,&x->h,&x->min,&x->max,&x->is_log,&x->isa,&x->snd,&x->rcv,&x->lab, - &x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->fcol,&x->lcol,&x->val,&x->log_height); -} -static void nbx_savefn(t_nbx *x, t_binbuf *b) { - t_foo foo = {0,0,b}; - if (!b) return; - pd_savehead(b,x,"nbx"); - nbx_pickle(x,&foo); -} -static void nbx_reload(t_nbx *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym("nbx"),argc,argv); - if (!nbx_pickle(x,&foo)) return; - if (!x->isa&1) SET(val,0.0); - SET(fontsize,max(x->fontsize,4)); - SET(h,iemgui_clip_size(x->h)); - SET(w,max(x->w,1)); - nbx_check_minmax(x); - SET(w,max(x->w,1)); - if (x->rcv) pd_bind(x,x->rcv); - gobj_changed(x,0); -} -static void *nbx_new(t_symbol *s, int argc, t_atom *argv) { - t_nbx *x = (t_nbx *)iemgui_new(nbx_class); - SET(log_height,256); - SET(is_log,0); - SET(w,5); - SET(h,14); - SET(min,-1.0e+37); - SET(max,1.0e+37); - x->buf[0]=0; - SET(change,0); - outlet_new(x, &s_float); - if (argc) nbx_reload(x,0,argc,argv); - return x; -} - -#define IEM_VU_STEPS 40 - -static char vu_db2i[]= { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11,12,12,12,12,12, - 13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,18, - 18,18,19,19,19,20,20,20,21,21,22,22,23,23,24,24,25,26,27,28, - 29,30,31,32,33,33,34,34,35,35,36,36,37,37,37,38,38,38,39,39, - 39,39,39,39,40,40 -}; - -static void vu_check_height(t_vu *x, int h) { - int n=max(h/IEM_VU_STEPS,2); - SET(led_size,n-1); - SET(h,IEM_VU_STEPS * n); -} - -static void vu_scale(t_vu *x, t_floatarg fscale) {SET(scale,!!fscale);} - -static void vu_size(t_vu *x, t_symbol *s, int ac, t_atom *av) { - SET(w, iemgui_clip_size((int)atom_getintarg(0, ac, av))); - if(ac>1) vu_check_height(x, (int)atom_getintarg(1, ac, av)); -} - -static int vuify(t_vu *x, float v) { - return v<=-99.9 ? 0 : - v>=12.0 ? IEM_VU_STEPS : - vu_db2i[(int)(2.0*(v+100.0))]; -} - -static float vu_round(float v) {return 0.01*(int)(100.0*v+0.5);} - -static void vu_float0(t_vu *x, t_floatarg v) { - SET(rms, vuify(x,v)); SET(fr,vu_round(v)); x->out(0)->send(x->fr); - sys_mgui(x,"rms=","i",x->rms);} -static void vu_float1(t_vu *x, t_floatarg v) { - SET(peak,vuify(x,v)); SET(fp,vu_round(v)); x->out(1)->send(x->fp); - sys_mgui(x,"peak=","i",x->peak);} - -static void vu_bang(t_vu *x) { - x->out(1)->send(x->fp); - x->out(0)->send(x->fr); -} - -static int vu_pickle(t_vu *x, t_foo *foo) { - return pd_pickle(foo,"iiaaiiiiccb;i",&x->w,&x->h,&x->rcv,&x->lab,&x->ldx,&x->ldy,&x->font_style, - &x->fontsize,&x->bcol,&x->lcol,&x->scale,&x->isa); -} - -static void vu_savefn(t_vu *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,"vu"); vu_pickle(x,&foo); -} - -static void vu_reload(t_vu *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym("vu"),argc,argv); - if (!vu_pickle(x,&foo)) return; - iemgui_constrain(x); - if(x->rcv) pd_bind(x,x->rcv); - gobj_changed(x,0); -} - -static t_class *vu_class; - -static void *vu_new(t_symbol *s, int argc, t_atom *argv) { - t_vu *x = (t_vu *)iemgui_new(vu_class); - outlet_new(x, &s_float); - outlet_new(x, &s_float); - SET(bcol,0x000000); - SET(h,IEM_VU_STEPS*3); - SET(scale,1); - SET(rms,0); /* ??? */ - SET(peak,0); - SET(fp,-101.0); - SET(fr,-101.0); - vu_check_height(x,x->h); - inlet_new(x,x,&s_float,gensym("ft1")); - if (argc) vu_reload(x,0,argc,argv); - return x; -} - -static t_class *cnv_class; - -static void cnv_get_pos(t_cnv *x) { - error("unimplemented (TODO)"); -// if(x->snd && x->snd->thing) {x->at[0].a_float = x; x->at[1].a_float = y; pd_list(x->snd->thing, &s_list, 2, x->at);} -} - -static void cnv_size(t_cnv *x, t_symbol *s, int ac, t_atom *av) { - SET(h,max(1,(int)atom_getintarg(0, ac, av))); - SET(w,x->h); -} - -static void cnv_vis_size(t_cnv *x, t_symbol *s, int ac, t_atom *av) { - SET(vis_w,max(1,(int)atom_getintarg(0, ac, av))); - SET(vis_h,x->w); - if(ac > 1) SET(vis_h,max(1,(int)atom_getintarg(1, ac, av))); - gobj_changed(x,0); -} - -static int cnv_pickle(t_cnv *x, t_foo *foo) { - return pd_pickle(foo,"iiiaaaiiiicc;i",&x->w,&x->vis_w,&x->vis_h, - &x->snd,&x->rcv,&x->lab,&x->ldx,&x->ldy,&x->font_style,&x->fontsize,&x->bcol,&x->lcol,&x->isa); -} - -static void cnv_savefn(t_cnv *x, t_binbuf *b) { - t_foo foo = {0,0,b}; if (!b) return; - pd_savehead(b,x,"cnv"); cnv_pickle(x,&foo); -} - -static void cnv_reload(t_cnv *x, t_symbol *s, int argc, t_atom *argv) { - t_foo foo = {argc,argv,0}; - binbuf_update(x,gensym("cnv"),argc,argv); - if (!cnv_pickle(x,&foo)) return; - SET(w,max(x->w,1)); - SET(h,x->w); - SET(vis_w,max(x->vis_w,1)); - SET(vis_h,max(x->vis_h,1)); - x->at[0].a_type = x->at[1].a_type = A_FLOAT; //??? - iemgui_constrain(x); - if (x->rcv) pd_bind(x,x->rcv); - gobj_changed(x,0); -} - -static void *cnv_new(t_symbol *s, int argc, t_atom *argv) { - t_cnv *x = (t_cnv *) iemgui_new(cnv_class); - SET(bcol,0xe0e0e0); - SET(fcol,0x000000); - SET(lcol,0x404040); - SET(w,15); - SET(vis_w,100); - SET(vis_h,60); - if (argc) cnv_reload(x,0,argc,argv); - return x; -} - -void canvas_notice(t_gobj *x, t_gobj *origin, int argc, t_atom *argv) { - t_canvas *self = (t_canvas *)x; - gobj_changed3(self,origin,argc,argv); -} - -void gobj_onsubscribe(t_gobj *x, t_gobj *observer) {gobj_changed(x,0);} - -void canvas_onsubscribe(t_gobj *x, t_gobj *observer) { - t_canvas *self = (t_canvas *)x; - gobj_onsubscribe(x,observer); - canvas_each( y,self) y->_class->onsubscribe( y,observer); - canvas_wires_each(oc,t,self) oc->_class->onsubscribe(oc,observer); -} - -/* [declare] and canvas_open come from 0.40 */ -/* ------------------------------- declare ------------------------ */ -/* put "declare" objects in a patch to tell it about the environment in which objects should be created in this canvas. - This includes directories to search ("-path", "-stdpath") and object libraries to load ("-lib" and "-stdlib"). - These must be set before the patch containing the "declare" object is filled in with its contents; so when the patch is - saved, we throw early messages to the canvas to set the environment before any objects are created in it. */ -struct t_declare : t_object { - int useme; -}; - -static void *declare_new(t_symbol *s, int argc, t_atom *argv) { - t_declare *x = (t_declare *)pd_new(declare_class); - x->useme = 1; - /* LATER update environment and/or load libraries */ - return x; -} - -static void declare_free(t_declare *x) { - x->useme = 0; - /* LATER update environment */ -} - -void canvas_savedeclarationsto(t_canvas *x, t_binbuf *b) { - canvas_each(y,x) { - if (pd_class(y) == declare_class) { - binbuf_addv(b,"t","#X"); - binbuf_addbinbuf(b, ((t_declare *)y)->binbuf); - binbuf_addv(b, ";"); - } else if (pd_class(y) == canvas_class) canvas_savedeclarationsto((t_canvas *)y, b); - } -} - -static void canvas_declare(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { - t_canvasenvironment *e = canvas_getenv(x); -#if 0 - startpost("declare:: %s", s->name); - postatom(argc, argv); - endpost(); -#endif - for (int i=0; i<argc; i++) { - char *buf; - char *flag = atom_getsymbolarg(i, argc, argv)->name; - if ((argc > i+1) && !strcmp(flag, "-path")) { - e->path = namelist_append(e->path, atom_getsymbolarg(i+1, argc, argv)->name, 0); - i++; - } else if (argc>i+1 && !strcmp(flag, "-stdpath")) { - asprintf(&buf, "%s/%s", sys_libdir->name, atom_getsymbolarg(i+1, argc, argv)->name); - e->path = namelist_append(e->path,buf,0); - i++; - } else if (argc>i+1 && !strcmp(flag, "-lib")) { - sys_load_lib(x, atom_getsymbolarg(i+1, argc, argv)->name); - i++; - } else if (argc>i+1 && !strcmp(flag, "-stdlib")) { - asprintf(&buf, "%s/%s", sys_libdir->name, atom_getsymbolarg(i+1, argc, argv)->name); - sys_load_lib(0,buf); - i++; - } else post("declare: %s: unknown declaration", flag); - } -} - -/* utility function to read a file, looking first down the canvas's search path (set with "declare" - objects in the patch and recursively in calling patches), then down the system one. The filename - is the concatenation of "name" and "ext". "Name" may be absolute, or may be relative with slashes. - If anything can be opened, the true directory is put in the buffer dirresult (provided by caller), - which should be "size" bytes. The "nameresult" pointer will be set somewhere in the interior of - "dirresult" and will give the file basename (with slashes trimmed). If "bin" is set a 'binary' - open is attempted, otherwise ASCII (this only matters on Microsoft.) If "x" is zero, the file is - sought in the directory "." or in the global path.*/ -int canvas_open2(t_canvas *x, const char *name, const char *ext, char **dirresult, char **nameresult, int bin) { - int fd = -1; - /* first check if "name" is absolute (and if so, try to open) */ - if (sys_open_absolute(name, ext, dirresult, nameresult, bin, &fd)) return fd; - /* otherwise "name" is relative; start trying in directories named in this and parent environments */ - for (t_canvas *y=x; y; y = y->dix->canvas) if (y->env) { - t_canvas *x2 = x; - while (x2 && x2->dix->canvas) x2 = x2->dix->canvas; - const char *dir = x2 ? canvas_getdir(x2)->name : "."; - for (t_namelist *nl = y->env->path; nl; nl = nl->nl_next) { - char *realname; - asprintf(&realname, "%s/%s", dir, nl->nl_string); - if ((fd = sys_trytoopenone(realname, name, ext, dirresult, nameresult, bin)) >= 0) return fd; - } - } - return open_via_path2((x ? canvas_getdir(x)->name : "."), name, ext, dirresult, nameresult, bin); -} -/* end miller 0.40 */ - -int canvas_open(t_canvas *x, const char *name, const char *ext, char *dirresult, char **nameresult, unsigned int size, int bin) { - char *dirr; - int r = canvas_open2(x,name,ext,&dirr,nameresult,bin); - if (dirr) {strncpy(dirresult,dirr,size); dirresult[size-1]=0; free(dirr);} - return r; -} - -static void canvas_with_reply (t_pd *x, t_symbol *s, int argc, t_atom *argv) { - if (!( argc>=2 && IS_A_FLOAT(argv,0) && IS_A_SYMBOL(argv,1) )) return; - pd_typedmess(x,atom_getsymbol(&argv[1]),argc-2,argv+2); - queue_put(manager->q,reply_new((short)atom_getfloat(&argv[0]),newest)); -} - -static void canvas_get_elapsed (t_canvas *x) { - canvas_each(y,x) { - sys_mgui(y,"elapsed","f",y->dix->elapsed / 800000000.0); - } -} - -static void g_canvas_setup() { - reply_class = class_new2("reply",0,reply_free,sizeof(t_reply),CLASS_GOBJ,"!"); -// class_setsavefn(reply_class, (t_savefn)reply_savefn); - declare_class = class_new2("declare",declare_new,declare_free,sizeof(t_declare),CLASS_NOINLET,"*"); - t_class *c = canvas_class = class_new2("canvas",0,canvas_free,sizeof(t_canvas),CLASS_NOINLET,""); - /* here is the real creator function, invoked in patch files - by sending the "canvas" message to #N, which is bound to pd_canvasmaker. */ - class_addmethod2(pd_canvasmaker._class,canvas_new,"canvas","*"); - class_addmethod2(c,canvas_restore,"restore","*"); - class_addmethod2(c,canvas_coords,"coords","*"); - class_addmethod2(c,canvas_setbounds,"bounds","ffff"); - class_addmethod2(c,canvas_obj,"obj","*"); - class_addmethod2(c,canvas_msg,"msg","*"); - class_addmethod2(c,canvas_floatatom,"floatatom","*"); - class_addmethod2(c,canvas_symbolatom,"symbolatom","*"); - class_addmethod2(c,canvas_text,"text","*"); - class_addmethod2(c,canvas_canvas,"graph","*"); - class_addmethod2(c,canvas_scalar,"scalar","*"); - class_addmethod2(c,canvas_declare,"declare","*"); - class_addmethod2(c,canvas_push,"push",""); - class_addmethod2(c,canvas_pop,"pop","F"); - class_addmethod2(c,canvas_loadbang,"loadbang",""); - class_addmethod2(c,canvas_relocate,"relocate","ss"); - class_addmethod2(c,canvas_vis,"vis","f"); - class_addmethod2(c,canvas_menu_open,"menu-open",""); - class_addmethod2(c,canvas_clear,"clear",""); - class_addcreator2("pd",subcanvas_new,"S"); - class_addcreator2("page",subcanvas_new,"S"); - class_addmethod2(c,canvas_dsp,"dsp",""); - class_addmethod2(c,canvas_rename_method,"rename","*"); - class_addcreator2("table",table_new,"SF"); - class_addmethod2(c,canvas_close,"close","F"); - class_addmethod2(c,canvas_redraw,"redraw",""); - class_addmethod2(c,canvas_find_parent,"findparent",""); - class_addmethod2(c,canvas_arraydialog,"arraydialog","sfff"); - class_addmethod2(c,canvas_connect,"connect","ffff"); - class_addmethod2(c,canvas_disconnect,"disconnect","ffff"); - class_addmethod2(c,canvas_write,"write","sS"); - class_addmethod2(c,canvas_read, "read","sS"); - class_addmethod2(c,canvas_mergefile, "mergefile","sS"); - class_addmethod2(c,canvas_savetofile,"savetofile","ss"); - class_addmethod2(c,canvas_saveto, "saveto","!"); - class_addmethod2(c,graph_bounds,"bounds","ffff"); - class_addmethod2(c,graph_xticks,"xticks","fff"); - class_addmethod2(c,graph_xlabel,"xlabel","*"); - class_addmethod2(c,graph_yticks,"yticks","fff"); - class_addmethod2(c,graph_ylabel,"ylabel","*"); - class_addmethod2(c,graph_array,"array","sfsF"); - class_addmethod2(c,canvas_sort,"sort",""); -// dd-specific - class_addmethod2(c,canvas_object_moveto,"object_moveto","sff"); - class_addmethod2(c,canvas_object_delete,"object_delete","s"); - class_addmethod2(c,canvas_object_insert,"object_insert","*"); - class_addmethod2(c,canvas_object_get_tips,"object_get_tips","s"); - class_addmethod2(c,canvas_object_help,"object_help","s"); - class_addmethod2(c,canvas_text_setto,"text_setto","*"); - class_addmethod2(c,canvas_with_reply,"with_reply","*"); - class_addmethod2(pd_canvasmaker._class,canvas_with_reply,"with_reply","*"); - class_addmethod2(c,canvas_get_elapsed,"get_elapsed",""); - class_setnotice(c, canvas_notice); - class_setonsubscribe(c, canvas_onsubscribe); -} - -t_class *visualloader_class; - -static t_pd *visualloader_new(t_symbol *s, int argc, t_atom *argv) {return pd_new(visualloader_class);} -static void visualloader_free(t_pd *self) {free(self);} -static void copy_atoms(int argc, t_atom *argvdest, t_atom *argvsrc) {memcpy(argvdest,argvsrc,argc*sizeof(t_atom));} -static void visualloader_anything(t_gobj *self, t_symbol *s, int argc, t_atom *argv) { - int i=0,j=0; - //printf("visualloader_anything start newest=%p\n",newest); - while (j<argc) { - i=j; - while (j<argc && atom_getsymbolarg(j,argc,argv)!=gensym(",")) j++; - if (i==j) {j++; continue;} - t_arglist *al = (t_arglist *) malloc(sizeof(t_arglist) + (j-i)*sizeof(t_atom)); - al->c=j-i; - copy_atoms(al->c,al->v,&argv[i]); - //printf("#V reading '%s':\n",s->name); - if (!newest) {error("#V: there is no newest object\n"); return;} - t_visual *h = ((t_gobj *)newest)->dix->visual; - if (h->exists(s)) { - //printf("'%s' exists, deleting\n",s->name); - free(h->get(s)); - } - h->set(s,al); - //fprintf(stderr,"visualloader... %p %d\n",newest,hash_size(h)); - j++; - if (j<argc) {s=atom_getsymbolarg(j,argc,argv);j++;} - } - //printf("visualloader_anything end\n"); - gobj_changed(self,0); -} - -extern "C" void glob_update_path (); - -void glob_help(t_pd *bogus, t_symbol *s) { - t_class *c = class_find(s); - if (!c) { - //post("help: no such class '%s'",s->name); return; - t_binbuf *b = binbuf_new(); - binbuf_addv(b,"s",s); - newest = 0; - binbuf_eval(b,&pd_objectmaker,0,0); - if (!newest) {post("help: no such class '%s'",s->name); return;} - c = newest->_class; - pd_free(newest); - } - const char *hn = class_gethelpname(c); - char *buf; - bool suffixed = strcmp(hn+strlen(hn)-3, ".pd")==0; - asprintf(&buf,"%s%s",hn,suffixed?"":".pd"); - open_via_helppath(buf, c->externdir->name); - free(buf); -} - -extern "C" void glob_update_class_list (t_pd *self, t_symbol *cb_recv, t_symbol *cb_sel) { - t_symbol *k; t_class *v; - sys_gui("set ::class_list {"); - hash_foreach(k,v,class_table) if (k) sys_vgui("%s ", k->name); - sys_gui("}\n"); - sys_vgui("%s %s\n",cb_recv->name, cb_sel->name); -} - -EXTERN t_class *glob_pdobject; - -t_pd *pd_new2(int argc, t_atom *argv) { - if (argv[0].a_type != A_SYMBOL) {error("pd_new2: start with symbol please"); return 0;} - pd_typedmess(&pd_objectmaker,argv[0].a_symbol,argc-1,argv+1); - return newest; -} -t_pd *pd_new3(const char *s) { - t_binbuf *b = binbuf_new(); - binbuf_text(b,(char *)s,strlen(s)); - t_pd *self = pd_new2(binbuf_getnatom(b),binbuf_getvec(b)); - binbuf_free(b); - return self; -} - -extern "C" void boxes_init() { - t_class *c; - c = boxes_class = class_new2("__boxes" ,0/*boxes_new*/ , boxes_free,sizeof(t_boxes),CLASS_GOBJ,""); - class_setnotice(c,t_notice(boxes_notice)); - c = gop_filtre_class = class_new2("__gop_filtre",0/*gop_filtre_new*/,gop_filtre_free,sizeof(t_boxes),CLASS_GOBJ,""); - class_setnotice(c,t_notice(gop_filtre_notice)); -} - -static void desire_setup() { - t_class *c; - s_empty = gensym("empty"); - s_Pd = gensym("Pd"); - s_pd = gensym("pd"); - manager_class = class_new2("__manager",manager_new,manager_free,sizeof(t_manager),0,"*"); - class_addanything(manager_class,manager_anything); - class_setnotice(manager_class,manager_notice); - manager = manager_new(0,0,0); -#define S(x) x##_setup(); - S(vinlet) S(voutlet) S(g_array) S(g_canvas) S(g_scalar) S(g_template) S(g_traversal) S(g_text) -#undef S - - c = bng_class = class_new2("bng",bng_new,iemgui_free,sizeof(t_bng),0,"*"); - iemgui_subclass(c); - class_addbang (c, bng_bang); - class_addfloat (c, bng_bang2); - class_addsymbol (c, bng_bang2); - class_addpointer (c, bng_bang2); - class_addlist (c, bng_bang2); - class_addanything(c, bng_bang2); - class_addmethod2(c,bng_reload,"reload","*"); - class_addmethod2(c,bng_loadbang,"loadbang",""); - class_addmethod2(c,bng_size,"size","*"); - class_addmethod2(c,bng_flashtime,"flashtime","*"); - class_addmethod2(c,iemgui_init,"init","f"); - class_setsavefn(c, (t_savefn)bng_savefn); - class_sethelpsymbol(c, gensym("bng")); - class_setfieldnames(c, "foo bar x1 y1 class w hold break isa snd rcv lab ldx ldy fstyle fs bcol fcol lcol"); - - c = toggle_class = class_new2("tgl",toggle_new,iemgui_free,sizeof(t_toggle),0,"*"); - class_addcreator2("toggle",toggle_new,"*"); - iemgui_subclass(c); - class_addbang(c, toggle_bang); - class_addfloat(c, toggle_float); - class_addmethod2(c,toggle_reload,"reload","*"); - class_addmethod2(c,toggle_loadbang,"loadbang",""); - class_addmethod2(c,toggle_set,"set","f"); - class_addmethod2(c,toggle_size,"size","*"); - class_addmethod2(c,iemgui_init,"init","f"); - class_addmethod2(c,toggle_nonzero,"nonzero","f"); - class_setsavefn(c, (t_savefn)toggle_savefn); - class_sethelpsymbol(c, gensym("toggle")); - - c = radio_class = class_new2("radio",radio_new,iemgui_free,sizeof(t_radio),0,"*"); - iemgui_subclass(c); - class_addbang(c, radio_bang); - class_addfloat(c, radio_float); - class_addmethod2(c,radio_reload, "reload","*"); - class_addmethod2(c,radio_loadbang, "loadbang",""); - class_addmethod2(c,radio_set, "set","f"); - class_addmethod2(c,radio_size, "size","f"); - class_addmethod2(c,iemgui_init, "init","f"); - class_addmethod2(c,radio_fout, "fout","f"); - class_addmethod2(c,radio_number, "number","f"); - class_addmethod2(c,radio_orient,"orient","f"); - class_addmethod2(c,radio_single_change, "single_change",""); - class_addmethod2(c,radio_double_change, "double_change",""); - sym_hdl = gensym("hdl"); sym_hradio = gensym("hradio"); - sym_vdl = gensym("vdl"); sym_vradio = gensym("vradio"); - class_setsavefn(c,(t_savefn)radio_savefn); - class_sethelpsymbol(c, gensym("hradio")); - class_addcreator2("hradio",radio_new,"*"); - class_addcreator2("vradio",radio_new,"*"); - class_addcreator2("hdl",radio_new,"*"); - class_addcreator2("vdl",radio_new,"*"); - class_addcreator2("rdb",radio_new,"*"); - class_addcreator2("radiobut",radio_new,"*"); - class_addcreator2("radiobutton",radio_new,"*"); - - c = slider_class = class_new2("slider",slider_new,iemgui_free,sizeof(t_slider),0,"*"); - class_addcreator2("hslider",slider_new,"*"); - class_addcreator2("vslider",slider_new,"*"); - class_addcreator2("hsl" ,slider_new,"*"); - class_addcreator2("vsl" ,slider_new,"*"); - - iemgui_subclass(c); - class_addbang(c,slider_bang); - class_addfloat(c,slider_float); - class_addmethod2(c,slider_reload,"reload","*"); - class_addmethod2(c,slider_loadbang,"loadbang",""); - class_addmethod2(c,slider_set,"set","f"); - class_addmethod2(c,slider_size,"size","*"); - class_addmethod2(c,slider_range,"range","ff"); - class_addmethod2(c,slider_log,"log",""); - class_addmethod2(c,slider_lin,"lin",""); - class_addmethod2(c,iemgui_init,"init","f"); - class_addmethod2(c,slider_steady,"steady","f"); - class_addmethod2(c,slider_orient,"orient","f"); - sym_vsl = gensym("vsl"); - sym_vslider = gensym("vslider"); - class_setsavefn(c,(t_savefn)slider_savefn); - class_sethelpsymbol(c, gensym("hslider")); - - c = nbx_class = class_new2("nbx",nbx_new,iemgui_free,sizeof(t_nbx),0,"*"); - iemgui_subclass(c); - class_addbang(c,nbx_bang); - class_addfloat(c,nbx_float); - class_addlist(c, nbx_list); - class_addmethod2(c,nbx_reload,"reload","*"); - class_addmethod2(c,nbx_loadbang,"loadbang",""); - class_addmethod2(c,nbx_set,"set","f"); - class_addmethod2(c,nbx_size,"size","*"); - class_addmethod2(c,nbx_range,"range","*"); - class_addmethod2(c,nbx_log,"log",""); - class_addmethod2(c,nbx_lin,"lin",""); - class_addmethod2(c,iemgui_init,"init","f"); - class_addmethod2(c,nbx_log_height,"log_height","f"); - class_setsavefn(c,(t_savefn)nbx_savefn); - class_sethelpsymbol(c, gensym("numbox2")); - - c = cnv_class = class_new2("cnv",cnv_new,iemgui_free,sizeof(t_cnv),CLASS_NOINLET,"*"); - class_addmethod2(c,cnv_reload,"reload","*"); - class_addmethod2(c,cnv_size,"size","*"); - class_addmethod2(c,cnv_vis_size,"vis_size","*"); - class_addmethod2(c,cnv_get_pos,"get_pos",""); - iemgui_subclass(c); - class_setsavefn(c,(t_savefn)cnv_savefn); - class_sethelpsymbol(c, gensym("my_canvas")); - - c = vu_class = class_new2("vu",vu_new,iemgui_free,sizeof(t_vu),0,"*"); - iemgui_subclass(c); - class_addbang(c,vu_bang); - class_addfloat(c,vu_float0); - class_addmethod2(c,vu_float1,"ft1","f"); - class_addmethod2(c,vu_reload,"reload","*"); - class_addmethod2(c,vu_size,"size","*"); - class_addmethod2(c,vu_scale,"scale","F"); - class_setsavefn(c,(t_savefn)vu_savefn); - class_sethelpsymbol(c, gensym("vu")); - - visualloader_class = class_new2("#V",visualloader_new,visualloader_free,sizeof(t_object),CLASS_GOBJ,"*"); - class_addanything(visualloader_class,visualloader_anything); - pd_bind(pd_new(visualloader_class),gensym("#V")); -} - -/* ---------------------------------------------------------------- */ -/* formerly m_glob.c */ - -t_class *glob_pdobject; -static t_class *maxclass; - -#define IGN(sym) if (s==gensym(sym)) return; -void max_default(t_pd *x, t_symbol *s, int argc, t_atom *argv) { - IGN("audioindev"); - IGN("audiooutdev"); - IGN("audioininfo"); - IGN("audiooutinfo"); - IGN("testaudiosettingresult"); - IGN("audiodevice"); - IGN("xrun"); - IGN("audio_started"); - IGN("sys_lock_timeout"); - IGN("midiindev"); - IGN("midioutdev"); - IGN("midicurrentindev"); - IGN("midicurrentoutdev"); - IGN("audiocurrentininfo"); - IGN("audiocurrentoutinfo"); - IGN("asiolatency"); - startpost("%s: unknown message %s ", class_getname(pd_class(x)), s->name); - std::ostringstream buf; - for (int i = 0; i < argc; i++) {buf << " "; atom_ostream(argv+i,buf);} - post("%s",buf.str().data()); - endpost(); -} - -static void openit(const char *dirname, const char *filename) { - char *dirbuf; - char *nameptr; - int fd = open_via_path2(dirname,filename,"",&dirbuf,&nameptr,0); - if (fd<0) {error("%s: can't open", filename); return;} - close(fd); - glob_evalfile(0, gensym(nameptr), gensym(dirbuf)); - free(dirbuf); -} - -extern "C" t_socketreceiver *netreceive_newest_receiver(t_text *x); - -/* this should be rethought for multi-client */ -void glob_initfromgui(void *dummy, t_symbol *s) { - char buf[256], buf2[256]; - char cwd[666]; - if (!getcwd(cwd,665)) strcpy(cwd,"actual_name_is_way_too_long.oops"); - sys_socketreceiver=netreceive_newest_receiver(sys_netreceive); - sys_vgui("%s",lost_posts.str().data()); - /* load dynamic libraries specified with "-lib" args */ - for (t_namelist *nl=sys_externlist; nl; nl = nl->nl_next) - if (!sys_load_lib(0, nl->nl_string)) - post("%s: can't load library", nl->nl_string); - /* open patches specified with "-open" args */ - for (t_namelist *nl=sys_openlist; nl; nl = nl->nl_next) openit(cwd, nl->nl_string); - namelist_free(sys_openlist); - sys_openlist = 0; - /* send messages specified with "-send" args */ - for (t_namelist *nl=sys_messagelist; nl; nl = nl->nl_next) { - t_binbuf *b = binbuf_new(); - binbuf_text(b, nl->nl_string, strlen(nl->nl_string)); - binbuf_eval(b, 0, 0, 0); - binbuf_free(b); - } - namelist_free(sys_messagelist); - sys_messagelist = 0; - sys_get_audio_apis(buf); - sys_get_midi_apis(buf2); - sys_vgui("pd_startup {%s} %s %s\n", pd_version, buf, buf2); -/* - fprintf(stdout,"This line was printed on stdout\n"); - fprintf(stderr,"This line was printed on stderr\n"); -*/ -} - -void glob_meters(void *, t_floatarg f); -void glob_audiostatus(void *); -void glob_audio_properties(t_pd *, t_floatarg flongform); -void glob_audio_dialog(t_pd *, t_symbol *s, int argc, t_atom *argv); -void glob_audio_setapi(t_pd *, t_floatarg f); -void glob_midi_properties(t_pd *, t_floatarg flongform); -void glob_midi_dialog(t_pd *, t_symbol *s, int argc, t_atom *argv); -void glob_midi_setapi(t_pd *, t_floatarg f); -void glob_start_path_dialog(t_pd *, t_floatarg flongform); -void glob_path_dialog(t_pd *, t_symbol *s, int argc, t_atom *argv); -void glob_start_startup_dialog(t_pd *, t_floatarg flongform); -void glob_startup_dialog(t_pd *, t_symbol *s, int argc, t_atom *argv); -void glob_ping(t_pd *); -extern "C" { -void glob_finderror(t_pd *); -}; -/* tb: message-based audio configuration { */ -void glob_audio_testaudiosetting(t_pd *, t_symbol *s, int ac, t_atom *av); -void glob_audio_getaudioindevices(t_pd *, t_symbol *s, int ac, t_atom *av); -void glob_audio_getaudiooutdevices(t_pd *, t_symbol *s, int ac, t_atom *av); -void glob_audio_getaudioininfo(t_pd *, t_float f); -void glob_audio_getaudiooutinfo(t_pd * dummy, t_float f); -//void glob_audio_samplerate(t_pd *, t_float f); -//void glob_audio_delay(t_pd *, t_float f); -//void glob_audio_dacblocksize(t_pd *, t_float f); -//void glob_audio_scheduler(t_pd *, t_float f); -void glob_audio_device(t_pd *, t_symbol *s, int argc, t_atom *argv); -//void glob_audio_device_in(t_pd *, t_symbol *s, int argc, t_atom *argv); -//void glob_audio_device_out(t_pd *, t_symbol *s, int argc, t_atom *argv); -void glob_audio_getcurrent_devices (); -void glob_audio_asio_latencies(t_pd *, t_float f); -void glob_midi_getindevs( t_pd *, t_symbol *s, int ac, t_atom *av); -void glob_midi_getoutdevs(t_pd *, t_symbol *s, int ac, t_atom *av); -void glob_midi_getcurrentindevs(t_pd *); -void glob_midi_getcurrentoutdevs(t_pd *); -/* tb } */ - -static void glob_object_table() { - t_symbol *s_inlet = gensym("inlet"); - t_symbol *s___list = gensym("__list"); - size_t inlets=0, lists=0, zombies=0; - t_pd *k; long v; - post("object_table = {"); - hash_foreach(k,v,object_table) { - t_pd *x = (t_pd *)k; - if (!(long)v&1) {zombies++; continue;} /* skip zombies */ - //post(" %p %ld %s",k,(long)v,x->_class->name->name); - if (x->_class->name == s_inlet) {inlets++; continue;} - if (x->_class->name == s___list) {lists++; continue;} - int nobs = x->_class->gobj ? ((t_gobj *)x)->dix->nobs : 0; - // this has been duplicated as the ostream operator of t_pd * (see above). - t_binbuf *b; - if (x->_class->patchable && (b = ((t_text *)x)->binbuf)) { - char *buf; int bufn; - binbuf_gettext(b,&buf,&bufn); - post(" %p %ld (%dobs) %s [%.*s]",k,(long)v,nobs,x->_class->name->name,bufn,buf); - } else post(" %p %ld (%dobs) %s",k,(long)v,nobs,x->_class->name->name); - } - post("} (%ld non-omitted objects, plus %ld [inlet], plus %ld [__list], plus %ld zombies)", - long(object_table->size()-inlets-lists-zombies),long(inlets),long(lists),long(zombies)); -} - -void glob_symbol_table (t_pd *, float onlybound); - -extern t_class *glob_pdobject; -extern "C" void glob_init () { - /* can this one really be called "max"? isn't that a name conflict? */ - maxclass = class_new2("max",0,0,sizeof(t_pd),CLASS_DEFAULT,""); - class_addanything(maxclass, max_default); - pd_bind((t_pd *)&maxclass, gensym("max")); - - /* this smells bad... a conflict with [pd] subpatches */ - t_class *c = glob_pdobject = class_new2("pd",0,0,sizeof(t_pd),CLASS_DEFAULT,""); - class_addmethod2(c,glob_initfromgui, "init", "*"); - class_addmethod2(c,glob_setfilename, "filename", "ss"); - class_addmethod2(c,glob_evalfile, "open", "ss"); - class_addmethod2(c,glob_quit, "quit", ""); - class_addmethod2(c,glob_dsp, "dsp", "*"); - class_addmethod2(c,glob_meters, "meters", "f"); - class_addmethod2(c,glob_audiostatus, "audiostatus", ""); - class_addmethod2(c,glob_finderror, "finderror", ""); - class_addmethod2(c,glob_audio_properties, "audio-properties", "F"); - class_addmethod2(c,glob_audio_dialog, "audio-dialog", "*"); - class_addmethod2(c,glob_audio_setapi, "audio-setapi", "f"); - class_addmethod2(c,glob_midi_setapi, "midi-setapi", "f"); - class_addmethod2(c,glob_midi_properties, "midi-properties", "F"); - class_addmethod2(c,glob_midi_dialog, "midi-dialog", "*"); - class_addmethod2(c,glob_ping, "ping",""); - /* tb: message-based audio configuration { */ -// class_addmethod2(c,glob_audio_samplerate, "audio-samplerate", "F"); -// class_addmethod2(c,glob_audio_delay, "audio-delay", "F"); -// class_addmethod2(c,glob_audio_dacblocksize,"audio-dacblocksize", "F"); -// class_addmethod2(c,glob_audio_scheduler, "audio-scheduler", "F"); - class_addmethod2(c,glob_audio_device, "audio-device", "*"); -// class_addmethod2(c,glob_audio_device_in, "audio-device-in", "*"); -// class_addmethod2(c,glob_audio_device_out, "audio-device-out", "*"); - class_addmethod2(c,glob_audio_getaudioindevices, "getaudioindev", "*"); - class_addmethod2(c,glob_audio_getaudiooutdevices,"getaudiooutdev", "*"); - class_addmethod2(c,glob_audio_getaudioininfo, "getaudioininfo", "f"); - class_addmethod2(c,glob_audio_getaudiooutinfo, "getaudiooutinfo", "f"); - class_addmethod2(c,glob_audio_testaudiosetting, "testaudiosetting", "*"); - class_addmethod2(c,glob_audio_getcurrent_devices,"getaudiodevice", ""); - class_addmethod2(c,glob_audio_asio_latencies, "getasiolatencies", "F"); - class_addmethod2(c,glob_midi_getoutdevs,"getmidioutdev", "*"); - class_addmethod2(c,glob_midi_getindevs, "getmidiindev", "*"); - class_addmethod2(c,glob_midi_getcurrentoutdevs, "getmidicurrentoutdev", ""); - class_addmethod2(c,glob_midi_getcurrentindevs, "getmidicurrentindev", ""); - /* tb } */ -#ifdef UNIX - class_addmethod2(c,glob_watchdog, "watchdog", ""); -#endif - class_addmethod2(c,glob_update_class_list, "update-class-list", "ss"); - class_addmethod2(c,glob_update_class_info, "update-class-info", "sss"); - class_addmethod2(c,glob_update_path, "update-path", ""); - class_addmethod2(c,glob_help, "help", "s"); - class_addmethod2(c,glob_object_table,"object_table",""); - class_addmethod2(c,glob_symbol_table,"symbol_table","F"); - class_addanything(c, max_default); - pd_bind((t_pd *)&glob_pdobject, gensym("pd")); -} - -/* ---------------------------------------------------------------- */ -/* formerly s_print.c */ - -t_printhook sys_printhook; -FILE *sys_printtofh = 0; /* send to console by default */ - -static void dopost(const char *s) { - if (sys_printhook) sys_printhook(s); - else if (sys_printtofh) fprintf(sys_printtofh, "%s", s); - else { - std::ostringstream t; - for(int i=0; s[i]; i++) { - if (strchr("\\\"[]$\n",s[i])) t << '\\'; - t << char(s[i]=='\n' ? 'n' : s[i]); - } - sys_vgui("pdtk_post \"%s\"\n",t.str().data()); - } -} - -void post(const char *fmt, ...) { - char *buf; va_list ap; va_start(ap, fmt); - size_t n = vasprintf(&buf, fmt, ap); va_end(ap); - buf=realloc2(buf,n+2); strcpy(buf+n,"\n"); - dopost(buf); free(buf); -} -void startpost(const char *fmt, ...) { - char *buf; va_list ap; va_start(ap, fmt); - vasprintf(&buf, fmt, ap); va_end(ap); - dopost(buf); free(buf); -} - -void poststring(const char *s) {dopost(" "); dopost(s);} - -void postatom(int argc, t_atom *argv) { - std::ostringstream buf; - for (int i=0; i<argc; i++) {buf << " "; atom_ostream(argv+i,buf);} - dopost(buf.str().data()); -} - -/* what's the point? */ -void postfloat(float f) {t_atom a; SETFLOAT(&a, f); postatom(1, &a);} -void endpost () {dopost("\n");} - -static t_pd *error_object; -static char *error_string; -void canvas_finderror(void *object); - -void verror(const char *fmt, va_list ap) { - if (error_string) free(error_string); - dopost("error: "); - vasprintf(&error_string,fmt,ap); - dopost(error_string); - dopost("\n"); - //post("at stack level %ld\n",pd_stackn); - error_object = pd_stackn>=0 ? pd_stack[pd_stackn-1].self : 0; -} -void error( const char *fmt, ...) {va_list ap; va_start(ap,fmt); verror(fmt,ap); va_end(ap);} -void pd_error(void *moot, const char *fmt, ...) {va_list ap; va_start(ap,fmt); verror(fmt,ap); va_end(ap);} - -void verbose(int level, const char *fmt, ...) { - char *buf; - va_list ap; - if (level>sys_verbose) return; - dopost("verbose("); - postfloat((float)level); - dopost("):"); - va_start(ap, fmt); - vasprintf(&buf,fmt,ap); - va_end(ap); - dopost(buf); - dopost("\n"); -} - -extern "C" void glob_finderror(t_pd *dummy) { - if (!error_object) {post("no findable error yet."); return;} - post("last trackable error was for object x%lx: %s",long(error_object),error_string); - sys_mgui(error_object,"show_error","S",error_string); - canvas_finderror(error_object); -} - -void bug(const char *fmt, ...) { - char *buf; - va_list ap; - dopost("bug: "); - va_start(ap, fmt); - vasprintf(&buf,fmt,ap); - va_end(ap); - dopost(buf); - free(buf); - dopost("\n"); -} - -static const char *errobject; -static const char *errstring; - -void sys_logerror (const char *object, const char *s){errobject=object; errstring = s;} -void sys_unixerror(const char *object) {errobject=object; errstring = strerror(errno);} - -void sys_ouch () { - if (*errobject) error("%s: %s", errobject, errstring); else error("%s", errstring); -} - -/* properly close all open root canvases */ -extern "C" void glob_closeall(void *dummy, t_floatarg fforce) { - foreach(x,windowed_canvases) canvas_close(x->first); -} - -/* ---------------------------------------------------------------- */ -/* formerly m_conf.c */ - -void builtins_setup (); -void builtins_dsp_setup (); -void desire_setup (); -void d_soundfile_setup (); -void d_ugen_setup (); - -extern "C" void conf_init () { - builtins_setup(); - builtins_dsp_setup(); - desire_setup(); - d_soundfile_setup(); - d_ugen_setup(); -} - -// and just to make some externs happy: -#define BYE error("%s unimplemented in desiredata!", __PRETTY_FUNCTION__); -extern "C" { - void glist_grab () {BYE} - void glist_xtopixels () {BYE} - void glist_ytopixels () {BYE} - void *glist_findrtext () {BYE return 0;} - void canvas_fixlinesfor () {BYE} - void class_setpropertiesfn () {BYE} - void glist_eraseiofor () {BYE} - void glist_getcanvas () {BYE} - void rtext_gettag () {BYE} - void class_setwidget () {BYE} - void glist_isvisible () {BYE} - void gobj_vis () {BYE} - void gfxstub_deleteforkey () {BYE} - void gfxstub_new () {BYE} - void rtext_width () {BYE} - void rtext_height () {BYE} - void *rtext_new () {BYE return 0;} - void rtext_free () {BYE} - void glist_delete(t_canvas *x, t_gobj *y) {canvas_delete(x,y);} - - //redundantwards-compatibility - void canvas_setcurrent (t_canvas *x) {pd_pushsym(x);} - void canvas_unsetcurrent(t_canvas *x) {pd_popsym(x);} - - //int sys_isreadablefile(const char *file) {} - - /* test if path is absolute or relative, based on leading /, env vars, ~, etc */ - int sys_isabsolutepath(const char *dir) { - return dir[0] == '/' || dir[0] == '~' -#ifdef MSW - || dir[0] == '%' || (dir[1] == ':' && dir[2] == '/') -#endif - ;} -}; - -t_gobj *canvas_first (t_canvas *self) {return self->boxes->first();} -t_gobj *gobj_next (t_gobj *self) {return self->next();} diff --git a/desiredata/src/desire.h b/desiredata/src/desire.h deleted file mode 100644 index 0be0c00d..00000000 --- a/desiredata/src/desire.h +++ /dev/null @@ -1,686 +0,0 @@ -/* - This file is part of PureData - Copyright 2004-2006 by Mathieu Bouchard - Copyright 2000-2001 IEM KUG Graz Austria (Thomas Musil) - Copyright (c) 1997-1999 Miller Puckette. - For information on usage and redistribution, and for a DISCLAIMER OF ALL - WARRANTIES, see the file, "LICENSE.txt", in this distribution. - - this file declares the C interface for the second half of DesireData. - this is where most of the differences between DesireData and PureData lie. - - SYNONYMS: - 1. glist = graph = canvas = patcher; those were not always synonymous. - however, graph sometimes means a canvas that is displaying an array. - 2. outconnect = connection = patchcord = wire - - canvases have a few flags that determine their appearance: - gl_havewindow: should open its own window (only if mapped? or...) - gl_isgraph: the GOP flag: show as graph-on-parent, vs TextBox. - gl_owner==0: it's a root canvas, should be in canvas_list. - In this case "gl_havewindow" is always set. - - canvas_list is a list of root windows only, which can be traversed using canvases_each. - - If a canvas has a window it may still not be "mapped." Miniaturized - windows aren't mapped, for example, but a window is also not mapped - immediately upon creation. In either case gl_havewindow is true but - gl_mapped is false. - - Closing a non-root window makes it invisible; closing a root destroys it. - A canvas that's just a text object on its parent is always "toplevel." An - embedded canvas can switch back and forth to appear as a toplevel by double- - clicking on it. Single-clicking a text box makes the toplevel become visible - and raises the window it's in. - - If a canvas shows up as a graph on its parent, the graph is blanked while the - canvas has its own window, even if miniaturized. -*/ - -#ifndef DESIRE -#define DESIRE 1 -#endif -#ifndef __DESIRE_H -#define __DESIRE_H - -#include "m_pd.h" -#include <stdio.h> - -#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) -extern "C" { -#endif - -/* ----------------------- START OF FORMER S_STUFF ----------------------------- */ - -/* from s_path.c */ - -typedef struct _namelist { /* element in a linked list of stored strings */ - struct _namelist *nl_next; /* next in list */ - char *nl_string; /* the string */ -} t_namelist; - -t_namelist *namelist_append(t_namelist *listwas, const char *s, int allowdup); -t_namelist *namelist_append_files(t_namelist *listwas, const char *s); -void namelist_free(t_namelist *listwas); -char *namelist_get(t_namelist *namelist, int n); -void sys_setextrapath(const char *p); -extern int sys_usestdpath; -extern t_namelist *sys_externlist; -extern t_namelist *sys_searchpath; -extern t_namelist *sys_helppath; - -// IOhannes : added namespace support for libraries -// the define QUALIFIED_NAME both turns on namespaces and sets the library-object delimiter -#define QUALIFIED_NAME "/" -#ifdef QUALIFIED_NAME -void pd_set_library_name(char *libname); -#endif - -int sys_open_absolute( const char *name, const char* ext, char **dirresult, char **nameresult, int bin, int *fdp); -int sys_trytoopenone(const char *dir, const char *name, const char* ext, char **dirresult, char **nameresult, int bin); - -/* s_main.c */ -extern int sys_debuglevel; -extern int sys_verbose; -extern int sys_noloadbang; -extern int sys_nogui; -extern char *sys_guicmd; -extern int sys_tooltips; -extern int sys_defeatrt; -extern t_symbol *sys_flags; -extern t_symbol *sys_libdir; /* library directory for auxilliary files */ - -/* s_loader.c */ -int sys_load_lib(t_canvas *canvas, char *filename); - -/* s_audio.c */ -#define SENDDACS_NO 0 /* return values for sys_send_dacs() */ -#define SENDDACS_YES 1 -#define SENDDACS_SLEPT 2 -#define DEFDACBLKSIZE 64 /* the default dac~blocksize */ -extern int sys_dacblocksize; /* the real dac~blocksize */ -extern int sys_schedblocksize; /* audio block size for scheduler */ -extern int sys_hipriority; /* real-time flag, true if priority boosted */ -extern t_sample *sys_soundout; -extern t_sample *sys_soundin; -extern int sys_inchannels; -extern int sys_outchannels; -extern int sys_advance_samples; /* scheduler advance in samples */ -extern int sys_blocksize; /* audio I/O block size in sample frames */ -extern float sys_dacsr; -extern int sys_schedadvance; -extern int sys_sleepgrain; -extern int sys_callbackscheduler; /* tb: scheduler to use (0: traditional, 1: callback) */ -void sys_open_audio( -int naudioindev, int * audioindev, int nchindev, int * chindev, -int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, -int srate, int dacblocksize, int advance, int schedmode, int enable); -void sys_reopen_audio(void); -void sys_close_audio(void); -int sys_send_dacs(void); -void sys_set_priority(int higher); -void sys_audiobuf(int nbufs); -void sys_getmeters(float *inmax, float *outmax); -void sys_listdevs(void); -void sys_setblocksize(int n); -void sys_update_sleepgrain(void); //tb - -/* s_midi.c */ -#define MAXMIDIINDEV 16 /* max. number of input ports */ -#define MAXMIDIOUTDEV 16 /* max. number of output ports */ -extern int sys_nmidiin; -extern int sys_nmidiout; -extern int sys_midiindevlist[]; -extern int sys_midioutdevlist[]; -void sys_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec, int enable); -void sys_get_midi_params(int *pnmidiindev, int *pmidiindev, int *pnmidioutdev, int *pmidioutdev); -void sys_get_midi_apis(char *buf); -void sys_reopen_midi( void); -void sys_close_midi( void); -EXTERN void sys_putmidimess(int portno, int a, int b, int c); -EXTERN void sys_putmidibyte(int portno, int a); -EXTERN void sys_poll_midi(void); -EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime); -EXTERN void sys_midibytein(int portno, int byte); -/* implemented in the system dependent MIDI code (s_midi_pm.c, etc.) */ -void midi_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize); -void sys_do_open_midi(int nmidiindev, int *midiindev, int nmidioutdev, int *midioutdev); - -#ifdef USEAPI_ALSA -EXTERN void sys_alsa_putmidimess(int portno, int a, int b, int c); -EXTERN void sys_alsa_putmidibyte(int portno, int a); -EXTERN void sys_alsa_poll_midi(void); -EXTERN void sys_alsa_setmiditimediff(double inbuftime, double outbuftime); -EXTERN void sys_alsa_midibytein(int portno, int byte); -EXTERN void sys_alsa_close_midi( void); -/* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */ -void midi_alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize); -void sys_alsa_do_open_midi(int nmidiindev, int *midiindev, int nmidioutdev, int *midioutdev); -#endif - -/* m_sched.c */ -EXTERN void sys_log_error(int type); -#define ERR_NOTHING 0 -#define ERR_ADCSLEPT 1 -#define ERR_DACSLEPT 2 -#define ERR_RESYNC 3 -#define ERR_DATALATE 4 -#define ERR_XRUN 5 -#define ERR_SYSLOCK 6 -void sched_set_using_dacs(int flag); -void sys_setscheduler(int scheduler); //tb -int sys_getscheduler(void); //tb - -/* s_inter.c */ -EXTERN void sys_microsleep(int microsec); -EXTERN void sys_bail(int exitcode); -EXTERN int sys_pollgui(void); -typedef void (*t_socketnotifier)(void *x); -typedef void (*t_socketreceivefn)(void *x, t_binbuf *b); - -typedef struct _socketreceiver { - char *inbuf; - int inhead; - int intail; - void *owner; - int udp; - t_socketnotifier notifier; - t_socketreceivefn socketreceivefn; -/* for sending only: */ - int fd; - struct _socketreceiver *next; - char *obuf; - int ohead, otail, osize; - int waitingforping; - int bytessincelastping; -} t_socketreceiver; - -EXTERN char pd_version[]; -EXTERN t_text *sys_netreceive; -EXTERN t_socketreceiver *sys_socketreceiver; -//EXTERN t_socketreceiver *netreceive_newest_receiver(t_text *x); - -EXTERN t_namelist *sys_externlist; -EXTERN t_namelist *sys_openlist; -EXTERN t_namelist *sys_messagelist; - -EXTERN t_socketreceiver *socketreceiver_new(t_pd *owner, int fd, - t_socketnotifier notifier, t_socketreceivefn socketreceivefn, int udp); -EXTERN void socketreceiver_read(t_socketreceiver *x, int fd); -EXTERN void sys_sockerror(const char *s); -EXTERN void sys_closesocket(int fd); - -typedef void (*t_fdpollfn)(void *ptr, int fd); -EXTERN void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr); -EXTERN void sys_rmpollfn(int fd); -#ifdef UNIX -void sys_setalarm(int microsec); -void sys_setvirtualalarm(void); -#endif - -#define API_NONE 0 -#define API_ALSA 1 -#define API_OSS 2 -#define API_MMIO 3 -#define API_PORTAUDIO 4 -#define API_JACK 5 -#define API_ASIO 7 - -#if defined(USEAPI_OSS) -#define API_DEFAULT API_OSS -#define API_DEFSTRING "oss" -#elif defined(USEAPI_ALSA) -#define API_DEFAULT API_ALSA -#define API_DEFSTRING "alsa" -#elif defined(USEAPI_JACK) -#define API_DEFAULT API_JACK -#define API_DEFSTRING "jack" -#elif defined(USEAPI_MMIO) -#define API_DEFAULT API_MMIO -#define API_DEFSTRING "mmio" -#elif defined(USEAPI_PORTAUDIO) -#define API_DEFAULT API_PORTAUDIO -#define API_DEFSTRING "portaudio" -#else -#define API_DEFAULT 0 -#define API_DEFSTRING "none" -#endif - -#define DEFAULTAUDIODEV 0 -#define MAXAUDIOINDEV 4 -#define MAXAUDIOOUTDEV 4 -#define DEFMIDIDEV 0 -#define DEFAULTSRATE 44100 -#ifdef MSW -#define DEFAULTADVANCE 70 -#else -#define DEFAULTADVANCE 50 -#endif - -struct t_audiodevs { - int ndev; - int dev[MAXAUDIOINDEV]; - int chdev[MAXAUDIOINDEV]; -#ifdef __cplusplus - t_audiodevs() : ndev(-1) {} -#endif -}; - -/* new audio api interface */ -typedef struct t_audioapi { - int (*open_audio)( - int naudioindev, int *audioindev, int nchindev, int *chindev, - int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, - int rate, int schedmode); - void (*close_audio)(void); - int (*send_dacs)(void); - void (*getdevs)(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize); -} t_audioapi; - -int pa_open_audio(int inchans, int outchans, int rate, int advance, int indeviceno, int outdeviceno, int schedmode); - -/* tb { */ -void pa_test_setting (int ac, t_atom *av); -void pa_getcurrent_devices(void); -void pa_getaudiooutdevinfo(t_float f); -void pa_getaudioindevinfo(t_float f); -/* } tb */ - -int jack_open_audio(int wantinchans, int wantoutchans, int rate, int scheduler); -void jack_listdevs(void); -void sys_listmididevs(void); -void sys_set_midi_api(int whichapi); -void sys_set_audio_api(int whichapi); -void sys_get_audio_apis(char *buf); -extern int sys_audioapi; -void sys_set_audio_state(int onoff); - -/* API dependent audio flags and settings */ -void oss_set32bit(void); -void linux_alsa_devname(char *devname); - -void sys_get_audio_params(t_audiodevs *in, t_audiodevs *out, int *prate, int *dacblocksize, int *padvance, int *pscheduler); -void sys_save_audio_params(t_audiodevs *in, t_audiodevs *out, int rate, int dacblocksize, int advance, int scheduler); - -/* s_file.c */ -typedef void (*t_printhook)(const char *s); -extern t_printhook sys_printhook; /* set this to override printing */ -extern FILE *sys_printtofh; -#ifdef MSW -#define vsnprintf _vsnprintf /* jsarlo -- alias this name for msw */ -#endif - -/* jsarlo { */ -EXTERN double sys_time; -EXTERN double sys_time_per_dsp_tick; -EXTERN int sys_externalschedlib; - -EXTERN t_sample* get_sys_soundout(void); -EXTERN t_sample* get_sys_soundin(void); -EXTERN int* get_sys_main_advance(void); -EXTERN double* get_sys_time_per_dsp_tick(void); -EXTERN int* get_sys_schedblocksize(void); -EXTERN double* get_sys_time(void); -EXTERN float* get_sys_dacsr(void); -EXTERN int* get_sys_sleepgrain(void); -EXTERN int* get_sys_schedadvance(void); - -EXTERN void sys_clearhist(void); -EXTERN void sys_initmidiqueue(void); -EXTERN int sys_addhist(int phase); -EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime); -EXTERN void sched_tick(double next_sys_time); -EXTERN void sys_pollmidiqueue(void); -EXTERN int sys_pollgui(void); -EXTERN void sys_setchsr(int chin, int chout, int sr, int dacblocksize); - -EXTERN void inmidi_noteon( int portno, int channel, int pitch, int velo); -EXTERN void inmidi_controlchange( int portno, int channel, int ctlnumber, int value); -EXTERN void inmidi_programchange( int portno, int channel, int value); -EXTERN void inmidi_pitchbend( int portno, int channel, int value); -EXTERN void inmidi_aftertouch( int portno, int channel, int value); -EXTERN void inmidi_polyaftertouch(int portno, int channel, int pitch, int value); -/* } jsarlo */ - -/* functions in x_midi.c */ -void inmidi_realtimein( int portno, int cmd); -void inmidi_byte( int portno, int byte); -void inmidi_sysex( int portno, int byte); - -/* ----------------------- END OF FORMER S_STUFF ----------------------------- */ - - -/* ----------------------- (v)asprintf missing on mingw... ---------------------------------------------------*/ - -#ifndef HAVE_VASPRINTF -extern int vasprintf(char **str, const char *fmt, va_list ap) throw (); -#endif - -#ifndef HAVE_ASPRINTF -extern int asprintf(char **str, const char *fmt, ...) throw (); -#endif - -/* ----------------------- m_imp.h ---------------------------------------------------*/ - -typedef struct _methodentry { - t_symbol *me_name; - t_gotfn me_fun; - t_atomtype me_arg[MAXPDARG+1]; -} t_methodentry; - -typedef void (*t_bangmethod) (t_pd *x); -typedef void (*t_pointermethod)(t_pd *x, t_gpointer *gp); -typedef void (*t_floatmethod) (t_pd *x, t_float f); -typedef void (*t_symbolmethod) (t_pd *x, t_symbol *s); -typedef void (*t_stringmethod) (t_pd *x, const char *s); -typedef void (*t_listmethod) (t_pd *x, t_symbol *s, int argc, t_atom *argv); -typedef void (*t_anymethod) (t_pd *x, t_symbol *s, int argc, t_atom *argv); - -t_pd *pd_new2(int argc, t_atom *argv); -t_pd *pd_new3(const char *s); - -struct _class { - t_symbol *name; /* name (mostly for error reporting) */ - t_symbol *helpname; /* name of help file */ - t_symbol *externdir; /* directory extern was loaded from */ - size_t size; /* size of an instance */ - t_methodentry *methods; /* methods other than bang, etc below */ - int nmethod; /* number of methods */ - t_method freemethod; /* function to call before freeing */ - t_bangmethod bangmethod; /* common methods */ - t_pointermethod pointermethod; - t_floatmethod floatmethod; - t_symbolmethod symbolmethod; /* or t_stringmethod, but only C++ has anonymous unions, so... */ - t_listmethod listmethod; - t_anymethod anymethod; - t_savefn savefn; /* function to call when saving */ - int floatsignalin; /* onset to float for signal input */ - unsigned gobj:1; /* true if is a gobj */ - unsigned patchable:1; /* true if we have a t_object header */ - unsigned firstin:1; /* if patchable, true if draw first inlet */ - unsigned drawcommand:1; /* a drawing command for a template */ - unsigned newatoms:1; /* can handle refcounting of atoms (future use) */ - unsigned use_stringmethod:1; /* the symbolmethod slot holds a stringmethod instead */ - t_symbol *firsttip; - t_symbol **fields; /* names of fields aka attributes, and I don't mean the #V attributes. */ - int nfields; /* ... and how many of them */ - t_notice notice; /* observer method */ - t_onsubscribe onsubscribe; /* observable method */ -}; - -//#define c_methods methods /* for Cyclone */ -//#define c_nmethod nmethod /* for Cyclone */ -//#define c_externdir externdir /* for PDDP */ -//#define c_name name /* for Cyclone,Creb,Pidip */ -//#define c_size size /* for Cyclone,Flext */ -//#define me_name name /* for Cyclone */ -//#define me_fun fun /* for Cyclone */ -//#define me_arg arg /* for Cyclone */ - -/* m_obj.c */ -EXTERN int obj_noutlets(t_object *x); -EXTERN int obj_ninlets(t_object *x); -EXTERN t_outconnect *obj_starttraverseoutlet(t_object *x, t_outlet **op, int nout); -EXTERN t_outconnect *obj_nexttraverseoutlet(t_outconnect *lastconnect, t_object **destp, t_inlet **inletp, int *whichp); -EXTERN t_outconnect *obj_connect(t_object *source, int outno, t_object *sink, int inno); -EXTERN void obj_disconnect(t_object *source, int outno, t_object *sink, int inno); -EXTERN void outlet_setstacklim(void); -EXTERN int obj_issignalinlet(t_object *x, int m); -EXTERN int obj_issignaloutlet(t_object *x, int m); -EXTERN int obj_nsiginlets(t_object *x); -EXTERN int obj_nsigoutlets(t_object *x); -EXTERN int obj_siginletindex(t_object *x, int m); -EXTERN int obj_sigoutletindex(t_object *x, int m); - -/* misc */ -EXTERN void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir); -EXTERN void glob_initfromgui(void *dummy, t_symbol *s); -EXTERN void glob_quit(void *dummy); - -/* ----------------------- g_canvas.h ------------------------------------------------*/ - -/* i don't know whether this is currently used at all in DesireData. -- matju 2006.09 */ -#ifdef GARRAY_THREAD_LOCK -#include <pthread.h> /* TB: for t_garray */ -#endif - -typedef struct t_gtemplate t_gtemplate; -typedef struct _canvasenvironment t_canvasenvironment; -typedef struct _slot t_slot; - -/* the t_tick structure describes where to draw x and y "ticks" for a canvas */ -typedef struct _tick { /* where to put ticks on x or y axes */ - float point; /* one point to draw a big tick at */ - float inc; /* x or y increment per little tick */ - int lperb; /* little ticks per big; 0 if no ticks to draw */ -} t_tick; - -typedef struct t_boxes t_boxes; - -/* the t_canvas structure, which describes a list of elements that live on an area of a window.*/ -#ifdef PD_PLUSPLUS_FACE -struct _glist : t_object { -#else -struct _glist { - t_object gl_obj; /* header in case we're a [pd] or abstraction */ -#endif - int pixwidth, pixheight; /* width in pixels (on parent, if a graph) */ - float x1,y1,x2,y2; /* bounding rectangle in our own coordinates */ - int screenx1, screeny1, screenx2, screeny2; /* screen coordinates when toplevel */ - int xmargin, ymargin; /* origin for GOP rectangle */ - /* ticks and tick labels */ - t_tick xtick; int nxlabels; t_symbol **xlabel; float xlabely; - t_tick ytick; int nylabels; t_symbol **ylabel; float ylabelx; - t_symbol *name; /* symbol bound here */ - int font; /* nominal font size in points, e.g., 10 */ - t_canvasenvironment *env; /* one of these per $0; env=0 for subpatches */ - unsigned int havewindow:1; /* this indicates whether we publish to the manager */ - unsigned int gop:1; - unsigned int goprect:1; /* gop version >= 0.39 */ - unsigned int hidetext:1; /* hide object-name + args when doing graph on parent */ - long next_o_index; /* next object index. to be incremented on each use */ - long next_w_index; /* next wire index. to be incremented on each use */ - t_boxes *boxes; -}; - -struct _namelist; - -/* LATER consider adding font size to this struct (see canvas_getfont()) */ -struct _canvasenvironment { - t_symbol *dir; /* directory patch lives in */ - int argc; /* number of "$" arguments */ - t_atom *argv; /* array of "$" arguments */ - long dollarzero; /* value of "$0" */ - struct _namelist *path;/* search path (0.40) */ -}; - -/* a data structure to describe a field in a pure datum */ -#define DT_FLOAT 0 -#define DT_SYMBOL 1 -#define DT_CANVAS 2 -#define DT_ARRAY 3 - -typedef struct t_dataslot { - int type; - t_symbol *name; - t_symbol *arraytemplate; /* filled in for arrays only */ -} t_dataslot; - -#ifdef PD_PLUSPLUS_FACE -typedef struct t_template : t_pd { -#else -typedef struct t_template { - t_pd t_pdobj; /* header */ -#endif - t_gtemplate *list; /* list of "struct"/gtemplate objects */ - t_symbol *sym; /* name */ - int n; /* number of dataslots (fields) */ - t_dataslot *vec; /* array of dataslots */ -} t_template; - -/* this is not really a t_object, but it needs to be observable and have a refcount, so... */ -#ifdef PD_PLUSPLUS_FACE -struct _array : t_object { -#else -struct _array { - t_gobj gl_obj; -#endif - int n; /* number of elements */ - int elemsize; /* size in bytes; LATER get this from template */ - char *vec; /* array of elements */ - union { - t_symbol *tsym; /* template for elements */ - t_symbol *templatesym; /* alias */ - }; - t_gpointer gp; /* pointer to scalar or array element we're in */ -}; - -#ifdef PD_PLUSPLUS_FACE -struct _garray : t_gobj { -#else -struct _garray { - t_gobj x_gobj; -#endif - t_scalar *scalar; /* scalar "containing" the array */ - t_canvas *canvas; /* containing canvas */ - t_symbol *name; /* unexpanded name (possibly with leading '$') */ - t_symbol *realname; /* expanded name (symbol we're bound to) */ - unsigned int usedindsp:1; /* true if some DSP routine is using this */ - unsigned int saveit:1; /* true if we should save this with parent */ - unsigned int listviewing:1; /* true if list view window is open */ - unsigned int hidename:1; /* don't print name above graph */ -}; - -t_array *garray_getarray(t_garray *x); - -/* structure for traversing all the connections in a canvas */ -typedef struct t_linetraverser { - t_canvas *canvas; - t_object *from; int nout; int outlet; t_outlet *outletp; - t_object *to; int nin; int inlet; t_inlet *inletp; - t_outconnect *next; - int nextoutno; -#ifdef __cplusplus - t_linetraverser() {} - t_linetraverser(t_canvas *canvas); -#endif -} t_linetraverser; - -extern t_canvas *canvas_list; /* list of all root canvases */ -extern t_class *vinlet_class, *voutlet_class, *canvas_class; -extern int canvas_valid; /* incremented when pointers might be stale */ -EXTERN int sys_noloadbang; -EXTERN t_symbol *s_empty; - -#define PLOTSTYLE_POINTS 0 /* plotting styles for arrays */ -#define PLOTSTYLE_POLY 1 -#define PLOTSTYLE_BEZ 2 - -/* from kernel.c */ -EXTERN void gobj_save(t_gobj *x, t_binbuf *b); -EXTERN void pd_eval_text(const char *t, size_t size); -EXTERN int sys_syntax; - -/* from desire.c */ -EXTERN int pd_scanargs(int argc, t_atom *argv, const char *fmt, ...); -EXTERN int pd_saveargs(t_binbuf *b, const char *fmt, ...); -EXTERN void pd_upload(t_gobj *self); -EXTERN void sys_mgui(void *self, const char *sel, const char *fmt, ...); -EXTERN void canvas_add(t_canvas *x, t_gobj *g, int index=-1); -EXTERN void canvas_delete(t_canvas *x, t_gobj *y); -EXTERN void canvas_deletelinesfor(t_canvas *x, t_text *text); -EXTERN void canvas_deletelinesforio(t_canvas *x, t_text *text, t_inlet *inp, t_outlet *outp); -EXTERN int canvas_isvisible(t_canvas *x); -EXTERN int canvas_istoplevel(t_canvas *x); -EXTERN int canvas_istable(t_canvas *x); -EXTERN int canvas_isabstraction(t_canvas *x); -EXTERN t_canvas *canvas_getcanvas(t_canvas *x); -EXTERN t_canvas *canvas_getrootfor(t_canvas *x); -EXTERN t_canvas *canvas_getcurrent(void); -EXTERN t_canvasenvironment *canvas_getenv(t_canvas *x); -EXTERN int canvas_getdollarzero(void); -EXTERN t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s); -EXTERN t_symbol *canvas_makebindsym(t_symbol *s); - -EXTERN void linetraverser_start(t_linetraverser *t, t_canvas *x); -EXTERN t_outconnect *linetraverser_next(t_linetraverser *t); - -/* -------------------- TO BE SORTED OUT --------------------- */ -EXTERN void canvas_redrawallfortemplatecanvas(t_canvas *x, int action); -EXTERN void array_resize(t_array *x, int n); -EXTERN void word_init(t_word *wp, t_template *tmpl, t_gpointer *gp); -EXTERN void word_restore(t_word *wp, t_template *tmpl, int argc, t_atom *argv); -EXTERN t_scalar *scalar_new(t_canvas *owner, t_symbol *templatesym); -EXTERN void word_free(t_word *wp, t_template *tmpl); -EXTERN void scalar_redraw(t_scalar *x, t_canvas *canvas); -//EXTERN int pd_pickle(t_foo *foo, const char *fmt, ...); -EXTERN void pd_set_newest (t_pd *x); -EXTERN const char *inlet_tip(t_inlet* i,int num); - -extern t_hash<t_pd *,long> *object_table; -extern t_hash<t_symbol *,t_class *> *class_table; - -/* some kernel.c stuff that wasn't in any header, when shifting to C++. */ -void obj_moveinletfirst(t_object *x, t_inlet *i); -void obj_moveoutletfirst(t_object *x, t_outlet *o); -int inlet_getsignalindex(t_inlet *x); -int outlet_getsignalindex(t_outlet *x); -void text_save(t_gobj *z, t_binbuf *b); -t_sample *obj_findsignalscalar(t_object *x, int m); -void class_set_extern_dir(t_symbol *s); -void glob_update_class_info (t_pd *bogus, t_symbol *s, t_symbol *cb_recv, t_symbol *cb_sel); -void pd_free_zombie(t_pd *x); - -/* some other stuff that wasn't in any header */ -void glob_watchdog(t_pd *dummy); - -#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) -} -#endif - -#ifdef __cplusplus -#include<iostream> -// should I remove min,max now? g++ complains about conflict between min and std::min... -// they have the same def. btw i don't know how to refer to my own. -namespace desire { -template <class T> static T min(T a, T b) {return a<b?a:b;} -template <class T> static T max(T a, T b) {return a>b?a:b;} -template <class T> T clip(T a, T b, T c) {return min(max(a,b),c);} -void oprintf(std::ostream &buf, const char *s, ...); -void voprintf(std::ostream &buf, const char *s, va_list args); -}; -EXTERN std::ostringstream lost_posts; -#endif - -#define L post("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__); -#define LS(self) post("%s:%d in %s (self=%lx class=%s)",__FILE__,__LINE__,__PRETTY_FUNCTION__,(long)self, \ - ((t_gobj *)self)->_class->name->name); - -#define STACKSIZE 1024 -struct t_call { - t_pd *self; /* receiver */ - t_symbol *s; /* selector */ - /* insert temporary profiling variables here */ -}; - -EXTERN t_call pd_stack[STACKSIZE]; -EXTERN int pd_stackn; - -EXTERN int gstack_empty(); /* that's a completely different stack: see pd_pushsym,pd_popsym */ - -class Error {}; -class VeryUnlikelyError : Error {}; -inline static int throw_if_negative(int n) {if (n<0) throw VeryUnlikelyError(); else return n;} -#define asprintf(ARGS...) throw_if_negative( asprintf(ARGS)) -#define vasprintf(ARGS...) throw_if_negative(vasprintf(ARGS)) - -#define PERFORM1ARGS(A,a) A a = (A)w[1]; -#define PERFORM2ARGS(A,a,B,b) PERFORM1ARGS(A,a) B b = (B)w[2]; -#define PERFORM3ARGS(A,a,B,b,C,c) PERFORM2ARGS(A,a,B,b) C c = (C)w[3]; -#define PERFORM4ARGS(A,a,B,b,C,c,D,d) PERFORM3ARGS(A,a,B,b,C,c) D d = (D)w[4]; -#define PERFORM5ARGS(A,a,B,b,C,c,D,d,E,e) PERFORM4ARGS(A,a,B,b,C,c,D,d) E e = (E)w[5]; -#define PERFORM6ARGS(A,a,B,b,C,c,D,d,E,e,F,f) PERFORM5ARGS(A,a,B,b,C,c,D,d,E,e) F f = (F)w[6]; -#define PERFORM7ARGS(A,a,B,b,C,c,D,d,E,e,F,f,G,g) PERFORM6ARGS(A,a,B,b,C,c,D,d,E,e,F,f) G g = (G)w[7]; -#define PERFORM8ARGS(A,a,B,b,C,c,D,d,E,e,F,f,G,g,H,h) PERFORM7ARGS(A,a,B,b,C,c,D,d,E,e,F,f,G,g) H h = (H)w[8]; - -#endif /* __DESIRE_H */ diff --git a/desiredata/src/desire.tk b/desiredata/src/desire.tk deleted file mode 100644 index c4dac9d7..00000000 --- a/desiredata/src/desire.tk +++ /dev/null @@ -1,8712 +0,0 @@ -#!/usr/bin/env wish -set svnid {$Id$} -#-----------------------------------------------------------------------------------# -# -# DesireData -# Copyright (c) 2004 by Mathieu Bouchard -# Copyright (c) 2005,2006,2007 by Mathieu Bouchard and Chun Lee -# -# 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. - -# See file ../COPYING.desire-client.txt for further informations on licensing terms. -# -# 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. -# -# Note that this is not under the same license as the rest of PureData. -# Even the DesireData server-side modifications stay on the same license -# as the rest of PureData. -# -#-----------------------------------------------------------------------------------# - -# this command rebuilds the package index: echo pkg_mkIndex . | tclsh - -set debug 0 ;# DON'T TOUCH THIS, make yourself a debug.tcl instead! - -if {$tcl_version < 8.5} {puts "Please upgrade to Tcl/Tk 8.5... Thank You.\n(your version is $tcl_version)"; exit 84} - -if {[catch {winfo children .}]} {set tk 0} {set tk 1} - -set argh0 [file normalize [file join [pwd] $argv0]] -set auto_path [concat . \ - [list [file join [file dirname [file dirname $argh0]] lib/pd/bin]] \ - /usr/share/tcltk/tcllib1.10/profiler \ - /usr/lib/tclx8.4 \ - $auto_path] - -package require poe -if {$tk} {package require bgerror} - -catch {package require Tclx} -#if {[catch {source /home/matju/src/svn-pd/desiredata/src/profile_dd.tcl}]} {error_dump} -if {[file exists debug.tcl]} {source debug.tcl} - -proc which {file} { - global env - foreach dir [split $::env(PATH) ":"] { - if {[file exists $dir/$file]} {return $dir/$file} - } - return "" -} - -#-----------------------------------------------------------------------------------# -# some list processing functions and some math too -# these could become another library like objective.tcl -# if they become substantial enough - -# min finds the smallest of two values -# max finds the biggest of two values -# [clip $v $min $max] does [max $min [min $max $v]] -proc min {x y} {expr {$x<$y?$x:$y}} -proc max {x y} {expr {$x>$y?$x:$y}} -proc clip {x min max} { - if {$x<$min} {return $min} - if {$x>$max} {return $max} - return $x -} - -# set several variables from elements of a list -# WARNING: for @-variables, use [list @a @b @c] instead of {@a @b @c} -proc mset {vars list} { - uplevel 1 "foreach {$vars} {$list} {break}" -} - -# add or subtract two lists -proc l+ { al bl} {set r {}; foreach a $al b $bl {lappend r [expr {$a+$b}]}; return $r} -proc l- { al bl} {set r {}; foreach a $al b $bl {lappend r [expr {$a-$b}]}; return $r} -# halve a list -proc l/2 { al } {set r {}; foreach a $al {lappend r [expr {$a/2 }]}; return $r} - -# like l+ or l- but for any infix supported by expr -proc lzip {op al bl} { - set r {} - set e "\$a $op \$b" - foreach a $al b $bl {lappend r [expr $e]} - return $r -} - -# do an operation between all elements of a list and a second argument -proc lmap {op al b } { - set r {} - set e "\$a $op \$b" - foreach a $al {lappend r [expr $e]} - return $r -} - -# sum and product of a list, like math's capital Sigma and capital Pi. -proc lsum {al} {set r 0; foreach a $al {set r [expr {$r+$a}]}; return $r} -proc lprod {al} {set r 1; foreach a $al {set r [expr {$r*$a}]}; return $r} - -# all elements from end to beginning -proc lreverse {list} { - set r {} - for {set i [expr {[llength $list]-1}]} {$i>=0} {incr i -1} {lappend r [lindex $list $i]} - return $r -} - -# list substraction is like set substraction but order-preserving -# this is the same algorithm as Ruby's - operation on Arrays -proc lwithout {a b} { - set r {} - foreach x $b {set c($x) {}} - foreach x $a {if {![info exists c($x)]} {lappend r $x}} - return $r -} - -proc lintersection {a b} { - set r {} - foreach x $b {set c($x) {}} - foreach x $a {if {[info exists c($x)]} {lappend r $x}} - return $r -} - -# removes duplicates from a list, but it must be already sorted. -proc luniq {a} { - set last [lindex $a 0] - set r [list $last] - set i 0 - foreach x $a { - if {$i && [string compare $last $x]} {lappend r $x} - incr i; set last $x - } - return $r -} - -# one-dimensional intervals (left-closed, right-open); not much in use at the moment, not that they wouldn't deserve to! -# (slightly buggy) -proc inside {x x0 x1} {return [expr {$x>=$x0 && $x<$x1}]} -proc overlap {y0 y1 x0 x1} {return [expr {[inside $y0 $x0 $x1] || [inside $y1 $x0 $x1]}]} - -proc distance {point1 point2} { - set off [l- $point1 $point2] - return [expr {sqrt([lsum [lzip * $off $off]])}] -} - -proc rect_centre {rect} { - mset {x1 y1 x2 y2} $rect - return [list [expr {($x1+$x2)/2}] [expr {($y1+$y2)/2}]] -} - -proc lmake {start end} {for {set i $start} {$i<=$end} {incr i} {lappend l $i}; return $l} -#-----------------------------------------------------------------------------------# -set callback_list {} - -proc append_callback {mode when def} { - global callback_list - dict set callback_list $mode $when $def -} - -proc remove_callback {mode} { - global callback_list - set callback_list [dict remove $callback_list $mode] -} - -proc modes_callback {self def {args}} { - global callback_list - set i 0 - dict for {mode callbacks} $callback_list { - foreach {when call} $callbacks { - if {$def == $when} {eval $self $call $args; incr i} - } - } - if {!$i} {return 0} else {return 1} -} - -#-----------------------------------------------------------------------------------# -# Observer pattern -# there's no class for "observer". -# it's anything that has def $myclass notice {args} {...} in which args indicate -# attributes that have changed, or is an empty list if an unspecified number of -# attributes (maybe all) have changed. - -class_new Observable {} -def Observable init {args} { - eval [concat [list super] $args] - set @subscribers {} -} -def Observable subscribe {observer} { - set i [lsearch $@subscribers $observer] - if {$i<0} {lappend @subscribers $observer} -} -def Observable unsubscribe {observer} { - set i [lsearch $@subscribers $observer] - if {$i>=0} {set @subscribers [lreplace $@subscribers $i $i]} -} - -if {$have_expand} { - #def Observable changed {args} { - # puts "Observable changed $self called from [info level [expr [info level]-2]]" - # foreach x $@subscribers {$x notice $self {expand}$args]} - #} - def Observable changed {args} {foreach x $@subscribers {$x notice $self {expand}$args}} - def Observable child_changed {origin args} {foreach x $@subscribers {$x notice $origin {expand}$args}} -} else { - def Observable changed {args} {foreach x $@subscribers {$x notice $self {*}$args}} - def Observable child_changed {origin args} {foreach x $@subscribers {$x notice $origin {*}$args}} -} -def Observable subscribers {} {return $@subscribers} - -#-----------------------------------------------------------------------------------# -set poolset(foo) bar -array unset poolset foo - -class_new Manager {Thing} - -def Manager init {} { - set @q {} - $self call -} - -def Manager call {} { - #if {[llength $@q]} {post "client queue %d" [llength $@q]} - for {set i 0} {$i < [llength $@q]} {incr i} { - set o [lindex $@q $i] - unset ::poolset($o) - if {[info exists _($o:_class)]} { - if {[catch {$o draw_maybe}]} {puts [error_dump]} - } else { - puts " tries to draw ZOMBIE $o" - } - if {$i == [expr {[llength $@q]-1}]} {set @q {}} - } - after 25 [list $self call] -} - -def Manager notice {origin args} { - if {[info exists ::poolset($origin)]} { - # post %s "def Manager notice: double dirty" - # nothing for now - } { - set ::poolset($origin) {-1} - lappend @q $origin - } - #post "Manager notice: queue length is now %d" [llength $@q] -} - -set serial 0 -proc serial {n obj} { - if {$n >= $::serial} {error "object creation serial number is in the future"} - eval [concat $::replyset($n) [list $obj]] - array unset ::replyset $n -} - -proc philtre {atoms} { - set r {} - foreach atom $atoms {lappend r [regsub -all {([;,\\ ])} $atom {\\\1}]} - return [join $r] -} - -# you pass the 2nd argument if and only if the message creates an object (or pretends to). -# this happens with #N canvas, and those methods of #X: -# obj, msg, floatatom, symbolatom, text, connect, text_setto, array. -# this does NOT happen with #X coords/restore/pop. -proc netsend {message {callback ""}} { - #if {$message == ""} {error "empty message... surely a mistake"} - if {$::sock == ""} {error "connection to server needed for doing this"} - if {$callback != ""} { - set ::replyset($::serial) $callback - set message [concat [lrange $message 0 0] [list with_reply $::serial] [lrange $message 1 end]] - incr ::serial - } - set text "[philtre $message];" - if {$::debug} {puts "[VTcyan]<- $text[VTgrey]"} - puts $::sock $text -} - -#-----------------------------------------------------------------------------------# -# This is not a real Hash, just the same interface as a Ruby/Python/Perl Hash... or quite like Tcl arrays themselves -class_new Hash {Thing} - -def Hash init {args} { super; foreach {k v} $args {$self set $k $v}} -def Hash reinit {args} {$self clear; foreach {k v} $args {$self set $k $v}} -def Hash set {k v} {set ::hash($self:$k) $v} -def Hash exists {k} {info exists ::hash($self:$k)} -def Hash get {k} {set ::hash($self:$k)} -def Hash size {} {llength [$self keys]} -def Hash unset {k} {unset ::hash($self:$k)} -def Hash list {} {set r {}; foreach k [$self keys] {lappend r $k [$self get $k]}; return $r} -def Hash keys {} { - set r {} - set n [string length $self:] - foreach k [array names ::hash $self:*] {lappend r [string range $k $n end]} - return $r -} -def Hash values {} { - set r {} - foreach k [array names ::hash $self:*] {lappend r $::hash($k)} - return $r -} -def Hash clear {} {foreach k [$self keys] {$self unset $k}} -def Hash delete {} {$self clear; super} - -def Hash search {v} { - foreach k [$self keys] {if {[$self get $k] == $v} {return $k}} - return -1 ;# this is not correct as -1 could be a Hash key, though not in its current context of use... -} - -if 0 { - set h [Hash new foo bar 1 2 3 4] - $h set hello world - puts keys=[$h keys] - puts values=[$h values] - puts list=[$h list] - $h unset foo - puts list=[$h list] - $h clear - puts list=[$h list] - foreach i {1 2 3 4} {puts "exists $i : [$h exists $i]"} -} - -class_new Selection {Hash} -def Selection set {k v} {super $k $v; $v selected?= 1} -def Selection unset {k} { - #set v [$self get $k]; puts "$v ::: [$v class]" - if {[$self exists $k]} {[$self get $k] selected?= 0} - super $k -} -#-----------------------------------------------------------------------------------# -# abstract class: subclass must def {value value= <<} -class_new Clipboard {Observable Thing} -def Clipboard init {{value ""}} {super; $self value= $value; set @copy_count 0} - -# uses system clipboard -class_new Clipboard1 {Clipboard} -def Clipboard1 value= {value} {clipboard clear; clipboard append $value; $self changed} -def Clipboard1 << {value} { clipboard append $value; $self changed} -def Clipboard1 value {} {clipboard get} - -# uses string buffer (not system clipboard) -class_new Clipboard2 {Clipboard} -def Clipboard2 value= {value} {set @value $value; $self changed} -def Clipboard2 << {value} {append @value $value; $self changed} -def Clipboard2 value {} {return $@value} - -if {$tk} { - set clipboard [Clipboard1 new] -} else { - set clipboard [Clipboard2 new] -} - -#-----------------------------------------------------------------------------------# -class_new EventHistory {Observable Thing} - -def EventHistory init {} {super; set @list {}} -def EventHistory add {e} {lappend @list $e; $self changed add $e} -def EventHistory list {{formatted 1}} { - if {!$formatted} {return $@list} - set r {} - foreach event $@list { - mset {type W x y mod K k} $event - lappend r [format "%-13s %9s %4d %4d %4d %4d %s" $type $K $k $x $y $mod $W] - } - return $r -} -set ::event_history [EventHistory new] - -#-----------------------------------------------------------------------------------# -class_new CommandHistory {Observable Thing} - -def CommandHistory init {} { - super - set @undo_stack {} - set @redo_stack {} -} - -def CommandHistory can_undo? {} {return [expr {[llength @undo_stack] > 0}]} -def CommandHistory can_redo? {} {return [expr {[llength @redo_stack] > 0}]} -def CommandHistory next_undo_name {} {return stuff} -def CommandHistory next_redo_name {} {return stuff} -def CommandHistory undo_stack {} {return $@undo_stack} -def CommandHistory redo_stack {} {return $@redo_stack} - -# overload this if you want to control how many levels -# of undo may be kept. -# keep in mind that undo information is kept hierarchically. -def CommandHistory add {message} { - lappend @undo_stack [list do $message [lrange [info level -3] 1 end]] - set @redo_stack {} - $self changed -} - -def CommandHistory can't {} { - lappend @undo_stack [list can't {} [lrange [info level -3] 1 end]] - set @redo_stack {} - $self changed -} - -# runs the restore procedure for the last item in the root undo queue. -def CommandHistory undo {} { - if {![$self can_perform? [lindex $@undo_stack end]]} {error "Can't undo this!"} - set backup $@undo_stack - set @undo_stack $@redo_stack - set @redo_stack {} - #set err [catch {$self perform [lindex $backup end]}]; if {$err} {set err $::errorInfo} - $self atomically [list atomic_undo] { - $self perform [lindex $backup end] - } - set @redo_stack $@undo_stack - set @undo_stack [lrange $backup 0 end-1] - $self changed - #if {$err} {post %s $err; error "undo: $err"} -} - -def CommandHistory redo {} { - if {![$self can_perform? [lindex $@undo_stack end]]} {error "Can't redo this!"} - set backup $@redo_stack - set @redo_stack {} - set err [catch {$self perform [lindex $backup end]}]; if {$err} {set err $::errorInfo} - $self atomically [list atomic_redo] { - $self perform [lindex $backup end] - } - set @redo_stack [lrange $backup 0 end-1] - $self changed - #if {$err} {post %s $err; error "redo: $err"} -} - -def CommandHistory can_perform? {action} { - switch -- [lindex $action 0] { - do {return 1} - can't {return 0} - default { - foreach x [lrange $action 1 end] { - if {![$self can_perform? $x]} {return 0} - } - return 1 - } - } -} - -def CommandHistory perform {action} { - switch -- [lindex $action 0] { - do {eval [lindex $action 1]} - can't {error "can't undo this!"} - default {foreach x [lreverse [lindex $action 1]] {$self perform $x}} - } -} - -def CommandHistory atomically {what code} { - set ubackup @undo_stack; set @undo_stack {} - set rbackup @redo_stack; set @redo_stack {} - uplevel 2 $code - set atom $@undo_stack - set @undo_stack $ubackup - set @redo_stack $rbackup - lappend @undo_stack [list $what $atom [lrange [info level -3] 1 end]] - $self changed -} - -def CommandHistory list {} { - set r {} - set hist [concat [$self undo_stack] [list "You Are Here"] [lreverse [$self redo_stack]]] - set i 0 - foreach e $hist {lappend r "$i: $e"; incr i} - return $r -} - -set command_history [CommandHistory new] - -#-----------------------------------------------------------------------------------# -class_new History {Thing} - -def History init {size} { - set @size $size - set @hist {{}} - set @histi -1 -} - -def History histi= {val} {set @histi $val} -def History histi {} {return $@histi} - -def History set_hist {idx stuff} {set @hist [lreplace $@hist $idx $idx $stuff]} - -def History prepend {stuff} { - set @hist [linsert $@hist 1 $stuff] - if {[llength $@hist] >= $@size} {set @hist [lrange $@hist 0 [expr {$@size-1}]]} -} - -def History traverse {incr} { - set @histi [expr {$@histi + $incr}] - set mod [min [llength $@hist] [expr {$@size+1}]] - if {$@histi >=$mod} {set @histi [expr $@histi%$mod]} - if {$@histi < 0} {set @histi [expr ($@histi+$mod)%$mod]} - return [lindex $@hist $@histi] -} - -History new_as obj_hist 5 -#-----------------------------------------------------------------------------------# -# this is the beginning of the more application-dependent part. - -switch $tcl_platform(os) { - Darwin {set OS osx} - default {set OS $tcl_platform(platform)} -} - -if {$tk} { - option add *foreground #000000 - option add *font {Helvetica -12} - foreach tkclass {Menu Button Checkbutton Radiobutton Entry Text Spinbox Scrollbar Canvas} { - option add *$tkclass*borderWidth 1 - option add *$tkclass*activeBorderWidth 1 - } - foreach tkclass {CheckButton RadioButton} { - option add *$tkclass*selectColor #dd3000 - } - foreach tkclass {Entry Text} { - option add *$tkclass*background #b0c4d8 - option add *$tkclass*selectBackground #6088b0 - } - option add *__tk__messagebox*Canvas*borderWidth 0 - foreach tkclass {Listbox} { - option add *$tkclass*background #c4d8b0 - option add *$tkclass*selectBackground #88b060 - } - foreach tkclass {Label} { - #option add *$tkclass*background #909090 - } - # very small icons: - foreach {name w h values} { - icon_empty 7 7 "0,0,0,0,0,0,0" - icon_plus 7 7 "8,8,8,127,8,8,8" - icon_minus 7 7 "0,0,0,127,0,0,0" - icon_close 7 7 "99,119,62,28,62,119,99" - icon_wedge_up 7 5 "8,28,62,127,0" - icon_wedge_down 7 5 "0,127,62,28,8" - icon_up 7 7 "8,28,62,127,28,28,28" - icon_down 7 7 "28,28,28,127,62,28,8" - icon_right 7 7 "8,24,63,127,63,24,8" - icon_left 7 7 "8,12,126,127,126,12,8" - } { - image create bitmap $name -data "#define z_width $w\n#define z_height $h - static unsigned char z_bits[] = { $values };" - } - - - set main [. cget -class] - set ::current_window . - bind $main <FocusIn> {set ::current_window %W} - bind Toplevel <FocusIn> {set ::current_window %W} - proc tk_messageBox2 {args} {tk_messageBox -parent $::current_window {*}$args} - - # Also we have to get rid of tab's changing the focus. - bind all <Key-Tab> "" - #bind all <Key-Shift-Tab> "" - bind all <<PrevWindow>> "" - set mods {{} 0 Shift- 1 Control- 4 Shift-Control- 5 Alt- 8 Shift-Alt- 9 Control-Alt- 12 Shift-Control-Alt- 13} - foreach type {KeyPress KeyRelease} { - foreach {subtype mod} $mods { - bind all <$subtype$type> "$::event_history add \[list $type %W %x %y $mod %K %k\]" - } - } - foreach type {ButtonPress ButtonRelease} { - foreach {subtype mod} $mods { - bind all <$subtype$type> "$::event_history add \[list $type %W %x %y $mod %b %b\]" - } - } -} - -proc modekey {k mode} { - set s "" - if {$mode&1} {append s Shift-} - if {$mode&4} {append s Control-} - if {$mode&8} {append s Alt-} - if {[regexp {[0-9]} $k]} {set k Key-$k} - return $s$k -} - -proc modeclick {k mode event} { - set s "" - if {$mode&1} {append s Shift-} - if {$mode&4} {append s Control-} - if {$mode&8} {append s Alt-} - if {[regexp {[0-9]} $k]} {set k $event-$k} - return $s$k -} - -# there are two palettes of 30 colours used in Pd -# when placed in a 3*10 grid, the difference is that -# the left corner of 3*3 (the greys) are transposed (matrixwise) -# here is the one used in the swatch color selector: -set preset_colors { - fcfcfc e0e0e0 bcbcbc fce0e0 fce0c0 fcfcc8 d8fcd8 d8fcfc dce4fc f8d8fc - a0a0a0 7c7c7c 606060 fc2828 fcac44 e8e828 14e814 28f4f4 3c50fc f430f0 - 404040 202020 000000 8c0808 583000 782814 285014 004450 001488 580050 -} - -switch $::OS { - osx {set pd_tearoff 0} - default {set pd_tearoff 1} -} - -proc guess_lang {} { - set lang C - if {[info exist ::env(LC_ALL)]} {set lang $::env(LC_ALL)} - if {[info exist ::env(LANG)]} {set lang $::env(LANG)} - set lang [lindex [split $lang {[_.]}] 0] - return $lang -} - -#temporary -set leet 0 - -proc say {k args} { - global text - if {[llength $args]} { - set text($k) [lindex $args 0] - } else { - if {[info exist text($k)]} { - if {$::leet} { - return [string map -nocase {a 4 e 3 t 7 s 5 i 1 o 0 g 9} $text($k)] - } else { - return $text($k) - } - } else {return "{{$k}}"} - } -} - -proc can_say {k args} { - return [info exist ::text($k)] -} - -proc say_namespace {k code} {uplevel 1 $code} -proc say_category {text} {} - -switch -- [lindex [file split $argh0] end] { - desire.tk {set cmdline(server) [file join [file dirname $argh0] pd]} - default {set cmdline(server) [file join [file dirname [file dirname $argh0]] bin/pd]} -} - -set cmdline(rcfilename) ~/.pdrc -set cmdline(ddrcfilename) ~/.ddrc -set cmdline(console) 1000 -if {[file exists ../icons/mode_edit.gif]} { - set cmdline(icons) ../icons -} else { - set cmdline(icons) [file join [file dirname [file dirname $argh0]] lib/pd/icons] -} - -#-----------------------------------------------------------------------------------# -set accels {} -proc read_client_prefs_from {filename} { - global cmdline look key accels - set ::accels {} - puts "reading from $filename" - set fd [open $filename] - set contents [read $fd] - close $fd - foreach {category category_data} $contents { - foreach {class class_data} $category_data { - foreach {var val} $class_data {set ${category}($class:$var) $val} - } - } - foreach k [array names key] { - if {[llength $key($k)]} { - if {![dict exists $accels $key($k)]} { - dict set accels $key($k) $k - } else { - dict lappend accels $key($k) $k - } - } - } -} -proc read_ddrc {} { ;# load defaults then load .ddrc - if {[file exists "defaults.ddrc"]} { - read_client_prefs_from "defaults.ddrc" - } else { - read_client_prefs_from [file join [file dirname [file dirname $::argh0]] "lib/pd/bin/defaults.ddrc"] - } - if {[file exists $::cmdline(ddrcfilename)]} { - read_client_prefs_from $::cmdline(ddrcfilename) - } -} -read_ddrc - -#-----------------------------------------------------------------------------------# - -set cmdline(port) 0 -set cmdline(gdb) 0 -set cmdline(gdbconsole) 1 -set cmdline(valgrind) 0 -if {$look(View:language) eq "auto"} { - set language [guess_lang] -} else { - set language $look(View:language) -} - -set files_to_open {} - -proc cmdline_help {} { - puts "DesireData commandline options: - -serverargs (for future use) - -server select the executable for the pd server - -gdb run pd server through gdb - -manualgdb run gdb in the terminal - -valgrind run pd server through valgrind - -novalgrind ... or don't - -safemode run desiredata with all default settings - -dzinc use zinc emulation" -} - -for {set i 0} {$i < $argc} {incr i} { - global cmdline files_to_open - set o [lindex $argv $i] - switch -regexp -- $o { - ^-port\$ {incr i; set cmdline(port) [lindex $argv $i]} - ^-serverargs\$ {error "not supported yet"} - ^-server\$ {incr i; set cmdline(server) [lindex $argv $i]} - ^-gdb\$ {set cmdline(gdb) 1} - ^-manualgdb\$ {set cmdline(gdbconsole) 0} - ^-valgrind\$ {set cmdline(valgrind) 1} - ^-novalgrind\$ {set cmdline(valgrind) 0} - ^-safemode\$ {set cmdline(safemode) 1} - ^-dzinc\$ {set cmdline(dzinc) 1} - ^(-h|-help|--help)\$ {cmdline_help; exit 1} - ^- {puts "ERROR: command line argument: unknown $o"} - default {lappend files_to_open [lindex $argv $i]} - } -} - -#set cmdline(server) \"$cmdline(server)\" -set encoding "" -if {$language == "C"} {set language en} -proc localedir {x} {file join [file dirname [file dirname $::argh0]] lib/pd/bin/$x} -if {[regexp {desire\.tk$} $argh0]} {source locale/index.tcl} {source [localedir locale/index.tcl]} -puts "locale/index.tcl vs [localedir locale/index.tcl]" -set langentry [figure_out_language $language] -set encoding [lindex $langentry 0] -set langfile locale/[lindex $langentry 1].tcl -if {[regexp {desire\.tk$} $argh0]} { - if {$encoding != ""} {source -encoding $encoding $langfile} else {source $langfile} -} else { - if {$encoding != ""} {source -encoding $encoding [localedir $langfile]} else {source [localedir $langfile]} -} - -if {[info exists ::cmdline(safemode)]} {read_client_prefs_from "defaults.ddrc"} -if {[info exists ::cmdline(dzinc)]} {package require dzinc} - -#-----------------------------------------------------------------------------------# - -#!@#$ is this still valid? -set look(Box:extrapix) [switch $::OS { - osx {concat 2} - default {concat 1}}] - -#font is defined as Thing for now, as the completion needs to get to these ones. - -#!@#$ View->??? -#set look(View:tooltip) 1 - -#!@#$ View->TextBox ? -#set look(View:minobjwidth) 21 - -#!@#$ View->ObjectBox -#set look(View:fg) #000000 -#set look(View:bg) #ffffff -#set look(View:frame1) #99cccc -#set look(View:frame2) #668888 -#set look(View:frame3) #000000 - -set zoom(canned) [list 25 33 50 75 100 125 150 200 250 300 400] -set scale_amount 1.1 -################## set up main window ######################### - -class_new Console {View} - -def Console osx_scroll {axis diff} {$@c.1 yview scroll [expr {-2-abs($diff)/$diff}]} - -def Console init {c} { - set @c $c - frame $c - text $c.1 -width 72 -height 20 -yscrollcommand "$c.2 set" -font [$self look font] - scrollbar $c.2 -command "$c.1 yview" - pack $c.1 -side left -fill both -expand yes - pack $c.2 -side left -fill y -expand no - pack $c -fill both -expand yes - $c.2 set 0.0 1.0 - switch $::OS {osx {bind $c.1 <MouseWheel> [list $self osx_scroll %D]}} - set @lines 0 -} - -def Console widget {} {return $@c} - -def Console post_string {x} { - set oldpos [lindex [$@c.2 get] 1] - $@c.1 insert end $x - regsub -all "\n" $x "" y - set n [expr {[string length $x]-[string length $y]}] - incr @lines $n - set max $::cmdline(console) - if {$@lines >= $max} {$@c.1 delete 1.0 [expr {$@lines-$max+1}].0; set @lines $max} - if {$oldpos > 0.9999} {$@c.1 see end} -} - -#class_new Client {Menuable View} -class_new Client {Menuable Thing} - -set ctrls_audio_on 0 -set ctrls_meter_on 0 - -def Client window {} {return .} - -def Client init_binds {} { - bind . <Control-Key> {$main ctrlkey %x %y %K %A 0} - bind . <Control-Shift-Key> {$main ctrlkey %x %y %K %A 1} - switch $::OS { - osx { - bind . <Mod1-Key> {$main ctrlkey %x %y %K %A 0} - bind . <Mod1-Shift-Key> {$main ctrlkey %x %y %K %A 1} - } - } -# bind . <Motion> {.debug.1 configure -text "widget = %W"} -} - -# miller uses this nowadays (matju fished it in pd-cvs for 0.40). we don't use it for now. -# remember to fix all quoting problems, which in the end may or may not involve the following proc. -proc pdtk_unspace {x} { - set y [string map {" " "_" ";" "" "," "" "{" "" "}" "" "\\" ""} $x] - if {$y == ""} {set y "empty"} - concat $y -} - -proc pdtk_pd_meters {indb outdb inclip outclip} { - foreach {z clip db} [list in $inclip $indb out $outclip $outdb] { - .controls.$z.1.mtr coords m 0 0 $db 0 - .controls.$z.1.clip configure -background [if {$clip==1} {concat red} {concat black}] - } -} - -proc pd_startup {version apilist midiapilist args} { - set ::pd_version $version - set ::pd_apilist $apilist - set ::pd_midiapilist $midiapilist - foreach api $apilist { - lappend ::pd_apilist2 "-[string tolower [lindex $api 0]]" - } - set version [regsub "^DesireData " $::pd_version ""] - post "DesireData server version $version" -} - -def Client init_controls {} { - menu .mbar - pack [frame .controls] -side top -fill x - foreach t {file window help} { - .mbar add cascade -label [say $t] -menu [menu .mbar.$t -tearoff $::pd_tearoff] - } - .mbar.window configure -postcommand "$self fix_window_menu" - foreach {z fill} {in #0060ff out #00ff60} { - set f .controls.$z - frame $f - frame $f.1 -borderwidth 2 -relief groove - canvas $f.1.mtr -width 100 -height 10 -bg #222222 - $f.1.mtr create line [list 0 0 0 0] -width 24 -fill $fill -tags m - canvas $f.1.clip -width 5 -height 10 -bg #222222 - pack $f.1.mtr $f.1.clip -side left - pack [label $f.2 -text [say $z]:] $f.1 -side left - pack $f -side left -pady 0 -padx 0 - } - foreach {w x y z} { - audiobutton audio ctrls_audio_on {netsend [list pd dsp $ctrls_audio_on]} - meterbutton meters ctrls_meter_on {netsend [list pd meters $ctrls_meter_on]} - } { - pack [checkbutton .controls.$w -text [say $x] -variable $y -anchor w -command $z] -side left - } - button .controls.clear -text [say console_clear] -command {.log.1 delete 0.0 end} -padx 2 -pady 0 - button .controls.dio -text [say io_errors] -command {netsend [list pd audiostatus]} -padx 2 -pady 0 - pack .controls.clear .controls.dio -side right - if {$::debug} { - frame .debug - pack [label .debug.1 -anchor w -text ""] -side left - pack [entry .debug.3 -textvariable ::serial -width 5] -side right - pack [label .debug.2 -text "obj.serial: " -justify right] -side right - pack .debug -side bottom -fill x - } - if {$::cmdline(console)} {set ::console [Console new .log]} - . configure -menu .mbar - wm title . "DesireData" - catch {wm iconphoto . icon_pd_32} - if {[regexp {\d\d\d\d-\d\d-\d\d} $::svnid date]} { - regsub -all "/" $date "." date - regexp {desire.tk (\d+)} $::svnid blah revision - set version "svn#$revision ($date)" - } {set version "(unknown svn version)"} - set ::pd_version_client $version - post "DesireData client version %s" $version - post "Running from %s" [info script] - post "Using Tcl %s and Tk %s" $::tcl_patchLevel $::tk_patchLevel -} - -proc pdtk_pd_dsp {value} { - global ctrls_audio_on - set ctrls_audio_on $value -} - -proc pdtk_pd_dio {red} { - .controls.dio configure -background red -activebackground [if {$red==1} {list red} {list lightgrey}] -} - -############### set up global variables ################################ - -set pd_opendir [pwd] - -############### set up socket ########################################## -set sock {} -set sock_lobby {} - -proc poll_sock {} { - global sock sock_lobby cmdline - if {[llength $sock]==0} {return} - while {1} { - set cmd [gets $sock] - if {[eof $sock]} { - if {!$cmdline(gdb)} { - tk_messageBox2 -message "connection ended by server.\n(crash? try: desire -gdb)" -type ok - } - set sock {} - return - } - if {[fblocked $sock]} {break} - if {$::debug} {if {[string first pdtk_post $cmd]!=0} {puts "[VTmagenta]-> $cmd[VTgrey]"}} - append sock_lobby "\n$cmd" - if {[catch {eval $sock_lobby}]} { - switch -regexp -- $::errorInfo { "^missing close-brace" { - #puts "waiting for the end of: [string range $sock_lobby 0 40]" - continue - }} - error_dump - } - set sock_lobby {} - } - flush $sock - after 25 poll_sock -} - -set server_pid 0 -proc poll_gdb {} { - global gdb - while {1} { - set line [gets $gdb] - if {$line=="" || [fblocked $gdb]} {break} ;# which way should i check for no input? - if {[eof $gdb]} {return} - regsub {^\(gdb\) ?} $line {} line - if {[regexp {^\[Thread debug} $line]} {continue} - if {[regexp {^\[New Thread.*LWP (\d+)} $line dummy pid]} { - if {!$::server_pid} { - set ::server_pid $pid - post "server pid=$pid" - continue - } - } - if {[regexp {^Reading symbols from} $line]} {continue} - if {[regexp {^Using host libthread_db} $line]} {continue} - if {[regexp {^Starting program:} $line]} {continue} - if {[regexp {^Program received signal (\w+), (.*)\.} $line bogus sig1 sig2]} { - set where "" - # can anyone figure out why a long backtrace won't be slurped in this case? - set timeout [expr {[clock seconds]+2}] - #fconfigure $gdb -blocking 1 -buffering none - while {![eof $gdb] && [clock seconds] < $timeout} { - set line [gets $gdb] - if {$line eq ""} {continue} ;# busy-wait - regsub {^\(gdb\) ?} $line {} line - append where "$line\n" - #puts "where size = [string length $where]" - } - OopsDialogue new $sig1 $sig2 $where - } - post "\[gdb\] %s" $line - } - after 100 poll_gdb -} - -proc pd_connect {} { - global sock - if {[catch {set sock [socket 127.0.0.1 13666]}]} { - post "can't connect... wait a second" - after 1000 pd_connect - return - } - post "Connected to server" - fconfigure $sock -blocking 0 -buffering line - netsend [list pd init] - poll_sock - foreach f $::files_to_open { - set ff [file split [file normalize $f]] - set ffl [llength $ff] - set file [lindex $ff [expr $ffl-1]] - set dir [join [lrange $ff 0 [expr $ffl-2]] [file separator]] - netsend [join [list pd open $file $dir]] - } -} - -set server_port 13666 -after 1000 pd_connect - -after 0 { - if {$cmdline(port)} { - set server_port $cmdline(port) - # and then do nothing... - } elseif {$cmdline(valgrind)} { - #exec valgrind --tool=memcheck $cmdline(server) -guiport $server_port & - exec valgrind --tool=memcheck --gen-suppressions=all --suppressions=valgrind3.supp $cmdline(server) -guiport $server_port & - } else { - if {$cmdline(gdb)} { - if {$cmdline(console) && $cmdline(gdbconsole)} { - set gdb [open "| gdb --quiet 2&>1" w+] - fconfigure $gdb -blocking 0 -buffering none - puts $gdb "file \"$cmdline(server)\"" ;# bad quoting, sorry - puts $gdb "set width 242" - puts $gdb "run -guiport $server_port" - puts $gdb "where" - puts $gdb "quit" - flush $gdb - after 0 poll_gdb - } else { - exec gdb --args $cmdline(server) -guiport $server_port & - #exec gdb --tui --args $cmdline(server) -guiport $server_port & - } - } else { - exec $cmdline(server) -guiport $server_port & - } - } -} - -################ utility functions ######################### - -proc enquote {x} { - set foo [string map {"," "" ";" "" "\"" ""} $x] - return [string map {" " "\\ " "{" "" "}" ""} $foo] -} - -proc pdtk_watchdog {} {netsend [list pd ping]; after 2000 {pdtk_watchdog}} - -proc accel_munge {acc} { - switch $::OS { - osx { - set tmp [string toupper [string map {Ctrl Meta} $acc] end] - if [string is upper [string index $acc end]] { - return Shift+$tmp - } else { - return $tmp - } - } - default {return $acc} - } -} - -# a menuable must be a View -# and it must have a window so that the Menuable methods work -# it could be renamed to Windowed -class_new Menuable {} -def Menuable init {args} { - eval [concat [list super] $args] - set @accel {} - set @menubar .$self.m -} - -# this doesn't have to do with menus, only with toplevel windows. -def Menuable raise {} { - set w [$self window] - set w $w.c - raise $w - focus -force $w -} - -set untitled_number 1 -set untitled_folder [pwd] - -# just a dummy proc -proc none {args} {} - -def Client new_file {} { - global untitled_number untitled_folder - netsend [list pd filename Untitled-$untitled_number $untitled_folder] - netsend [list #N canvas] - netsend [list #X pop 1] - incr untitled_number -} - - -set patch_filetypes { - {"pd files" ".pd"} - {"max files" ".pat"} - {"all files" "*"} -} - -set image_filetypes { - {"image files" ".gif .png"} - {"gif files" ".gif"} - {"png files" ".png"} - {"all files" "*"} -} - -catch {tk_getOpenFile -load-once} ;#only works with tcltk 8.5 -catch { - set ::tk::dialog::file::showHiddenBtn 1 - set ::tk::dialog::file::showHiddenVar 0 -} - -def Client open_file {} { - global pd_opendir patch_filetypes - set filename [tk_getOpenFile -parent $::current_window -defaultextension .pd -filetypes $patch_filetypes -initialdir $pd_opendir] - if {$filename != ""} {$self open_file_really $filename} -} - -def Client open_file_really {filename} { - set i [string last / $filename] - set folder [string range $filename 0 [expr $i-1]] - set ::pd_opendir $folder - set basename [string range $filename [expr $i+1] end] - if {[string last .pd $filename] >= 0} { - netsend [list pd open $basename $folder] - } -} - -def Client send_message {} { - toplevel .sendpanel - set e .sendpanel.entry - pack [entry $e -textvariable send_textvar] -side bottom -fill both -ipadx 100 - $e select from 0 - $e select adjust end - bind $e <KeyPress-Return> {netsend $send_textvar; after 50 {destroy .sendpanel}} - focus $e -} - -def Client quit {} { - set answer [tk_messageBox2 -message "Do you really wish to quit?" -type yesno -icon question] - switch -- $answer {yes {netsend [list pd quit]; exit}} -} - -def Client abort_server {} { - set answer [tk_messageBox2 -message "Do you really wish to abort?" -type yesno -icon question] - switch -- $answer {yes {exec kill -ABRT $::server_pid}} -} - -def Client server_prefs {} {ServerPrefsDialogue new_as pdrc} -def Client client_prefs {} {ClientPrefsDialogue new_as ddrc} - -proc menu_pop_pd {} {raise .} - -def Menuable populate_menu {menu list} { - global key - if {[string index $menu 0] != "."} {set menu $@menubar.$menu} - foreach name $list { - if {$name == ""} {$menu add separator; continue} - set k "" - if {[info exists key($@_class:$name)]} { - if {[string length $key($@_class:$name)]} {set k $key($@_class:$name)} - } - $menu add command -label [say $name] -command "$self $name" -accelerator [accel_munge $k] - } -} - -def Client init_menus {} { - #removed paths after send_message - $self populate_menu file { - new_file open_file {} - server_prefs client_prefs send_message {} - audio_on audio_off {} - abort_server quit} - $self populate_menu help { - about documentation class_browser do_what_i_mean {} - test_audio_and_midi load_meter latency_meter {} - clipboard_view command_history_view event_history_view keyboard_view client_class_tree} -} - -def Client init {} { - super - set @menubar .mbar - $self init_controls - $self init_binds - $self init_menus - # it's necessary to raise the window on OSX - switch $::OS { osx {raise .; wm iconify .; after 100 {wm deiconify .}}} - after 0 { - Listener new .tcl [say "tcl_console"] tcl_eval - Listener new .pd [say "pd_console"] pd_eval - } - #wm geometry .[$self keyboard_view] -0+0 - #wm geometry .[$self event_history_view] -0-0 -} - -proc post {args} { - set s "[eval [linsert $args 0 format]]\n" - # set s "[info level -1]: $s" - if {$::cmdline(console)} {$::console post_string $s} else {puts stderr $s} -} -proc pdtk_post {s} { - if {$::cmdline(console)} {$::console post_string $s} else {puts stderr $s} -} - -def Menuable eval% {code} { - regsub -all %W $code $self code - uplevel [info level] $code -} - -def Menuable getkey {k} { - global accels - if {[dict exists $accels $k]} { - set vars [dict get $accels $k] - foreach var $vars { - #mset {class key} [split [dict get $accels $k] ":"] - mset {class key} [split $var ":"] - #if {$class != $@_class} {return ""} else {return $key} - if {$class == $@_class} {return $key} - } - } -} - -def Menuable ctrlkey {x y key iso shift} { - set key [if {$shift} {string toupper $key} {string tolower $key}] - set key "Ctrl+$key" - set cmd [$self getkey $key] - if {![string length $cmd]} { - switch [$self class]:$key { - #explicitly listed here to do nothing - Client:Ctrl+c {} - Client:Ctrl+v {} - default {post "unknown key $key"} - } - } else {$self eval% "%W $cmd"} -} - -def Menuable altkey {x y key iso shift} { - set key [if {$shift} {string toupper $key} {string tolower $key}] - set key "Alt+$key" - set cmd [$self getkey $key] - if {[string length $cmd]} {$self eval% "%W $cmd"} else {post "unknown key $key"} -} - -#-----------------------------------------------------------------------------------# -set pd_apilist "{ALSA 1}" -set pd_apilist2 "default" - -#-----------------------------------------------------------------------------------# -#fixme: actually, is it ok that View<Menuable ? --matju -class_new View {Menuable Observable Thing} - -# normally ninlets/noutlets should be in class "Box", but server-side isn't smart enough -def View pdclass= {v} {set @pdclass $v} -def View pdclass {} {return $@pdclass} -def View ninlets= {v} {set @ninlets $v} -def View ninlets {} {return $@ninlets} -def View noutlets= {v} {set @noutlets $v} -def View noutlets {} {return $@noutlets} -def View click {x y f target} {} -def View unclick {x y f target} {} -def View motion {x y f target} {} - -def View subpatch {} {if {[info exists @subpatch]} {return 1} else {return 0}} - -def View look_cache {k} { - global look look_cache - foreach super [$@_class ancestors] { - if {[info exists look($super:$k)]} { - set look_cache($@_class:$k) $super - return $super - } - } -} -def View look {k} { - if {![info exists ::look_cache($@_class:$k)]} {$self look_cache $k} - return $::look($::look_cache($@_class:$k):$k) -} - -def View init {} { - super - set @selected? 0 - set @index 0xDEADBEEF - set @ninlets 1 ;# should be in Box init - set @noutlets 0 ;# should be in Box init - set @canvas "" -# set @inside_box 42 ;# temporary fix - set @ioselect {} -} - -def View classtags {} {return {foo}} - -set item { - set canvas [$self get_canvas] - if {$canvas == ""} {return} - set c [$self cwidget] - set zoom [$canvas zoom] - set coords [lmap * $coords $zoom] - set find [lsearch $args "-width"] - if {$find >= 0} { - incr find - set w [lindex $args $find] - lset args $find [format %.0f [expr {$w*$zoom}]] - } - set find [lsearch $args "-font"] - if {$find >= 0} { - incr find - set fs [lindex [lindex $args $find] 1] - lset args $find 1 [format %.0f [expr {$fs*$zoom}]] - } - #set find [lsearch $args "-fill"] - #if {$find >= 0} { - # incr find - # set fill [lindex $args $find] - # lset args $find [randomise_color $fill] - #} - set tags {} - foreach s $suffixes {lappend tags "$self$s"} - set ss [lindex $tags 0] - lappend tags $self - set tags [concat $tags [$self classtags]] -} -append item [correct_splat { - if {![llength [$c gettags $ss]]} { - $c create $type $coords -tags $tags {*}$args - } { - $c itemconfigure $ss {*}$args - $c coords $ss {*}$coords - } -}] -def View item {suffixes type coords args} $item - -def View item_delete {{suffix all}} { - if {$@canvas == ""} {return} - set c [$@canvas widget] - if {![winfo exists $c]} { - set canvas [$@canvas get_canvas] - if {$canvas == ""} {return} - set c [[$@canvas get_canvas] widget] - if {![winfo exists $c]} {return} - } - switch -- $suffix { - all {$c delete $self} - default {$c delete $self$suffix}} -} - -def View draw {} {} - -def View delete {} {$self erase; super} -def View erase {} {$self item_delete} -def View selected? {} {return $@selected?} -def View selected?= {x} {set @selected? $x; $self changed} ;# this is for use by the Selection class only -def View edit? {} {if {[info exists @edit]} {return $@edit} else {return 0}} -def View select {state} { - set ostate [$self selected?] - set @selected? $state - if {$state!=$ostate} {$self changed} -} - -# give topleft point of an object in the canvas it's rendered in. -# this includes GOP and excludes zoom. -# inheritance problem: this doesn't work for Wire, which doesn't store its positions -def View xy {} { - if {$@canvas == ""} {return [list $@x1 $@y1]} - set type [$@canvas type] - if {$type == "gopabs" || $type == "gopsub"} { - mset {xmargin ymargin} [$@canvas margin] - mset {x y} [$@canvas xy] - set x1 [expr {($@x1-$xmargin)+$x}] - set y1 [expr {($@y1-$ymargin)+$y}] - #if $self's gop is opened - if {[regexp {^.x[0-9a-f]{6,8}.c} [focus] f]} { - if {$f == ".$@canvas.c"} {set x1 $@x1; set y1 $@y1} - } - #if {[focus] != "." && [focus] == ".$@canvas.c"} {set x1 $@x1; set y1 $@y1} - return [list $x1 $y1] - } - return [list $@x1 $@y1] -} - -def View canvas {} {return $@canvas} -def View canvas= {c} { - set @canvas $c - # should "subscribe" call "changed"? (or pretend to?) - $self subscribe $c - $self changed - $self outside_of_the_box -} - -def View visible {} {if {[info exists @inside_box]} {return $@inside_box} {return -1}} - -# this returns the canvas actually exists/drawn -# see also def Canvas get_canvas -def View get_canvas {} { - set canvas $@canvas - if {$canvas == ""} {return ""} - #while {![$canvas havewindow]} {set canvas [$canvas canvas]} - while {![winfo exists [$canvas widget]]} {set canvas [$canvas canvas]} - return $canvas -} -# this will return the top level gop if gop is nested -def View get_parent_gop {canvas} { - set obj $self - while {$canvas != [$obj canvas]} {set obj [$obj canvas]} - return $obj -} - -def View outside_of_the_box {} { - if {$@canvas eq ""} {return} - # always hide these things - if {[$self class] == "Wire"} {set @inside_box 0; return} - if {[$self class] == "ObjectBox"} {set @inside_box 0; return} - if {[$self class] == "MessageBox"} {set @inside_box 0; return} - if {[$self class] == "Comment"} {set @inside_box 0; return} - if {[$self class] == "Array"} {$@canvas visibles+= $self; set @inside_box 1; return} - set x1 $@x1; set y1 $@y1 - if {[$@canvas gop]} { - set mess [$@canvas get_mess] - set pixwidth [lindex $mess 4] - set pixheight [lindex $mess 5] - if {[llength $mess] == 6} { - set xmargin 0; set ymargin 0 - } else { - set xmargin [lindex $mess 6]; set ymargin [lindex $mess 7] - } - if {$x1 < $pixwidth +$xmargin && $x1 > $xmargin && \ - $y1 < $pixheight+$ymargin && $y1 > $ymargin} { - set @inside_box 1 - $@canvas visibles+= $self - } else { - set @inside_box 0 - $@canvas visibles-= $self - } - } else {set @inside_box 1} -} - -def View draw_maybe {} { - if {$@canvas == "" && [winfo exists .$self.c]} {$self draw; return} - if {[$self class] == "Canvas" && $@canvas == ""} {return} - if {$@inside_box} { - #if {[$@canvas mapped] && ![$@canvas abs] && [$self gop_check]} {$self draw} - if {[$@canvas mapped] && [$self gop_check]} {$self draw} - } else { - # for drawing opened gop - if {[winfo exists .$@canvas.c]} {$self draw} - } -} -#this checks if $self can be seen, ie nested gop. -def View gop_check {} { - set canvases $@canvas - while {[lindex $canvases end] != ""} {lappend canvases [[lindex $canvases end] canvas]} - set canvases [lreplace $canvases end-1 end]; # all canvases - foreach canvas $canvases { - # if a canvas is not a gop and its window does not exists - if {![$canvas gop] && ![winfo exists [$canvas widget]]} {return 0; break} - } - return 1 -} - -#-----------------------------------------------------------------------------------# - -class_new Canvas {Menuable ObjectBox} - -def Canvas close {} { - after cancel $@motion_after_id - if {$@subpatch} { - #can't wait till @mapped get updated thru proc change - if {$@gop} {foreach x [$@objects values] {$x outside_of_the_box}} - $self save_geometry - $self copy_times= 0 - netsend [list .$self vis 0] - #netsend [list .$self close] - return - } - if {$@gop} { - foreach x [$@objects values] {$x outside_of_the_box} - netsend [list .$self close] - return - } - switch [tk_messageBox2 -message [say save_changes?] -icon question -type yesnocancel -default cancel] { - yes {$self save; netsend [list .$self close]} - no { netsend [list .$self close]} - cancel {} - } -} - -def Canvas save_geometry {} { - set geometry [wm geometry .$self] - set cw [winfo width [$self widget]]; set ch [winfo height [$self widget]] - foreach {size x y} [split $geometry "+"] {mset {w h} [split $size "x"]; set x1 $x; set y1 $y} - set x2 [expr $x1+$cw]; set y2 [expr $y1+$ch] - netsend [list .$self bounds $x1 $y1 $x2 $y2] -} - -def Canvas save {} { - if {$@subpatch} {return [$@canvas save]} - $self checkgeometry - set c [$self widget] - if {![regexp {^Untitled-[0-9]} $@name]} { - $self save_geometry - netsend [list .$self savetofile $@name $@folder] - } else { - $self save_as - } -} - -def Canvas save_as {} { - $self checkgeometry - set filename [tk_getSaveFile -parent $::current_window -filetypes $::patch_filetypes] - if {$filename != ""} { - set @file [string range $filename [expr [string last / $filename]+1] end] - set @folder [string range $filename 0 [expr [string last / $filename]-1]] - $self save_geometry - puts "save $@file dir to $@folder" - netsend [list .$self savetofile $@file $@folder] - } -} - -def Canvas print {} { - set filename [tk_getSaveFile -parent $::current_window -initialfile pd.ps -defaultextension .ps -filetypes { {{postscript} {.ps}} }] - if {$filename != ""} {[$self widget] postscript -file $filename} -} -def Canvas quit {} {$::main quit} -def Canvas abort_server {} {$::main abort_server} - -proc wonder {} {tk_messageBox2 -message [say ask_cool] -type yesno -icon question} - -def Canvas eval% {code} { - mset {x y} $@curpos - regsub -all %X $code $x code - regsub -all %Y $code $y code - super $code -} - -def Client documentation {} { - set filename [tk_getOpenFile -parent $::current_window -defaultextension .pd -filetypes { {{documentation} {.pd .txt .htm}} } -initialdir $::docdir] - if {$filename != ""} { - if {[string first .txt $filename] >= 0} { - menu_opentext $filename - } elseif {[string first .htm $filename] >= 0} { - menu_openhtml $filename - } else { - set i [string last / $filename] - set help_directory [string range $filename 0 [expr $i-1]] - set basename [string range $filename [expr $i+1] end] - netsend [list pd open [enquote $basename] [enquote $help_directory]] - } - } -} - -def Canvas new_file {} {$::main new_file} -def Canvas open_file {} {$::main open_file} -def Canvas send_message {} {$::main send_message} -def Client test_audio_and_midi {} {menu_doc_open doc/7.stuff/tools testtone.pd } -def Client load_meter {} {menu_doc_open doc/7.stuff/tools load-meter.pd} -def Client latency_meter {} {menu_doc_open doc/7.stuff/tools latency.pd } -def Client about {} {AboutDialogue new} -def Client class_browser {} {Browser new_as browser browser 0 0 ""} -def Client audio_on {} {netsend [list pd dsp 1]} -def Client audio_off {} {netsend [list pd dsp 0]} -def Client keyboard_view {} { KeyboardDialogue new $::event_history} -def Client clipboard_view {} { ClipboardDialogue new $::clipboard} -def Client command_history_view {} { ListDialogue new $::command_history [say command_history_view]} -def Client event_history_view {} {EventHistoryDialogue new $::event_history} -def Client do_what_i_mean {} {wonder} - -set pd_prefix [file dirname [file dirname [which pd]]] -set pd_guidir ${pd_prefix}/lib/pd -set doc_number 1 -set updir [file dirname [file dirname $argh0]] -if {[file exists $updir/lib/pd/doc]} { - set docdir $updir/lib/pd/doc -} else { - set docdir $updir/doc -} - -proc menu_opentext {filename} { - set w [format ".help%d" $::doc_number] - toplevel $w - wm title $w $filename - frame $w.1 - frame $w.2 - pack [text $w.1.text -relief raised -bd 2 -yscrollcommand "$w.1.scroll set"] -side left -fill both -expand 1 - pack [scrollbar $w.1.scroll -command "$w.1.text yview"] -side right -fill y - pack [button $w.2.close -text [say close] -command "destroy $w"] -side right - pack $w.2 -side bottom -fill x -expand 0 - pack $w.1 -side bottom -fill both -expand 1 - set f [open $filename] - while {![eof $f]} { - set bigstring [read $f 1000] - regsub -all PD_BASEDIR $bigstring $::pd_guidir bigstring - regsub -all PD_VERSION $bigstring $::pd_version bigstring - $w.1.text insert end $bigstring - } - $w.1.text configure -state disabled - close $f - incr ::doc_number - return $w -} - -proc menu_doc_open {subdir basename} { - set dirname $::pd_guidir/$subdir - if {[string first .txt $basename] >= 0} { - return [menu_opentext $dirname/$basename] - } else { - netsend [list pd open $basename $dirname] - } -} - -#-----------------------------------------------------------------------------------# -def Canvas editmode {} {return $@editmode} -def Canvas editmode= {mode} { - if {$mode == $@editmode} {return} - if {!$mode} {$self deselect_all} - $self redraw ;# why this??? - set @editmode $mode; $self changed editmode -# catch {.$self.bbar.edit configure -image icon_mode_$mode} - if {$@mapped} { - if {$mode} {set im icon_mode_edit} else {set im icon_mode_run} - [$self window].bbar.edit configure -image $im - if {[$self look hairstate] && !$@editmode} {$@crosshair erase} - if {[$self look gridstate]} { - if {$@editmode} {$@grid draw} else {$@grid erase} - } - } - # comment's look depends on the value of @editmode - foreach child [$@objects values] {if {[[$child class] <= Comment]} {$child changed}} - #!@#$ should update the checkbox in the editmenu -} - -def Canvas editmodeswitch {} {$self editmode= [expr !$@editmode]} - -def Canvas window {} { - #if {$@gop && $@canvas != ""} {return [$@canvas window]} - return .$self -} -def Canvas widget {} {return .$self.c} -def View cwidget {} {return .[$self get_canvas].c} - -#-----------------------------------------------------------------------------------# - -def Canvas atomically {proc} {$@history atomically $proc} -def Canvas undo {} {$@history undo} -def Canvas redo {} {$@history redo} - -def Canvas init {mess} { - set @mapped 0 - set @gop 0 - set @goprect "" - set @abs 0 - set @name "" - set @folder "???" - set @file "" - super {#X obj 666 666 pd} ;# bogus - $self reinit $mess - set @zoom 1.0 ;# must be a float, not int - set @action none - set @objects [Hash new]; set @objectsel [Selection new]; set @visibles {} - set @wires [Hash new]; set @wiresel [Selection new] - - set @focus "" - set @curpos {30 30} - set @bbox {0 0 100 100} - set @dehighlight {} -# if {$@mapped} {$self init_window} ;#!@#$ @mapped can't possibly be 1 at this point - set @history $::command_history - $self subscribe $::manager - $self changed - #$self canvas= $self ;#!@#$ EEVIL - set @coords 0 - set @jump 0 - set @keynav_iocount 0 ;# the io select count - set @keynav_port 0 ;# which in/outlet is selected - set @keynav 0 ;# the list of objects that has io selected - set @keynav_iosel 0 ;# last object that is io selected - set @keynav_iosel_o {} ;# list of objects that has outlet selected - set @keynav_iosel_i {} ;# list of objects that has inlet selected - set @iosel_deselect 0 ;# if selected should be deselected by clicking at empty space - set @keynav_current 0 - set @keynav_last_obj 0 - set @keynav_last_wire 0 - set @keynav_tab_sel "wire" - set @keynav_shift 0 - set @copy_count 0 - set @findbar "" - set @find_string "" - set @iohilite {-1 0 0 0 0} - set @keyprefix 0 - set @coords {0 0 1 1} ;# default #X coords line - set @pixsize {0 0} - set @margin {0 0} - set @macro_q {} - set @macro_delay 200 - set @blinky "" - set @editmode 0 - set @show_id 0 - set @motion_queue {} -} - -def Canvas reinit {mess} { - switch -- [lindex $mess 0] { - "#N" { - # those four are not to be confused with other @variables of similar names. - set @canvas_pos [lrange $mess 2 3] - set @canvas_size [lrange $mess 4 5] - set args [lrange $mess 6 end] - switch [llength $args] { - 1 { - set @subpatch 0 - mset [list @fontsize] $args - set @name "" - set @mapped 1 - } - 2 { - set @subpatch 1 - mset [list @name @mapped] $args - set @fontsize "what?" - } - default {error "wrong number of arguments (expecting 5 or 6, got [expr 4+[llength $args]])"} - } - } - "#X" { - switch -- [lindex $mess 1] { - obj {} - restore { - set @x1 [lindex $mess 2] - set @y1 [lindex $mess 3] - set args [lrange $mess 4 end] - $self text= [lrange $mess 4 end] - if {!$@subpatch && [llength $args] != 0} {set @abs 1} - if {$@mapped && !$@gop} { - #if {!$@subpatch && $@text != ""} {set @abs 1; return} - #if {![winfo exists .$self.c]} {$self init_window} - } - } - coords { - set @coords [lrange $mess 2 5] - set @pixsize [lrange $mess 6 7] - switch [llength $mess] { - 8 {set @gop 0} - 9 {set @gop [lindex $mess 8]} - 11 { - set @gop [lindex $mess 8] - set @margin [lrange $mess 9 10] - } - default {error "what???"} - } - if {$@gop} {set @mapped 1} - } - } - } - "" {return} - default {error "huh? mess=$mess"} - } -} - -# doesn't this look like Canvas deconstruct ? -def Canvas get_mess {} { - return [concat $@coords $@pixsize $@margin] -} - - -def Canvas margin {} {return $@margin} -def Canvas gop {} {return $@gop} -def Canvas hidtext {} {return $@hidetext} -def Canvas abs {} {return $@abs} -#def Canvas abs {} {if {!$@subpatch} {return 1} else {return 0}} -def Canvas subpatch {} {return $@subpatch} -def Canvas get_dimen {} {return $@canvas_size} - -def Canvas gop_rect {} { - mset {pxs pys} $@pixsize - mset {mx my} $@margin - set rect [list $mx $my [expr $mx+$pxs] [expr $my+$pys]] - if {$@goprect == ""} { - set @goprect [GopRect new $self $rect] - } elseif {!$@editmode} {$@goprect delete; set @goprect ""; return} - $@goprect draw - -} - -rename toplevel toplevel_orig -proc toplevel {name args} { - eval [concat [list toplevel_orig $name] $args] - catch {wm iconphoto $name icon_pd_32} -} - -# should be called once and only from init -def Canvas init_window {} { - lappend ::window_list $self - set win .$self - set c [$self widget] - if {$::tcl_platform(platform) == "macintosh"} { - toplevel $win -menu $win.m - } else { - if {[$self look menubar]} {toplevel $win -menu $win.m} else {toplevel $win -menu ""} - } - set @menubar $win.m - $self init_menus - # turn buttonbar on/off - set @buttonbar [ButtonBar new $self] - if {[$self look buttonbar]} {pack [$@buttonbar widget] -side top -fill x -expand no} - set @statusbar [StatusBar new $self] - # turn statusbar on/off - if {[$self look statusbar]} {pack [$@statusbar widget] -side bottom -fill x} - set w [expr [lindex $@canvas_size 0]-4];# dd canvas is 4 pixel out with pd canvas? - set h [expr [lindex $@canvas_size 1]-4] - pack [canvas $c -width $w -height $h -background white] -side left -expand 1 -fill both - set @yscroll $win.yscroll; set @xscroll $win.xscroll - $self init_scrollbars - wm minsize $win 1 1 - wm geometry $win +[lindex $@canvas_pos 0]+[lindex $@canvas_pos 1] - wm protocol $win WM_DELETE_WINDOW "$self close" - focus $c - $self new_binds - $self update_title - $self motion_update - set @runcommand [Runcommand new .$self "command" canvas_eval] - set @crosshair [Crosshair new $self] - set @active [Active new $self] - set @sense [Sense new $self] - set @grid [Grid new $self] -} - -def Canvas activate_menubar= {val} {if {$val} {.$self configure -menu $@menubar} {.$self configure -menu ""}} - -def Canvas activate_buttonbar= {val} { - if {$val} { - pack [$@buttonbar widget] -side top -fill x -expand no -before [$self widget] - } else {pack forget [$@buttonbar widget]} -} - -def Canvas activate_statusbar= {val} { - if {$val} { - if {[winfo exists $@yscroll]} {set w .$self.yscroll} else {set w .$self.c} - pack [$@statusbar widget] -side bottom -fill x -before $w - } else {pack forget [$@statusbar widget]} -} - -def Canvas activate_scrollbars= {val} {if {!$val} {$self init_scrollbars} {$self remove_scrollbars}} - -def Canvas activate_grid= {val} {if {$val} {$@grid draw} {$@grid erase}} - -def Canvas init_scrollbars {} { - set win .$self - set c [$self widget] - if {[winfo exists $win.yscroll]} {return} - set size [$c bbox foo] - mset {xs ys} $@canvas_size - pack [scrollbar $win.yscroll -command "$c yview" ] -side right -fill y -before $c - pack [scrollbar $win.xscroll -command "$c xview" -orient horizontal] -side bottom -fill x -before $c - set xw $win.xscroll; set yw $win.yscroll - $c configure -yscrollcommand "$self scroll_set $yw" -xscrollcommand "$self scroll_set $xw" - after 0 [list $self adjust_scrollbars] -} - -def Canvas remove_scrollbars {} { - set win .$self - set c [$self widget] - if {![winfo exists $win.yscroll]} {return} - #use destroy instead of pack forget so that it can be tested with winfo exists - destroy $win.yscroll - destroy $win.xscroll - $c configure -yscrollcommand "" -xscrollcommand "" -scrollregion "" -} - -def Canvas adjust_scrollbars {} { - set c [$self widget] - set size [$c bbox foo] - if {[$self look scrollbar]} {$self auto_scrollbars} - if {$size != ""} { - mset {xmin ymin xmax ymax} {0 0 100 100} - mset {x1 y1 x2 y2} $size - if {$x2 > 100} {set xmax $x2} - if {$y2 > 100} {set ymax $y2} - set bbox [list $xmin $ymin $xmax $ymax] - set oldbbox [$c cget -scrollregion] - # it is very inefficient to call "configure" here - if {"$oldbbox" != "$bbox"} {$c configure -scrollregion $bbox} - set @bbox $bbox - } -} - -def Canvas auto_scrollbars {} { - set c [$self widget] - if {[$c bbox foo] != ""} { - mset {cx1 cy1 cx2 cy2} [$c bbox foo] - } else { - set cx2 [lindex $@canvas_size 0]; set cy2 [lindex $@canvas_size 1] - } - set x2 [$c canvasx [winfo width $c]] - set y2 [$c canvasy [winfo height $c]] - if {$x2 == 1} {set x2 $cx2; set y2 $cy2} - if {$cx2 <= $x2 && $cy2 <= $y2} {$self remove_scrollbars} {$self init_scrollbars} -} - -def Canvas delete_window {} { - set wl {} - foreach w $::window_list {if {$w != $self} {lappend wl $w}} - set ::window_list $wl - destroy .$self -} - -def Canvas delete {} { - $self delete_window - super -} - -def Canvas focus {} {return $@focus} -def Canvas focus= {o} {set @focus $o} -def Canvas history {} {return $@history} - -#-----------------------------------------------------------------------------------# -def Canvas find {} { - if {[info exists ::_(findmodel:_class)]} { - focus .$self.find.find - findmodel reinit - } else { - FindModel new_as findmodel $self - FindView new $self - focus .$self.find.find - } -} -def Canvas find_again {} { - if {[info exists ::_(findmodel:_class)]} {findmodel remove_info;findmodel search_recursive} -} - -def Canvas find_last_error {} {netsend [list pd finderror]} - -def Canvas bind {eventtype selector args} { - set c [$self widget] - #bind $c $eventtype [concat [list $self $selector] $args \; $self statusbar_draw %x %y] - #bind $c $eventtype "puts \[time {[concat [list $self $selector] $args \; $self statusbar_draw %x %y]}\]" - #bind $c $eventtype "puts \[time {[concat [list $self $selector] $args]}\]" - if {[$self look statusbar]} { - bind $c $eventtype [concat [list $self $selector] $args \; $self statusbar_draw %x %y] - } else { - bind $c $eventtype [concat [list $self $selector] $args] - } -} - -def Canvas new_binds {} { - # mouse buttons - $self bind <Button> click_wrap %x %y %b 0 - $self bind <Shift-Button> click_wrap %x %y %b 1 - $self bind <Control-Button> click_wrap %x %y %b 2 - $self bind <Control-Shift-Button> click_wrap %x %y %b 3 - $self bind <Alt-Button> click_wrap %x %y %b 4 - $self bind <Alt-Shift-Button> click_wrap %x %y %b 5 - $self bind <Alt-Control-Button> click_wrap %x %y %b 6 - $self bind <Alt-Control-Shift-Button> click_wrap %x %y %b 7 - switch $::OS { - osx { - $self bind <Button-2> click_wrap %x %y %b 8 - $self bind <Control-Button> click_wrap %x %y 3 8 - } - default { - $self bind <Button-3> click_wrap %x %y %b 8 - } - } - switch $::OS { unix { - $self bind <Button-4> scroll y -1 - $self bind <Button-5> scroll y +1 - $self bind <Shift-Button-4> scroll x -1 - $self bind <Shift-Button-5> scroll x +1 - } default { - $self bind <MouseWheel> scroll y %D - $self bind <Shift-MouseWheel> scroll x %D - }} - $self bind <ButtonRelease> unclick_wrap %x %y %b 0 - $self bind <Shift-ButtonRelease> unclick_wrap %x %y %b 1 - - # keyboard - $self bind <Control-Key> ctrlkey %x %y %K %A 0 - $self bind <Control-Shift-Key> ctrlkey %x %y %K %A 1 - $self bind <Alt-Key> altkey %x %y %K %A 0 - $self bind <Alt-Shift-Key> altkey %x %y %K %A 1 - switch $::OS { - unix { - $self bind <Mod1-Key> altkey %x %y %K %A 0 - $self bind <Mod1-Shift-Key> altkey %x %y %K %A 1 - $self bind <Mod4-Key> altkey %x %y %K %A 0 - $self bind <Mod4-Shift-Key> altkey %x %y %K %A 1 - } - osx { - $self bind <Mod1-Key> ctrlkey %x %y %K %A 0 - $self bind <Mod1-Shift-Key> ctrlkey %x %y %K %A 1 - } - } - $self bind <Key> key_wrap %x %y %K %A 0 - $self bind <Shift-Key> key_wrap %x %y %K %A 1 - $self bind <KeyRelease> keyup_wrap %x %y %K %A 0 - $self bind <Shift-KeyRelease> keyup_wrap %x %y %K %A 1 - $self bind <Control-KeyRelease> keyup_wrap %x %y %K %A 0 - $self bind <Motion> motion_wrap %x %y 0 - $self bind <Alt-Motion> motion_wrap %x %y 4 - $self bind <Control-Motion> motion_wrap %x %y 9 - #$self bind <Map> map - #$self bind <Unmap> unmap - $self bind <Leave> leave - $self bind <Configure> configure %h %w -} - -def Canvas configure {h w} { - if {[$self look gridstate]} { - $@grid update $h $w - if {[winfo exists .$self.yscroll]} {return}; # scrollbar will update grid already - $@grid draw - } -} - -#def Canvas map {} {} -#def Canvas unmap {} {} -def Canvas leave {} {$@crosshair erase} - -def Canvas scroll {axis diff} { - set c [$self widget] - $c [list $axis]view scroll $diff units - if {[$self look hairstate] && $@editmode} { - # this should be changed so that we don't need to recompute x,y here. - set x [expr [$c canvasx [expr [winfo pointerx $c] - [winfo rootx $c]]]/$@zoom] - set y [expr [$c canvasy [expr [winfo pointery $c] - [winfo rooty $c]]]/$@zoom] - set target [$self identify_target $x $y 0] - $@crosshair data= $x $y $target - $@crosshair draw - } else { - $@crosshair erase - } -} - -# this allows the grid to update when scroll -def Canvas scroll_set {w v1 v2} {if {[$self look gridstate] && $@editmode} {$@grid draw}; $w set $v1 $v2} - -def Canvas reload {} {netsend [list .$self reupload]} -def Canvas redraw {} { - $self changed - foreach x [$@objects values] {$x changed} - foreach x [ $@wires values] {$x changed} -} - -#patch editing commandline shortcuts -def Canvas o {x y {name ""}} { - set c [$self widget] - if {[$self snap_grid]} {set off [expr [$self look grid_size]/2]} {set off 0} - set @curpos [list [expr [$c canvasx $x]+$off] [expr [$c canvasy $y]+$off]] - $self new_object obj $name -} - -def Canvas c {from outlet to inlet} { - set out_objs [$self parse_idx $from] - set in_objs [$self parse_idx $to] - foreach out $out_objs { - foreach in $in_objs { - $self connect [list $out $outlet $in $inlet] - } - } -} - -def Canvas pc {from outlet to inlet} { - set out_objs [$self parse_idx $from] - set in_objs [$self parse_idx $to] - if {[llength $out_objs] != [llength $in_objs]} {return "No can do :("} - for {set i 0} {$i < [llength $out_objs]} {incr i} { - $self connect [list [lindex $out_objs $i] $outlet [lindex $in_objs $i] $inlet] - } -} - -def Canvas s {selection} { - set objs [$self parse_idx $selection] - foreach obj $objs {$self selection+= [$@objects get $obj]} -} - -def Canvas s+ {selection} { - set objs [$self parse_idx $selection]; set ids {} - foreach obj $objs { - set v [$@objects get $obj]; lappend ids $v - $self selection+= $v - } - $self selection_wire= [$self implicit_wires $ids] -} - -def Canvas sw {from outlet to inlet} { - set out_objs [$self parse_idx $from] - set in_objs [$self parse_idx $to] - foreach out $out_objs { - foreach in $in_objs { - set id [$self wire_idx [list $out $outlet $in $inlet]] - if {$id>=0} {$self selection_wire+= [$@wires get $id]} - } - } -} - -def Canvas parse_idx {val} { - set objs {} - foreach obj [split $val ","] { - if {[regexp {\d+-\d+} $obj range]} { - set l [split $range "-"] - set objs [concat $objs [lmake [lindex $l 0] [lindex $l 1]]] - continue - } - lappend objs $obj - } - return $objs -} - -def Canvas xy_snap {x y} { - if {[$self look snap_grid]} { - set grid [$self look grid_size] - set x [expr floor($x/$grid)*$grid] - set y [expr floor($y/$grid)*$grid] - } - return [list $x $y] - -} - -def Canvas new_object {sel args} { - $self editmode= 1 - $self deselect_all - mset {x y} $@curpos - if {[$self look snap_grid]} { - set grid [$self look grid_size] - set x [expr floor($x/$grid)*$grid] - set y [expr floor($y/$grid)*$grid] - } - switch -- $sel { - obj { set goto [list $self new_object_edit]} - msg { set goto [list $self new_object_edit]} - text { set goto [list $self new_object_edit]} - default {set goto [list $self new_object_callback]} - } - netsend [concat [list .$self $sel $x $y] $args] $goto -} - -def Canvas new_wire_callback {wire} {} - -def Canvas new_object_callback {obj} { - $self add_to_obj_history $obj - set @keynav_last_obj $obj - $self selection+= $obj - if {$@keynav} {$self update_Active $obj} -} - -def Canvas new_object_copyselect {obj} { - $self selection+= $obj - #set @action "move" - #$self click_on_object $obj 0 -} - -def Canvas new_wire_select {wire} {$self selection_wire+= $wire} - -def Canvas new_object_edit {obj} { - if {[$obj class] == "NumBox"} {return} - $obj edit -} - -def Canvas add_to_obj_history {obj} { - if {![[$obj class] <= ObjectBox]} {return} - obj_hist prepend [$obj text] -} - - -def Canvas insertxy {} {return [list $@insert_x $@insert_y]} - -def Canvas insert_object {} {$self do_insert_obj "none" "none"} - -def Canvas get_canvas {} { - if {![info exists @gop]} { - if {[info exists @subpatch]} {if {$@subpatch} {return [$self canvas]}} - if {[info exists @abs]} {if {$@abs} {return [$self canvas]}} - if {[winfo exists .$self.c]} {return $self} - } - #if {[info exists @subpatch]} {if {$@subpatch} {return [$self canvas]}} - return [super] -} - -def Canvas get_topcanvas {} { - set canvas $@canvas - if {$@canvas == ""} {return $self} - while {[$canvas canvas] != ""} {set canvas [$canvas canvas]} - return $canvas -} - -def Canvas do_insert_obj {x y} { - if {$x == "none" && $y == "none"} { - if {[$@wiresel size] != 1} {return} - set wire [$@wiresel values] - puts "insert object for wire $wire" - mset {from outlet to inlet} [$wire report] - set c [$self widget] - set iowidth [$self look iowidth] - mset {ox1 oy1 ox2 oy2} [lmap / [$c bbox ${from}o${outlet}] [$self zoom]] - mset {ix1 iy1 ix2 iy2} [lmap / [$c bbox ${to}i${inlet} ] [$self zoom]] - set x1 [expr $ox1 + $iowidth/2]; set y1 [expr ($oy1+$oy2)/2] - set x2 [expr $ix1 + $iowidth/2]; set y2 [expr ($iy1+$iy2)/2] - set x [expr $x1 + ($x2-$x1)/2] - set y [expr $y1 + ($y2-$y1)/2] - } - netsend [list .$self obj $x $y] [list $self new_object_edit] - set @action insert -} - -def Canvas new_object_insert_wire {obj} { - set wire [$self selection_wire] - $self selection_wire-= $wire - mset {from outlet to inlet} [$wire report] - $self disconnect [$wire connects] - set @keynav 0; $@active hide; set @keynav_tab_sel "object" - set from_idx [$@objects search $from] - set to_idx [$@objects search $to] - set obj3_idx [$@objects search $obj] - $self connect [list $from_idx $outlet $obj3_idx 0] [list $self keynav_current=] - $self connect [list $obj3_idx 0 $to_idx $inlet] - $self action= none -} - -def Canvas chain_object {} { - if {[$@objectsel size] != 1} {return} - set o [$@objectsel values] - mset {x1 y1 x2 y2} [$o bbox] - set grid [$self look grid_size] - if {[$self look snap_grid]} {set y [expr floor(($y2+$grid)/$grid)*$grid]} {set y [expr $y2+10]} - netsend [list .$self obj $x1 $y] [list $self new_object_edit] - set @action chain_obj -} -def Canvas new_object_chain_wire {obj} { - obj_hist prepend [$obj text] - set from_idx [$@objects search [lindex [$self selection] 0]] - $self deselect_all - set to_idx [$@objects search $obj] - $self connect [list $from_idx 0 $to_idx 0] - $self action= none - $self selection= $obj -} - -def Canvas objects {} {return $@objects} -#def Canvas wires {} {return $@wires} -def Canvas selection {} {$@objectsel values} -def Canvas selection= {objs} {$@objectsel clear; $self selection+= $objs} -def Canvas selection+= {objs} {foreach obj $objs {$@objectsel set [$obj index] $obj}} -def Canvas selection-= {objs} {foreach obj $objs {set k [$obj index]; if {[$@objectsel exists $k]} {$@objectsel unset $k}}} -def Canvas selection_wire {} {$@wiresel values} -def Canvas selection_wire= {objs} {$@wiresel clear; $self selection_wire+= $objs} -def Canvas selection_wire+= {objs} {foreach obj $objs {$@wiresel set [$obj index] $obj}} -def Canvas selection_wire-= {objs} {foreach obj $objs {set k [$obj index]; if {[ $@wiresel exists $k]} { $@wiresel unset $k}}} - -def Canvas Object {} {$self new_object obj} -def Canvas Message {} {$self new_object msg} -def Canvas Number {} {$self new_object floatatom} -def Canvas Symbol {} {$self new_object symbolatom} -def Canvas Comment {} {$self new_object text} - -#!@#$ these 9 should be harmonised with the class list instead of having special names -def Canvas bng {} {$self new_object obj bng} -def Canvas tgl {} {$self new_object obj tgl} -def Canvas nbx {} {$self new_object obj nbx} -def Canvas vsl {} {$self new_object obj vsl} -def Canvas hsl {} {$self new_object obj hsl} -def Canvas vradio {} {$self new_object obj vradio} -def Canvas hradio {} {$self new_object obj hradio} -def Canvas vu {} {$self new_object obj vu} -def Canvas cnv {} {$self new_object obj cnv} - -def Canvas Graph {} {$self editmode= 1; netsend [list .x$self graph ]} -def Canvas Array {} {$self editmode= 1; netsend [list .x$self menuarray]} - -def Canvas init_menus {} { - set name .$self - set m $name.m - menu $m - #removed Paths after send_message - foreach x {file edit find view put window help} {menu $m.$x -tearoff $::pd_tearoff} - $self populate_menu file {new_file open_file {} send_message {} close save save_as print {} abort_server quit} - $self populate_menu edit {undo redo {} cut copy paste duplicate select_all subpatcherize {} tidy_up {}} - $self populate_menu find {find find_again find_last_error} - #!@#$ those shortcuts should be looked up in the key table!!! - $m.view add checkbutton -label [say visual_diff] -selectcolor grey0 -command [list $self visual_diff] \ - -accelerator [accel_munge "Ctrl+E"] -indicatoron 1 - $self populate_menu view {get_elapsed {} reload redraw} - $self populate_menu put {Object Message Number Symbol Comment {} bng tgl nbx vsl hsl vradio hradio vu cnv {} Graph Array} - $self populate_menu window {{}} - $m.edit add checkbutton -label [say edit_mode] -selectcolor grey0 -command [list $self editmodeswitch] \ - -accelerator [accel_munge "Ctrl+e"] -indicatoron 1 - $m.edit configure -postcommand "$self fix_edit_menu" - $m.window configure -postcommand "$self fix_window_menu" - foreach x {file edit view find put window help} { - if {$x=="help"} { - # help menu is in the wrong place in patch windows because it's taken from .mbar ??? - $m add cascade -label [say $x] -menu .mbar.$x - } { - $m add cascade -label [say $x] -menu $m.$x - } - } -} - -# corrects edit menu, enabling or disabling undo/redo -# LATER also cut/copy/paste -def Canvas fix_edit_menu {} { - set e .$self.m.edit - switch $::OS {osx {set i 0} default {set i 1}} - set t [say undo] - if {[$@history can_undo?]} { - $e entryconfigure $i -state normal -label "$t [$@history next_undo_name]" - } else { - $e entryconfigure $i -state disabled -label "[say cannot] $t" - } - incr i - set t [say redo] - if {[$@history can_redo?]} { - $e entryconfigure $i -state normal -label "$t [$@history next_redo_name]" - } else { - $e entryconfigure $i -state disabled -label "[say cannot] $t" - } -} - -def Menuable fix_window_menu {} { - set menu $@menubar.window - $menu delete 0 end - foreach w $::window_list {$menu add command -label [wm title [$w window]] -command "$w raise"} -# {"parentwindow" {menu_windowparent} ""} -} - -#-----------------------------------------------------------------------------------# -#this just tells whether an object is part of the selection, that is, what usually makes objects turn blue. -def Canvas selection_include? {member} {expr [$@objectsel search $member]>=0} - -def Canvas type {} { - if {$@subpatch && !$@gop} {return "sub"} - if {$@subpatch && $@gop} {return "gopsub"} - if {$@abs && !$@gop} {return "abs"} - if {$@abs && $@gop} {return "gopabs"} - if {!$@subpatch && !$@abs && !$@gop} {return "toplevel"} -} - -def Canvas draw {} { - if {$@gop} { - if {[$self gop_check]} {$self all_changed} - #if the focus is not in the opened gop - if {[regexp {^.x[0-9a-f]{6,8}.c} [focus] f]} { - if {$@canvas != ""&& $f != [$self widget]} {super;return} - } elseif {$@canvas != "" && [focus] != [$self widget]} {super;return} - } elseif {$@subpatch || $@abs} {super} - if {!$@mapped} {return} else {if {![winfo exists [$self widget]]} {return}} - $self check_findbar - if {$@editmode} {set bg [$self look bgedit]} else {set bg [$self look bgrun]} - [$self widget] configure -background $bg - $self adjust_scrollbars - if {$@gop} {$self gop_rect} -} - -def Canvas popup_properties {} {CanvasPropertiesDialogue new $self} - -def Canvas gop_target {id} { - while {[$id canvas] != $self} {set id [$id canvas]}; return $id -} - -#-----------------------------------------------------------------------------------# -class_new MacroRect {View} - -def MacroRect init {} {super; $self data= 0 0 0 0 blue} - -def MacroRect data= {x1 y1 x2 y2 col} { - set @x1 $x1; set @y1 $y1 - set @x2 $x2; set @y2 $y2 - set @col $col -} - -def MacroRect flash {x1 y1 x2 y2 col} { - $self data= $x1 $y1 $x2 $y2 $col - $self draw - after 500 $self erase -} - -def MacroRect draw {} { - set @canvas [string range [focus] 1 [string first . [focus] 1]-1] - $self item MACRO rect [list $@x1 $@y1 $@x2 $@y2] -outline $@col -} - -class_new Macro {EventHistory} -def Macro init {} { - $::event_history subscribe $self - set @idx 0 - set @state 0 - set @list {} - set @ref_list {} - set @delay 200 - set @offset_x 0 - set @offset_y 0 - set @rect [MacroRect new] -} -def Macro state= {val} { - set @state $val - if {$val} { - set @ref_list {} - set @list {} - post %s "start recording macro..." - } else { - post %s "end..." - } -} -def Macro state {} {return $@state} -def Macro dump {} {set i 0; foreach step $@list {post %s "step $i -> $step"; incr i}} -def Macro idx= {val} {set @idx $val} -def Macro idx {} {return $@idx} -def Macro delay {} {return $@delay} -def Macro append_ref {mess} {lappend @ref_list $mess} -def Macro ref_list {} {puts "$@ref_list";return $@ref_list} -def Canvas ref_list {} {$::macro ref_list} - - -def Macro notice {args} { - if {$@state} { - set mess [lindex $args 2] - switch [lindex $args 1] { - add {$self add $mess} - default {} - } - } -} - -def Macro add {mess} { - mset {event widget x y mode k kval} $mess - if {[regexp {^Control_} $k]} {return} - if {[regexp {^Alt_} $k]} {return} - if {[regexp {^Shift_} $k]} {return} - if {$event == "KeyRelease"} {return} - if {$event == "ButtonRelease"} {lappend @list [lreplace $mess 0 0 "Motion"]} - if {$event == "KeyPress" } {lappend @list [lreplace $mess 0 0 "Motion"]} - if {$event == "ButtonPress" } {lappend @list [lreplace $mess 0 0 "Motion"]} - lappend @list $mess -} - -def Macro test_playable {x y} { - mset {macro_width macro_height} [$self calc_size] - set c [string range [focus] 0 [string first . [focus] 1]+1] - set cwidth [winfo width $c]; set cheight [winfo height $c] - set cx1 [$c canvasx 0]; set cy1 [$c canvasy 0] - set cx2 [$c canvasx $cwidth]; set cy2 [$c canvasy $cheight] - set new_x [expr $x+$macro_width]; set new_y [expr $y+$macro_height] - $@rect flash $x $y $new_x $new_y blue - if {$new_x > $cx2 || $new_x < $cx1 || $new_y > $cy2 || $new_y < $cy1} { - puts "Can't playback Macro:: outside of canvas area" - return - } else {$self idx= 0; $self offset $x $y; $self play [$self delay]} - -} - -def Macro offset {new_x new_y} { - mset {event widget x y mode k kval} [lindex $@list 0] - set @offset_x [expr $new_x-$x] - set @offset_y [expr $new_y-$y] -} - -def Macro play {delay} { - if {$@idx == [llength $@list]} {return} - #$self test_canvas_size - set i 0 - set focus [string range [focus] 1 [string first . [focus] 2]-1] - set step [lindex $@list $@idx] - #puts "\t $step" - mset {event widget x y mode k kval} $step - switch $event { - #KeyRelease {set name [modekey $k $mode]} - KeyPress {set name [modekey $k $mode]} - ButtonPress {set name $event-$k} - ButtonRelease {set name $event-$k} - Motion {set name $event} - default {puts "Error: event $event should not have been here.."} - } - if {$@idx < [llength $@list]} { - #after $delay [list $self run $event $name $k [expr $X+$@offset_x] [expr $Y+$@offset_y] \ - # [expr $x+$@offset_x] [expr $y+$@offset_y]] - after $delay [list $self run $event $name $k $x $y] - } -} - -#this don't make sense when multiple window, and should be re implemeneted somehow -def Macro calc_size {} { - set x1 66666; set x2 0 - set y1 66666; set y2 0 - foreach step $@list { - mset {event widget x y mode k kval} $step - set x1 [min $X $x1]; set x2 [max $x2 $X] - set y1 [min $Y $y1]; set y2 [max $y2 $Y] - - } - return [list [expr $x2-$x1] [expr $y2-$y1]] -} - -def Macro test_canvas_size {} { - set c [string range [focus] 0 [string first . [focus] 1]+1] - set cwidth [winfo width $c]; set cheight [winfo height $c] - set cx1 [$c canvasx 0]; set cy1 [$c canvasy 0] - set cx2 [$c canvasx $cwidth]; set cy2 [$c canvasy $cheight] - mset {x1 y1 x2 y2} [$self calc_size] -} - -def Macro run {event name k x y} { - set w [focus] - incr @idx - event generate $w <$name> -x $x -y $y - if {$event=="KeyPress"} {event generate $w <KeyRelease-$k> -x $x -y $y} - $self play $@delay -} - -def Macro copy {} { - clipboard clear - selection clear - set i 0 - foreach step $@list { - if {$i == [expr [llength $@list]-1]} {set comma ""} else {set comma ","} - mset {event widget x y mode k kval} $step - set mess [list $event $x $y $mode $k] - set t ${mess}$comma - switch $event { - KeyPress {clipboard append [lreplace $t 0 0 "key"]} - ButtonPress {clipboard append [lreplace $t 0 0 "click"]} - ButtonRelease {clipboard append [lreplace $t 0 0 "unclick"]} - } - incr i - } - selection handle -selection PRIMARY [focus] "$self getdata" - selection own -command lost -selection PRIMARY -} - -def Macro getdata {offset maxchar} { - puts "clipboard ::: [clipboard get]" - return [string range [format %s [clipboard get]] $offset [expr {$offset+$maxChars}]] -} - -def Macro reset {} {set @idx 0} - -set ::macro [Macro new] -set ::macro_state 0 - -def Canvas macro_toggle {} {if {![$::macro state]} {set ::macro_state 1} {$::macro state= 0; $::macro dump}} -#def Canvas macro_play {} {puts ">> $@click_at <<"; $::macro idx= 0; $::macro play [$::macro delay]} -def Canvas macro_play {} { - mset {x y} $@click_at - $::macro reset - $::macro play [$::macro delay] - #$::macro test_playable $x $y -} -def Canvas keyevent {} { - focus [$self widget] - event generate [$self widget] <Control-Key-1> -} - -def Canvas macro_copy {} {$::macro copy} - -#-----------------------------------------------------------------------------------# -class_new TextBox {Box} - -def TextBox init {mess} { - super $mess - set @edit 0 - set @x1 [lindex $mess 2] - set @y1 [lindex $mess 3] - set @text [$self remove_braces [join [lrange $mess 4 end]]] - set @multi 0 - set @max_width 40 - # @textoffset is for offseting the text item/widget, ie, ObjectBox vs NumBox - switch [$self class] { - NumBox {set @textoffset [list 10 2]} - default {set @textoffset [list 2 2]} - } -} - -def TextBox text= {text} {set @text [$self remove_braces [join $text]]} -def TextBox text {} {return $@text} -def TextBox filter_text {{for_edit 0}} {return $@text} - -def TextBox draw {} { - if {[$self class] == "Canvas"} {if {$@text == "graph"} {$self update_size; super; return}} - # "TEXT" is the text label while "text" is the the input text field tk widget. - # the text should be drawn before, so that update_size works at the right time. - mset {x1 y1} [$self xy] - set z [$@canvas zoom] - if {$@edit} { - $self draw_edit - } else { - set fw [font measure [$self look font] 0] - set text [$self filter_text] - if {$::leet} {set text [string map -nocase {a 4 e 3 t 7 s 5 i 1 o 0 g 9} $text]} - $self item TEXT text [l+ $@textoffset [$self xy]] \ - -font [$self look font] -text $text \ - -fill [$self look fg] -anchor nw -width [expr ($fw*$@max_width)-1] - # set width with -1 because text item seem to be inclusive at wrap point - # where as the text widget is exclusive - } - $self update_size - super -} - -def TextBox edit {} { - if {$@edit} {return}; set @edit 1; $self changed edit - if {[[$self class] <= AtomBox]} {set @clear 1} -} - -def TextBox new_bind {} { - set t [$self cwidget].${self}text - bind $t <Key> "$self key_input %W %x %y %K %A 0" - bind $t <Control-Return> "$self key_input %W %x %y 10 %A 0" - bind $t <Control-v> "$self paste_resize" - bind $t <Return> "$self unedit" - bind $t <Escape> "$self unedit 0" - bind $t <Up> "$self scroll_history +1" - bind $t <Down> "$self scroll_history -1" - bind $t <Control-p> "$self scroll_history +1" - bind $t <Control-n> "$self scroll_history -1" - bind $t <Alt-BackSpace> "$self clear" -} - -def TextBox draw_edit {} { - set c [$self cwidget] - switch $::tcl_platform(os) { - Linux {$c configure -cursor crosshair} - #need to find equivalent names for other os - } - if {[lsearch [$@canvas selection] $self] < 0} {$@canvas selection+= $self} - set t $c.${self}text - if {[winfo exists $t]} {return} - set @edit 1 - set @tab_repeats 0 - obj_hist histi= 0 - set @selected? 1 - set z [$@canvas zoom] - set font_height [font metrics [$self look font] -linespace] - if {[$c bbox ${self}TEXT] != ""} { - mset {ix1 iy1 ix2 iy2} [lmap / [$c bbox ${self}TEXT] $z] - if {($iy2-$iy1)/$z > $font_height} {set @multi 1} - } else { - set ix1 0; set iy1 0 - set ix2 [font measure [$self look font] 0] - set iy2 [font metrics [$self look font] -linespace] - } - $c delete ${self}TEXT - set font_str [$self look font] - set new_size [format %.0f [expr [lindex $font_str 1]*$z]] - set font_str [lreplace $font_str 1 1 $new_size] - foreach char [split $@text ""] {lappend l [scan $char %c]} - mset {width height} [$self get_size [expr $ix2-$ix1] [expr $iy2-$iy1]] - set insertbg [$self look fg]; set fg [$self look fg] - if {[[$self class] <= AtomBox]} {set fg "red"; set insertbg [$self look bgedit]} - text $t -width $width -height $height -relief flat -bg [$self look bgedit] -borderwidth 0 \ - -highlightthickness 0 -font $font_str -fg $fg -insertbackground $insertbg -wrap word - $self new_bind - $@canvas focus= $self - $self item text window [l+ [lmap / $@textoffset $z] [$self xy]] -window $t -anchor nw -tags "${self}text $self text" - $t insert 1.0 $@text - $t configure -pady 0 -padx 0 - # dnd bindtarget $c.${self}text text/uri-list <Drop> {} - # tkdnd::drop_target register $c.${self}text - #set w .[$self get_canvas] - #tkdnd::drop_target register $w * - #bind $w <<Drop>> {post %s "Drop %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %b %D"} - #bind $w <<Drop:DND_Files>> {post %s "Drop:DND_Files %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %b %D"} - #bind $w <<DropEnter>> {post %s "DropEnter %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %b %D"} - #bind $w <<DropPosition>> {post %s "DropPosition %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %b %D"} - #bind $w <<DropLeave>> {post %s "DropLeave %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %b %D"} - - # "pd \"x[list ${self}] symbol \[ enquote %D \] ;\"" - $self resize - focus $t -} - -def TextBox resize {} { - if {[[$self class] <= AtomBox]} {return} - set c [$self cwidget] - set t $c.${self}text - #set z [$@canvas zoom] - set pix_height [$t count -update -ypixels 1.0 end] - set pix_width [font measure [$self look font] [$t get 1.0 end]] - mset {width height} [$self get_size $pix_width $pix_height] - $t configure -width [min $width $@max_width] -height $height -wrap word -} - -def TextBox get_size {w h} { - set c [$self cwidget] - set t $c.${self}text - set pix_height $h - set pix_width $w - set char_width [font measure [$self look font] 0] - set line_height [font metrics [$self look font] -linespace] - set round_chars [expr int(ceil($pix_width/$char_width.0))] - if {$round_chars < $@max_width && !$@multi} { - set round_lines 1 - } else { - set @multi 1 - set round_chars $@max_width - set round_lines [expr int(ceil($pix_height/$line_height))] - } - return [list $round_chars $round_lines] -} - -def TextBox key_input {widget x y key iso shift} { - after 0 "$self after_key $widget" - set c [$@canvas widget] - set t $c.${self}text - if {[[$self class] <= AtomBox]} {if {$@clear} {$t delete 1.0 1.end; set @clear 0}} - switch -- $key { - Tab { - if {[$self class] == "ObjectBox"} { - $self propose_completions; $widget configure -state disabled - } - } - 10 {$t configure -height [expr [lindex [$t configure -height] 4] + 1]} - } -} - -def TextBox after_key {widget} { - $widget configure -state normal; # for in case there is completion box - $self resize - $self changed -} - -def TextBox paste_resize {} { - if {[[$self class] <= AtomBox]} {return} - set c [$self cwidget] - set t $c.${self}text - set fixed [font metrics [$self look font] -fixed] - set text [clipboard get] - if {$fixed} { - set width [string length $text] - } else { - set textpix [font measure [$self look font] $text] - set fwidth [font measure [$self look font] 0] - set width [expr (($textpix+$fwidth-1)/$fwidth)+1] - } - set maxwidth 40 - mset {y1 y2} [$t yview] - if {$width < $maxwidth} {set height 1} {set height [expr ceil($width/$maxwidth.0)]} - $t configure -width [min $width $maxwidth] -height $height -wrap word - after 0 [list $t mark set insert 1.end] - $t mark set insert 1.0 - $self update_size - $self changed -} - -def TextBox scroll_history {incr} { - if {[[$self class] <= MessageBox]} {return} - set c [$self cwidget] - set t $c.${self}text - if {![obj_hist histi]} {obj_hist set_hist 0 [$t get 1.0 1.end]} - $t delete 1.0 1.end - set text [obj_hist traverse $incr] - $t insert 1.0 $text - $t configure -width [string length $text] - $self update_size - after 0 $self changed - -} - -def TextBox clear {} { - set c [$self cwidget] - set t $c.${self}text - $t delete 1.0 1.end -} - -def TextBox text {} {return $@text} - -def TextBox update_size {} { - if {[info exists @gop]} {if {$@gop} {mset [list @xs @ys] $@pixsize; return}} - if {$@canvas == ""} {puts "update_size: this textbox has no canvas, try again later"; return} - set c [$self cwidget] - set t_widget $c.${self}text - set t_item $c.${self}TEXT - set w2 0; set h2 0 - set xpad 2; set ypad 3 - set z [$@canvas zoom] - if {[winfo exists $t_widget]} { - set textwidth [expr ([winfo reqwidth $t_widget]+$xpad)/$z] - set height [expr ([winfo reqheight $t_widget]+$ypad)/$z] - } else { - mset {x1 y1 x2 y2} [[[$self canvas] widget] bbox ${self}TEXT] - set textwidth [expr ($x2-$x1+$xpad)/$z] - set height [expr ($y2-$y1+$ypad)/$z] - } - set iowidth [$self look iowidth] - set topwidth [expr {(2* $@ninlets-1)*$iowidth}] - set bottomwidth [expr {(2*$@noutlets-1)*$iowidth}] - set @xs [max [$self look minobjwidth] [max $bottomwidth [max $topwidth $textwidth]]] - set @ys $height -} - -#----------------------------------------------------------------------------------- - -class_new ObjectBox {TextBox} - -def ObjectBox init {mess} { - super $mess - set @valid 0 ;# only ObjectBox needs a @valid. (removed all others) - set @ninlets 0 - set @noutlets 0 - set @pdclass "" -} - -def ObjectBox valid= {v} {set @valid $v} -def ObjectBox valid {} {return $@valid} -def Canvas objectsel {} {return $@objectsel} -def Canvas wiresel {} {return $@wiresel} - -def ObjectBox draw_box {} { - super - set xya [$self bbox] - mset {x1 y1 x2 y2} $xya - # the 3d look could be done quicker using incr on x1 y1 x2 y2 like BlueBox does. - #set xyb [l+ [list $x2 $y1 $x1 $y1 $x1 $y2] [list -1 +1 +1 +1 +1 -1]] - #set xyc [l+ [list $x2 $y1 $x2 $y2 $x1 $y2] [list -1 +1 -1 -1 +1 -1]] - if {[$self selected?]} {set fg [$self look selectframe]} {set fg [$self look frame3]} - if {$@valid} { - $self item BASE rectangle $xya -fill [$self look bg] -outline $fg -width 1 - } else { - $self item BASE rectangle $xya -fill [$self look bg] -outline $fg -width 1 -dash {3 3} - } - #$self item BASE1 line $xyb -fill [$self look frame1] -width 1 - #$self item BASE2 line $xyc -fill [$self look frame2] -width 1 - #[$@canvas widget] lower ${self}BASE ${self}TEXT - [[$self get_canvas] widget] lower ${self}BASE ${self}TEXT - #[[$self get_canvas] widget] lower ${self}BASE -} - -def ObjectBox draw {} {super; $self draw_io} - -# this is called from the GUI; text= is reserved for server. -def TextBox setto {text} { - [$@canvas history] add [list $self setto $@text] - [$@canvas widget] configure -cursor {} - set @text $text - set l {} - foreach char [split $@text ""] {lappend l [scan $char %c]} - $@canvas selection-= [list $self] - switch [$@canvas action] { - insert {set goto [list $@canvas new_object_insert_wire]} - chain_obj {set goto [list $@canvas new_object_chain_wire]} - subpatcherize {set goto [list $@canvas new_object_subpatcherize_redraw]} - default {set goto [list $@canvas new_object_callback]} - } - netsend [concat [list .$@canvas text_setto $self] $l] $goto -} - -def TextBox unedit {{accept 1}} { - if {!$@edit} {return} - set @edit 0 - $self changed edit - set c [[$self get_canvas] widget] - set t $c.${self}text - if {$accept} {$self setto [$t get 1.0 "end - 1 chars"]} - after 1 "destroy $t" - if {[winfo exists .completion]} {$@action cancel} - focus $c - $@canvas focus= "" -} - -#-----------------------------------------------------------------------------------# -def Canvas name {} {return $@name} -def Canvas folder {} {return $@folder} -def Canvas name= {name} {if {!$@mapped} {return}; set @name $name ; $self update_title} -def Canvas folder= {folder} {if {!$@mapped} {return}; set @folder $folder; $self update_title} - -def Canvas make_title {} { - if {!$@mapped} {return} - if {$@subpatch} { - if {$@canvas == "" || 0==[string compare $@canvas $self]} { - set t "(uh)" - } else { - set t [$@canvas make_title] - } - set t "subpatch '$@name' of $t" - } else { - #set t "$@name in $@folder" - set t "$@name" - } - if {[$self modified?]} {append t "(*)"} - return $t -} - -def Canvas update_title {} { - if {[winfo exists .$self]} {wm title .$self [$self make_title]} -} - -# UNIMPLEMENTED: this should indicate whether the patch in pd is different from the last saved patch -def Canvas modified? {} {return 1} - -def Canvas mapped {} {return $@mapped} -def Canvas mapped= {v} {set @mapped $v} - -def Canvas havewindow= {flag} { - set was [winfo exists .$self] - if {$flag && !$was} {$self init_window; $self redraw} - #if {$flag && $was && [$self gop]} {$self redraw} - if {$flag && $was} {$self raise} - if {!$flag && $was} {$self delete_window} -} - -def Canvas visibles+= {child} { - if {[lsearch $@visibles $child] < 0} {lappend @visibles $child; $self changed visibles} -} -def Canvas visibles-= {child} { - if {[lsearch $@visibles $child] >= 0} {set @visibles [lwithout $@visibles $child]; $self changed visibles} -} - -def Canvas visibles {} {return $@visibles} - -def Canvas all_changed {} { - foreach x $@visibles { - if {[$x class] == "Canvas"} {if {$@gop} {$x all_changed}} - $x changed - } -} - -# this is a shim between the client's new-style indices and the server's remaining old-style indices -proc dex {h k} {lsearch [lsort -integer [$h keys]] $k} - -# for undo; calls the server -def Canvas ins {i constructor} { - set parts [pd_mess_split $constructor] - set last [lindex $parts end] - set parts [lrange $parts 0 end-1] - foreach part $parts {netsend $part} - netsend [concat [list .$self object_insert $i] $last] - $@history add [list $self del $i] -} - -def Canvas del {i} { - set o [$@objects get $i] - #this keynav should be better sorted out - if {$o == $@keynav_current || $o == $@keynav_last_obj} { - set @keynav_current 0 - set @keynav_last_obj 0 - } - # this "if" might not be necessary... try deconstruct_to for everything. - if {[$o class] != "Canvas"} { - $@history add [list $self ins $i [$o deconstruct]] - } else { - set meuh [Clipboard2 new] - $o deconstruct_to $meuh - $@history add [list $self ins $i [$meuh value]] - $meuh delete - } - netsend [list .$self object_delete $o] -} - -def Canvas wires {} {return $@wires} - -def Canvas delete_selection {} { - $@history atomically [list delete_selection] { - if {![$@objectsel size] && ![$@wiresel size]} {return} - #this keynav should be better sorted out - if {$@keynav} { - set @keynav 0 - switch [$@keynav_current class] { - Wire {set @keynav_last_wire 0} - default {set @keynav_last_obj 0} - } - set @keynav_current 0 - $@active hide - } - set del_wire {} - foreach obj [$@objectsel values] { - foreach wire [$obj wires2] { - if {[$@wires search $wire] != -1 && [lsearch $del_wire $wire] < 0} { - $self disconnect [$wire connects] - lappend del_wire $wire - } - } - $self del [$@objects search $obj] - } - foreach x [$@wiresel values] { - if {[$@wires search $x] != -1 && [lsearch $del_wire $x] < 0} { - $self disconnect [$x connects] - } - } - $@objectsel clear - $@wiresel clear - } -} - -def View position= {xy1} {mset [list @x1 @y1] $xy1; $self changed x1 y1} -def View set_orig_xy {x y} {set @orig_x $x; set @orig_y $y} - -def Canvas motion_wrap {x y f} { - set c [$self widget] - set x [expr [$c canvasx $x]/$@zoom] - set y [expr [$c canvasy $y]/$@zoom] - lappend @motion_queue [list $x $y $f] - #$self motion $x $y $f [$self identify_target $x $y $f] -} - -def Canvas motion_update {} { - if {[llength $@motion_queue]} { - mset {x y f} [lindex $@motion_queue end]; set @motion_queue {} - $self motion $x $y $f [$self identify_target $x $y $f] - } - set @motion_after_id [after 50 "$self motion_update"] -} - -def Canvas click_wrap {x y b f} { - set c [$self widget] - set x [expr [$c canvasx $x]/$@zoom] - set y [expr [$c canvasy $y]/$@zoom] - set f [expr 1<<($b+7)|$f] - $self click $x $y $f [$self identify_target $x $y $f] -} -def Canvas unclick_wrap {x y b f} { - set c [$self widget] - set x [expr [$c canvasx $x]/$@zoom] - set y [expr [$c canvasy $y]/$@zoom] - set f [expr 1<<($b+7)|$f] - $self unclick $x $y $f [$self identify_target $x $y $f] -} -def Canvas key_wrap {x y key iso shift} { - set c [$self widget] - $self key [expr [$c canvasx $x]/$@zoom] [expr [$c canvasy $y]/$@zoom] $key $iso $shift -} -def Canvas keyup_wrap {x y key iso shift} { - set c [$self widget] - $self keyup [expr [$c canvasx $x]/$@zoom] [expr [$c canvasy $y]/$@zoom] $key $iso $shift -} - -proc lsearch_minimum {l} { - set i 0 - set j 0 - set min [lindex $l 0] - foreach o $l { - if {$o < $min} {set i $j; set min $o} - incr j - } - return $i -} - -def Canvas quadrant {du dv array} { - if {$@keynav_current == 0} {set @keynav_current [$@objects get [lindex [$@objects keys] 0]]} - set foo {} - set bar {} - set pos [$@keynav_current xy] - foreach o $array { - mset {x y} [l- $pos [$o xy]] - set u [expr $x+$y] - set v [expr $x-$y] - if {$u*$du>0 && $v*$dv>0} {lappend foo $o; lappend bar [distance $pos [$o xy]]} - } - if {![llength $bar]} {return $@keynav_current} - set best [lindex $foo [lsearch_minimum $bar]] - return $best -} - -def Canvas motion {x y f target} { - #modes_callback $self "motion" $x $y $f $target - set c [$self widget] - $self motion_checkhairtip $target $x $y - eval $@dehighlight - set @dehighlight {} - set oldpos $@curpos - set @curpos [list $x $y] - # detects if the focus is not on the canvas itself in run mode, ie. numbox - if {!$@editmode & [$self focus] != $self & [$self focus] != ""} { - [$self focus] motion $x $y $f $target - } - mset {type id detail} $target - switch $@action { - edit {$self motion_edit $x $y $f} - insert {} - chain_obj {} - imove {$self motion_imove $oldpos $x $y; return} - mouse_copy {$self motion_move $oldpos $x $y; return} - move {$self motion_move $oldpos $x $y; return} - none {} - default {$@action motion $x $y $f $target} - } - if {$@editmode} {$self motion_iohilite2 $x $y $f} - if {$id == ""} {return} -} - -proc remainder {val val2} { - if {[expr {abs($val)}]} {return [expr {(abs($val)%$val2)*($val/abs($val))}]} else {return 0} -} - -def Canvas motion_move {oldpos x y} { - mset {ox oy} $oldpos - if {$@keynav} {$@active draw} - foreach obj [$@objectsel values] { - #if {[[$obj class] <= Box]} { - if {[$self look snap_grid]} { - set grid [$self look grid_size] - set ax [expr {(int($x)/$grid)*$grid}] - set ay [expr {(int($y)/$grid)*$grid}] - set oax [expr {(int($ox)/$grid)*$grid}] - set oay [expr {(int($oy)/$grid)*$grid}] - mset {x1 y1} [$obj xy] - if {![expr {($ax-$oax)%$grid}]} { - set xoff [remainder [expr {int($x1-$ax)}] $grid] - } else {set xoff 0} - if {![expr {($ay-$oay)%$grid}]} { - set yoff [remainder [expr {int($y1-$ay)}] $grid] - } else {set yoff 0} - $obj move [expr ($ax-$oax)-$xoff] [expr ($ay-$oay)-$yoff] - } else { - $obj move [expr {$x-$ox}] [expr {$y-$oy}] - } - #} else { - # puts "Canvas motion warning: trying to move non-Box explicitly" - #} - } -} - -def Canvas motion_imove {oldpos x y} { - mset {ox oy} $oldpos - if {$@keynav} {$@active draw} - if {[$@objectsel size] == 1} { - set obj [$@objectsel values] - set in_objs $obj - set out_objs $obj - } else { - if {![llength $@keynav_iosel_i] || ![llength $@keynav_iosel_o]} { - return - } else { - set obj [lindex $@keynav_iosel_i 0] - set in_objs $@keynav_iosel_i - set out_objs $@keynav_iosel_o - } - } - if {[[$obj class] <= Box]} { - if {[$obj class] == "Canvas"} { - if {[$obj gop]} {[$self widget] raise [list $obj [$obj visibles]]} - } else { - [$self widget] raise $obj - } - mset {type id detail} [$self identify_target $x $y 0] - if {$type == "wire"} { - mset {from outlet to inlet} [$id report] - $self disconnect [$id connects] - set from_idx [$@objects search $from] - set to_idx [$@objects search $to] - foreach obj $in_objs { - set obj3_idx [$@objects search $obj] - if {![llength [$obj ioselect]]} {set port 0} else {set port [lindex [$obj ioselect] 0]} - set w1 [list $from_idx $outlet $obj3_idx $port] - if {[$@wires search $w1]<0} {$self connect $w1} - } - foreach obj $out_objs { - set obj3_idx [$@objects search $obj] - if {![llength [$obj ioselect]]} {set port 0} else {set port [lindex [$obj ioselect] 0]} - set w2 [list $obj3_idx $port $to_idx $inlet] - if {[$@wires search $w2]<0} {$self connect $w2} - } - set @action move - } - foreach obj [$@objectsel values] {$obj move [expr $x-$ox] [expr $y-$oy]} - } else { - puts "Canvas motion warning: trying to move non-Box explicitly" - } -} - -def Canvas motion_edit {x y f} { - if {[distance [list $x $y] $@click_at] > 5} { - foreach obj [$@objectsel values] { - if {[[$obj class] <= Box]} { - $obj backupxy= [$obj xy] - } else { - puts "Canvas motion warning: trying to backup coordinates of non-Box" - } - } - if {$f == 9} {set @action imove} else {set @action move; $self motion_move $@click_at $x $y} - mset {ox oy} $@click_at - } -} - -def Canvas motion_checkhairtip {target x y} { - global tooltip - if {[$self look hairstate] && $@editmode} { - $@crosshair data= $x $y $target - $@crosshair draw - } else { - $@crosshair erase - } - if {[$self look tooltip]} { - if {$tooltip ne "" && ![$tooltip iserror] && [expr [distance [$tooltip curpos] [list $x $y]] > 10]} { - $tooltip delete - set tooltip "" - } - } -} - -def Canvas motion_iohilite2 {x y f} { - set c [$self widget] - set io [$self identify_closestio $x $y $f] - if {$io<0} {set @iohilite [list -1 0 0 0 0]; return} - foreach item {i o} { - set type_idx [string first $item $io] - set type [string index $io $type_idx] - set port [string range $io [expr $type_idx+1] end] - set object [string range $io 0 [expr $type_idx-1]] - if {$type_idx >= 0} {break} - } - mset {iox ioy} [lmap / [rect_centre [$c bbox $io]] $@zoom] - set @iohilite [list $object $iox $ioy $type $port] - $object hilite_io $type $iox $ioy - set @dehighlight [list $c delete ${io}b] -} - -def Canvas iohilite {} {return $@iohilite} - -def Canvas motion_iohilite {target x y} { - set c [$self widget] - mset {type id detail} $target - if {[llength $@keynav_iosel_i] || [llength $@keynav_iosel_o]} {return} - if {$@editmode && [$id canvas] == $self} { - switch $type { - inlet {set io i} - outlet {set io o} - default {return} - } - set port [$id hilite_io $io $x $y] - set @dehighlight [list $c delete ${id}$io${port}b] - } -} - -#-----------------------------------------------------------------------------------# -# returns one of those five things: -# object $id : the body of an object -# inlet $id $inlet : an inlet of an object -# outlet $id $outlet : an outlet of an object -# wire $id : a wire -# label $id : a label -# nothing : nothing -def Canvas identify_target {x y f} { - set c [$self widget] - set cx [expr $x*$@zoom] - set cy [expr $y*$@zoom] - set stack [$c find overlapping [expr $cx-2] [expr $cy-2] [expr $cx+2] [expr $cy+2]] - # reversing the stack is necessary for some things - # not reversing the stack is also necessary for some other things - # we have to figure out something. - set stack [lreverse $stack] - set target "" - foreach tag $stack {set target [$self target $x $y $f $tag]; if {[llength $target] > 1} {break}} - if {[llength $target] > 1} {return $target} {return [list "nothing"]} -} - -def Canvas target {x y f tag} { - set c [$self widget] - set cx [expr $x*$@zoom] - set cy [expr $y*$@zoom] - set tags [$c gettags $tag] - if {[regexp {^[xo][0-9a-f]{6,8}} $tags id]} { - # prior to Aug 15th, Wires had lower priority as all objects together - # now it's same priority, so just stacking order (and it's prolly wrong) - if {[$id classtags] == ""} {return [list "nothing"]} - set class [$id class] - if {[$self == $id]} {continue} - if {[$class <= Wire]} {if {$@action != "imove"} {return [list "wire" $id]}} - if {[$class <= Box]} { - if {$@action == "imove"} { - foreach tag [$self item_stack $x $y] { - set tags2 [$c gettags $tag] - if {[regexp {^[xo][0-9a-f]{6,8}} $tags2 id2]} { - set class [$id2 class] - if {[$class == Wire]} {return [list "wire" $id2]} - } - } - } - mset {x1 y1 x2 y2} [$id bbox] - if {[regexp {^x[0-9a-f]{6,8}LABEL} $tags label]} { - if {$x>$x1 && $x<$x2 && $y>$y1 && $y<$y2} { - return [list "object" $id] - } else { - return [list "label" $id] - } - } - set outs [$id noutlets] - set ins [$id ninlets] - if {$y>=$y2-6 && $outs} { - set val [expr int(($x-$x1)*$outs/($x2-$x1))] - if {$val==$outs} {incr val -1} - return [list "outlet" $id $val] - } - if {$y< $y1+2 && $ins} { - set val [expr int(($x-$x1)* $ins/($x2-$x1))] - if {$val== $ins} {incr val -1} - return [list "inlet" $id $val] - } - return [list "object" $id] - } - #puts "skipped a $class" - } -} - -def Canvas item_stack {x y} { - set c [$self widget] - set cx [expr {$x*$@zoom}] - set cy [expr {$y*$@zoom}] - set sense [$self pointer_sense] - set stack [$c find overlapping [expr {$cx-$sense}] [expr {$cy-$sense}]\ - [expr {$cx+$sense}] [expr {$cy+$sense}]] - set stack [lreverse $stack] - return $stack -} - -def Canvas identify_closestio {x y f} { - set c [$self widget] - set ios {} - set objs {} - foreach tag [$self item_stack $x $y] { - set tags [$c gettags $tag] - if {[regexp {^[x][0-9a-f]{6,8}[oi][0-9]{1,3}} $tags io]} { - foreach item {i o} { - set type_idx [string first $item $io] - set object [string range $io 0 [expr $type_idx-1]] - if {$type_idx >= 0} {break} - } - if {[$object canvas] == $self} {lappend ios $io} - } - } - if {![llength $ios]} {return -1} - set mindist 66666 - set idx 0; set i 0 - foreach io $ios { - set point2 [rect_centre [$c bbox $io]] - set point1 [list $x $y] - set dist [distance $point2 $point1] - if {$dist < $mindist} {set mindist $dist; set idx $i} - incr i - } - return [lindex $ios $idx] -} -def Canvas pointer_sense {} {return [$self look pointer_sense]} -def Canvas pointer_sense= {sense} { - set ::look(Canvas:pointer_sense) $sense - mset {x y} $@curpos - $@sense flash $x $y $sense "red" -} - -#-----------------------------------------------------------------------------------# -class_new StatusBar {View} ;# no, using View is wrong here. View is for tk canvas item collections. - -def StatusBar widget {} {return .$@canvas.stat} - -def StatusBar addw {a b text args} { - set f [$self widget] - if {$text!=""} { - eval [concat [list pack [label $f.${a}_l -text $text -font {helvetica -10} -pady 0] -side left] $args] - } - label $f.$a -width $b -font {helvetica -10} -background #cccccc -foreground black -anchor w -pady 0 - pack $f.$a -side left -} - -def StatusBar init {canvas} { - super - set @canvas $canvas - set f [$self widget] - frame $f -border 1 -relief ridge - $self addw px 4 "" - $self addw py 4 "" - $self addw what 28 " " -fill x -expand yes - $self addw action 12 " Action: " - $self addw sel 3 " Sel: " - $self addw focus 10 " Focus: " -} - -def Canvas statusbar_draw {x y} {$@statusbar draw $x $y} -def Canvas action {} {return $@action} -def Canvas action= {action} {set @action $action} -def Canvas zoom {} {return $@zoom} - -def StatusBar draw {x y} { - if {$x == "??"} {return} - set c [$@canvas widget] - set f [$self widget] - set zoom [$@canvas zoom] - set x [expr [$c canvasx $x]/$zoom] - set y [expr [$c canvasy $y]/$zoom] - set target [$@canvas identify_target $x $y -1] - mset {type id detail} $target - set t $target - switch -- $type { - object { - if {[info exists _($id:pdclass)]} {set class $_($id:pdclass)} {set class unknown} - append t " \[$class\]" - } - } - set action [$@canvas action] - if {[regexp ^o $action]} {set action [$action class]} - if {[string length [$@canvas focus]]} {set t "focus: [$@canvas focus]"} - $f.px configure -text [format "%4d" [expr round($x)]] - $f.py configure -text [format "%4d" [expr round($y)]] - if {$::debug} { - $f.what configure -text [$c gettags [lindex [$c find overlapping [expr $x-2] [expr $y-2] [expr $x+2] [expr $y+2]] end]] - } { - $f.what configure -text $t - } - $f.action configure -text $action - $f.sel configure -text [llength [$@canvas selection]] - $f.focus configure -text [$@canvas focus] -} - -#-----------------------------------------------------------------------------------# -class_new FindModel {Thing} - -def FindModel init {canvas} { - set @orig_canvas $canvas - set @find_string "" - set @next_canvases $canvas - set @last_canvas 0 - set @result "" - set @results {} - set @views {} - set @recursive 1 - set @info "" -} - -def FindModel reinit {} { - set @next_canvases $@orig_canvas - set @last_canvas 0 - set @result "" - set @results {} - $self remove_info -} -def FindModel remove_info {} { - foreach view $@views { - set f [$view widget] - destroy $f.info_l; destroy $f.info - } -} -def FindModel delete {} {foreach view $@views {destroy [$view widget]}; super} - -def FindModel find_string= {s} {set @find_string $s} -def FindModel find_string {} {return $@find_string} -def FindModel result= {s} { - $@orig_canvas deselect_all - $@orig_canvas selection= $s - set @result $s -} -def FindModel result {} {return $@result} -def FindModel views+ {view} {lappend @views $view} -def FindModel views {} {return $@views} -def FindModel end? {} {return $@end} -def FindModel end= {v} {set @end 0} - -def FindModel search_recursive {} { - if {![llength $@next_canvases]} {$self end; return} - if {[llength $@results]} {$self result= [lindex $@results 0]; set @results [lreplace $@results 0 0];return} - while {$@last_canvas < [llength $@next_canvases]} { - set canvas [lindex $@next_canvases $@last_canvas] - if {[$self cache_results $canvas]} { - if {![winfo exists [$canvas widget]]} {$canvas popup_open} else {focus [$canvas widget]} - $self result= [lindex $@results 0] - set @results [lreplace $@results 0 0] - incr @last_canvas - } else { - incr @last_canvas - $self search_recursive - } - return - } - set old_canvases $@next_canvases - set @next_canvases {} - if {$@recursive} { - foreach canvas $old_canvases {foreach x [$canvas get_childcanvas] {lappend @next_canvases $x}} - } else { - set @next_canvases {} - } - set @last_canvas 0 - $self search_recursive -} - -def FindModel end {} { - $self reinit - $@orig_canvas deselect_all - set @info " \"$@find_string\" not found" - foreach view $@views { - $view addw label "info" "info" - } -} - -def FindModel cache_results {canvas} { - set @results {} - foreach child [$@objects values] { - if {[string first $@find_string [$child text] 0] >= 0} { - lappend @results $child - } - } - if {[llength $@results]} {return 1} else {return 0} -} - -class_new FindView {FindModel} ;# no, using View is wrong here. View is for tk canvas item collections. -def FindView widget {} {return .$@canvas.find} -def FindView init {canvas} { - findmodel views+ $self - set @canvas $canvas - set @break 0 - set f [$self widget] - frame $f -border 1 -relief ridge - $self addw button "close" "" - $self addw text "find" "find" - $self addw checkbutton "recursive" "recursive" - if {[winfo exists .$@canvas.yscroll]} {set w .$@canvas.yscroll} else {set w .$@canvas.c} - pack $f -side bottom -fill x -before $w - set string [findmodel find_string] - if {$string != ""} {$f.find insert 0 $string} -} - -def FindView addw {type name label} { - set f [$self widget] - if {$label!=""} { - eval [concat [list pack [label $f.${label}_l -text ${label}: -font {helvetica -10} -pady 0] -side left]] - } - switch $type { - text { - entry $f.$name -width 10 -relief flat -bg white -borderwidth 0 -highlightthickness 0 - bind $f.$name <Escape> "findmodel delete" - bind $f.$name <Return> "$self find" - } - checkbutton { - checkbutton $f.$name - if {$name == "recursive"} {$f.$name configure -variable _(findmodel:recursive)} - } - button { - button $f.$name -border 1 -command "findmodel delete" -image icon_close -width 9 -height 9 - if {$name == "close"} {bind $f.$name <Return> "findmodel delete"} - } - label {label $f.$name -textvariable _(findmodel:info) -font {helvetica -10} -pady 0} - } - pack $f.$name -side left - bind $f.$name <Tab> "$self traversal %K %W forward" -} - -def FindView find {} { - set f [$self widget] - findmodel find_string= [$f.find get] - findmodel search_recursive - focus .$@canvas.c -} - -def FindView traversal {k w direction} { - set f [$self widget] - if {$w == "$f.recursive"} {set next $f.close} else {set next [tk_focusNext $w]} - focus $next -} - -def Canvas check_findbar {} { - if {[info exists ::_(findmodel:_class)] && ![winfo exists .$self.find.find]} {FindView new $self} -} - -def Canvas get_childcanvas {} { - set canvases {} - foreach child [$@objects values] {if {[$child class] == "Canvas"} {lappend canvases $child}} - return $canvases -} - -def Canvas runcommand {} {$@runcommand pack_prompt} - -class_new Runcommand {Listener} -def Runcommand canvas {} {return $@canvas} - -def Runcommand init {serf name command} { - set @history [History new 20] - set @serf ${serf}.run - set @command $command - set @expanded 0 - set @canvas [string trimleft $serf "."] - set @defs {} - set @completions {} - set @comp_i 0 - set @comp_s "666" - set @show_id 0 - $self defs - set f $@serf - frame $f -border 1 -relief ridge - button $f.close -border 1 -command "$self unpack_prompt" -image icon_close -width 9 -height 9 - bind $f.close <Return> "$self unpack_prompt" - pack $f.close -side left - bind $f.close <Tab> "$self traversal %K %W forward" - label $f.cmd_l -text Command: -font {helvetica -10} -pady 0 - pack $f.cmd_l -side left - entry $f.entry -width 30 -relief flat -bg white -borderwidth 0 -highlightthickness 0 - bind $f.entry <Escape> "$self unpack_prompt" - bind $f.entry <Control-g> "$self unpack_prompt" - bind $f.entry <Return> "$self eval" - bind $f.entry <Up> "$self scroll_history +1" - bind $f.entry <Down> "$self scroll_history -1" - bind $f.entry <Control-p> "$self scroll_history +1" - bind $f.entry <Control-n> "$self scroll_history -1" - bind $f.entry <Tab> "$self completion +" - switch $::tcl_platform(os) { - Linux {bind $f.entry <ISO_Left_Tab> "$self completion -"} - default {bind $f.entry <Shift-Tab> "$self completion -"} - } - pack $f.entry -side left -fill x -expand yes - bind $f.entry <Control-Tab> "$self traversal %K %W forward" -} - -def Runcommand pack_prompt {} { - set f $@serf - set @show_id [$@canvas show_id] - if {!$@show_id} {$@canvas show_id= 1} - if {[winfo exists .$@canvas.yscroll]} {set w .$@canvas.yscroll} else {set w .$@canvas.c} - pack $f -side bottom -fill x -before $w - focus $f.entry -} - -def Runcommand unpack_prompt {} { - if {!$@show_id} {$@canvas show_id= 0} - pack forget $@serf - focus [$@canvas widget] -} - -def Runcommand traversal {k w direction} { - set f $@serf - if {$w == "$f.entry"} {set next $f.close} else {set next [tk_focusNext $w]} - focus $next -} - -def Runcommand eval {} { - set f $@serf - if {[winfo exists $f.completion]} { - set l [string range $@comp 0 [expr [string first ":" $@comp 0]-1]] - $self replace $l - destroy $f.completion - return - } - #$self unpack_prompt - super - $self unpack_prompt -} - -def Runcommand defs {} { - set name [$@canvas class] - set len [string length ${name}_] - foreach def [$name methods] {lappend @defs $def} -} - -def Runcommand completion {which} { - set f $@serf - set text [$f.entry get] - if {$text != $@comp_s} { - set @comp_s $text - set @completions {} - set @comp_i 0 - foreach def $@defs {if {[regexp ^$@comp_s $def]} {lappend @completions $def}} - } - if {![llength $@completions]} return - set def [lindex $@completions $@comp_i] - set args [$@canvas args $def] - if {[lindex $args 0] == "self"} { - set args2 [lreplace $args 0 0] - } else { - set args2 $args - } - if {![llength $args2]} {set args2 "none"} - set @comp [join [list $def ":" $args2]] - if {$which == "+"} { - set @comp_i [expr ($@comp_i+1)%[llength $@completions]] - } else { - set @comp_i [expr $@comp_i-1] - if {$@comp_i<0} {set @comp_i [expr [llength $@completions]-1]} - } - if {![winfo exists $f.completion]} { - label $f.completion -textvariable _($self:comp) -pady 0 - pack $f.completion -side right - } -} - -def Thing args {def} { - set class [$self class] - set ancestors [$class ancestors] - set name ${class}_$def - set n 0 - foreach class $ancestors { - set name ${class}_$def - if {[info exists ::__args($name)]} {break} - } - return $::__args($name) -} - -def Canvas visible_rect {} { - set c [$self widget] - set height [winfo height $c] - set width [winfo width $c] - if {$width == 1 && $height == 1} {set height 300; set width 450} - mset {l r} [$c xview] - mset {t b} [$c yview] - if {$l == $r} {set l 0; set r 1} - if {$t == $b} {set t 0; set b 1} - set w [expr $width / ($r - $l)] - set h [expr $height / ($b - $t)] - mset {l2 r2} [lmap * [list $l $r] $w] - mset {t2 b2} [lmap * [list $t $b] $h] - return [list $l2 $t2 $r2 $b2] -} - -def Canvas clipboard_coords {offset} { - set in 0 - foreach mess [pd_mess_split [$::clipboard value]] { - set type [lindex $mess 1] - switch $type { - canvas {set in 1} "" {} connect {} - default { - if {$type == "restore"} {set in 0} - mset {x y} [lmap + [lrange $mess 2 3] $offset] - if {!$in} {lappend xcoords $x; lappend ycoords $y} - } - } - } - return [list $xcoords $ycoords] -} - -def Canvas paste_visible? {x1 y1 x2 y2 offset} { - set in 0 - foreach mess [pd_mess_split [$::clipboard value]] { - set type [lindex $mess 1] - switch $type { - canvas {set in 1} "" {} connect {} - default { - if {$type == "restore"} {set in 0} - mset {x y} [lmap + [lrange $mess 2 3] $offset] - if {!$in} { - if {$x > $x2 || $x < $x1} {return 0} - if {$y > $y2 || $y < $y1} {return 0} - } - } - } - } - return 1 -} - -def Canvas copy_times= {c} {set @copy_count $c} -def Canvas copy_times {} {return $@copy_count} - -def Canvas copy {} { - if {![$@objectsel size]} {return} - $clipboard value= "" - $self copy_times= 1 - array unset ::obj_index_sel $self:* - set j 0 - foreach i [lsort -integer [$@objectsel keys]] { - set child [$@objectsel get $i] - #set ::obj_index_sel($self:$child) [$@objectsel search $child] - set ::obj_index_sel($self:$child) $j; incr j - $child deconstruct_to $::clipboard - } - foreach wire [$@wiresel values] { - if {[array names ::obj_index_sel $self:[$wire from]] == ""} {continue} - if {[array names ::obj_index_sel $self:[$wire to ]] == ""} {continue} - $wire deconstruct_to $::clipboard $self - } -} - -def Canvas paste {} { - if {[$self look snap_grid]} {set offset [$self look grid_size]} {set offset 15} - $self do_paste [expr [$self copy_times] * $offset] - $self copy_times= [expr [$self copy_times] + 1] -} - -def Canvas do_paste {offset} { - set in 0 - $self deselect_all - netsend [list .$self "push"] - foreach mess [pd_mess_split [$::clipboard value]] { - set type [lindex $mess 1] - if {$type == "restore"} {incr in -1} - if {!$in} {set with [list $self new_object_copyselect]} else {set with ""} - switch $type { - "" {} - canvas {incr in; netsend $mess} - connect { - if {$with != ""} {set with [list $self new_wire_select]} - netsend $mess $with} - default {netsend [$self paste_coords $mess $offset] $with} - } - } - netsend [list #X pop 1] -} - -def Canvas paste_coords {mess offset} { - set x [lindex $mess 2]; set y [lindex $mess 3] - mset {vx1 vy1 vx2 vy2} [$self visible_rect] - mset {xcoords ycoords} [$self clipboard_coords $offset] - set visible [$self paste_visible? $vx1 $vy1 $vx2 $vy2 $offset] - set ref [lsearch $ycoords [lindex [lsort -real -increasing $ycoords] 0]] - if {!$visible} { - set xoff [expr ($vx2 - $vx1) * 0.25] - set yoff [expr ($vy2 - $vy1) * 0.25] - set x2 [expr [lindex $mess 2] - [lindex $xcoords $ref] + $vx1 + $xoff] - set y2 [expr [lindex $mess 3] - [lindex $ycoords $ref] + $vy1 + $yoff] - return [lreplace $mess 2 3 $x2 $y2] - } else { - puts "\t \t [expr $x+$offset] [expr $y+$offset] <<<<<" - return [lreplace $mess 2 3 [expr $x+$offset] [expr $y+$offset]] - } -} - -def Canvas cut {} { - $@history atomically [list cut] { - $self copy - $self delete_selection - } -} - -def Canvas duplicate {} { - if {[$self look snap_grid]} {set off [$self look grid_size]} {set off 15} - $self do_duplicate $off -} - -def Canvas do_duplicate {offset} { - global clipboard - set backup $clipboard - set clipboard [Clipboard2 new] - $self copy - $self do_paste $offset - $clipboard delete - set clipboard $backup -} - -def Canvas mouse_copy {} { - $self do_duplicate 0 -} - -def Canvas select_all {} { - $self editmode= 1 - eval [concat [list $@objectsel reinit] [$@objects list]] - eval [concat [list $@wiresel reinit] [ $@wires list]] -} -def Canvas deselect_all {} { - #$self editmode= 1 - $@objectsel clear - $@wiresel clear -} - -def Canvas popup_help {} {$::main class_browser} - -def Canvas popup_open {} { - #$self init_window - #set @mapped 1 - if {[winfo exists [$self widget]]} {raise .$self; return} - netsend [list .$self vis 1] - #$self init_window - #$self redraw -} - -def Canvas popup {id x y} { - set p .$self.popup - catch {destroy $p} - menu $p -tearoff false - if {$id == $self} { - $self populate_menu $p {popup_properties popup_help} - } elseif {[$id class] == "Wire"} { - $id populate_menu $p {popup_insert} - } else { - $id populate_menu $p {popup_properties popup_open popup_help - popup_clear_wires popup_remove_from_path popup_delete_from_path popup_copy_id} - } - tk_popup $p [expr $x-5] [expr $y-5] -} - -def View popup_copy_id {} { - clipboard clear - clipboard append $self -} - -def Canvas disconnect {wire} { - set @keynav_tab_sel "wire" - set id [$@wires get [$self wire_idx $wire]] - if {$id == $@keynav_current || $id == $@keynav_last_wire} { - set @keynav_current 0 - set @keynav_last_wire 0 - } - mset {from outlet to inlet} $wire - netsend [list .$self disconnect $from $outlet $to $inlet] - $@history add [list $self connect $wire] -} -def Canvas connect {wire {callback ""}} { - mset {from outlet to inlet} $wire - netsend [list .$self connect $from $outlet $to $inlet] $callback - $@history add [list $self disconnect $wire] -} - -def Canvas clear_wires_of {obj} { - if {![llength [$obj ioselect]]} { - set port 0; set type "none" - } else { - set port [lindex [$obj ioselect] 0] - set type [lindex [$obj ioselect] 1] - } - foreach wire [$obj wires2] { - mset {from outlet to inlet} [$wire report] - switch $type { - i {if { $to==$obj && $inlet==$port} {$self disconnect [$wire connects]; if { !$inlet} {lappend @auto_wire_from $from}}} - o {if {$from==$obj && $outlet==$port} {$self disconnect [$wire connects]; if {!$outlet} {lappend @auto_wire_to $to }}} - none { - $self disconnect [$wire connects] - if {$from==$obj && !$outlet} {lappend @auto_wire_to $to } - if { $to==$obj && ! $inlet} {lappend @auto_wire_from $from} - } - } - } -} - -def Canvas clear_wires {} { - set @auto_wire_to {}; set @auto_wire_from {} - if {[$@objectsel size] == 1} { - set objs [$@objectsel values] - } else { - if {![llength $@keynav_iosel_i] && ![llength $@keynav_iosel_o]} {return} - set objs [list $@keynav_iosel_i $@keynav_iosel_o] - } - foreach obj $objs {$self clear_wires_of $obj} -} - -def Canvas reconnect {} { - foreach from $@auto_wire_from { - set idx1 [$@objects search $from] - foreach to $@auto_wire_to { - set idx2 [$@objects search $to] - set wire [list $idx1 0 $idx2 0] - if {[$self wire_idx $wire] < 0} {$self connect $wire} - } - } -} - -def Canvas delete_obj_from_path {} {$self clear_wires; $self reconnect; $self delete_selection} -def Canvas remove_obj_from_path {} {$self clear_wires; $self reconnect} - -def Canvas wire_idx {connects} { - foreach {idx x} [$@wires list] { - if {[string compare [join $connects] [join [$x connects]]] == 0} {return $idx} - } - return -1 -} - -def Canvas reconnect_brkwires {type brk_quads obj} { - set k [$@objects search $obj] - foreach quad $brk_quads { - mset {from outlet to inlet} $quad - set orig_outlet $outlet; set orig_inlet $inlet - switch $type { - i {set orig_obj $to; set to $k; set inlet 0} - o {set orig_obj $from; set from $k; set outlet 0} - } - netsend [list .$self connect $from $outlet $to $inlet] - } - if {$type == "i"} { - netsend [list .$self connect $k 0 $orig_obj $orig_inlet] - } else { - netsend [list .$self connect $orig_obj $orig_outlet $k 0] - } - $self new_object_callback $obj - -} - -def Canvas expand_port {type idx port} { - set obj [$@objects get $idx] - mset {bx1 by1 bx2 by2} [$obj io_bbox $type $port] - mset {ox1 oy1 ox2 oy2} [$obj bbox] - mset ys [expr $oy2-$oy1] - mset {brk_wires brk_quads} [$self broken_wires $type $idx $port $self] - switch $type { - i {mset {nx ny} [$self xy_snap $bx1 [expr $by1-25]]} - o {mset {nx ny} [$self xy_snap $bx1 [expr $by1+$ys+25]]} - } - foreach quad $brk_quads {$self disconnect $quad} - set reply [list $self reconnect_brkwires $type $brk_quads] - netsend [concat [list .$self obj $nx $ny] t a] $reply - -} - -def Canvas outlet_expand {k outlet} {set reconnect [$self broken_wires o $k $inlet]} - -def Canvas implicit_wires {objs} { - set l {}; set h $@objects - foreach obj $objs { - set k [$h search $obj] - for {set i 0} {$i < [$obj ninlets]} {incr i} { - set ws [$self com_wires i $k $i]; if {[llength $ws]} {foreach w $ws {lappend l $w}} - } - for {set o 0} {$o < [$obj noutlets]} {incr o} { - set ws [$self com_wires o $k $o]; if {[llength $ws]} {foreach w $ws {lappend l $w}} - } - } - #return [lsort -integer -unique $l] - return [lsort -unique $l] -} - -def Canvas com_wires {type k port} { - set h $@objectsel; set obj [$@objects get $k]; set wires [$obj wires2]; set l {} - foreach wire $wires { - mset {f2 o2 t2 i2} [$wire connects] - if {$t2==$k && $i2==$port && $type=="i" && [$h exists $f2]} {lappend l $wire} - if {$f2==$k && $o2==$port && $type=="o" && [$h exists $t2]} {lappend l $wire} - } - return $l -} - -def Canvas broken_wires {type k port canvas} { - set shash [$canvas objectsel] - set obj [[$canvas objects] get $k] - set wires [$obj wires2]; set brk_wires {}; set quads {} - foreach wire $wires { - mset {f2 o2 t2 i2} [$wire connects] - if {$t2==$k && $i2==$port && $type=="i" && ![$shash exists $f2]} { - lappend brk_wires $wire; lappend quads [$wire connects] - } - if {$f2==$k && $o2==$port && $type=="o" && ![$shash exists $t2]} { - lappend brk_wires $wire; lappend quads [$wire connects] - } - } - return [list $brk_wires $quads] -} - - -def Canvas selection_center {} { - set x 0; set y 0 - foreach obj [$@objectsel values] { - mset {x1 y1} [$obj xy] - incr x $x1 - incr y $y1 - } - set n [$@objectsel size] - set x [expr $x / $n] - set y [expr $y / $n] - return [list $x $y] -} - -# translate the key/idx in $@objects to key/idx in $@objectsel -def Canvas idx_map {idx} { - set i 0; set obj [$@objects get $idx] - foreach sobj [$@objectsel values] {if {$obj == $sobj} {return $i}; incr i} - return -1 -} - -def Canvas subpatcherize_mkio {center iolist offset} { - mset {x y} $center; set inx 0; set outx 0 - for {set i 0} {$i < [llength $iolist]} {incr i} { - mset {type io port dsp} [lindex $iolist $i] - if {$type == "i"} { - if {$dsp} {set inlet "inlet~"} {set inlet "inlet"} - netsend [list #X obj [expr ($inx+1)*100] 0 $inlet] - netsend [list #X connect $offset 0 $io $port] - incr inx - } else { - if {$dsp} {set outlet "outlet~"} {set outlet "outlet"} - netsend [list #X obj [expr ($outx+1)*100] [expr $y*2] $outlet] - netsend [list #X connect $io $port $offset 0] - incr outx - } - incr offset - } -} - -def Canvas subpatcherize_iopos {orig io} { - set tab {}; set result {} - for {set x 0} {$x < [llength $orig]} {incr x} { - mset {from k1 io1 dsp} [lindex $orig $x]; mset {k2 io2} [lindex $io $x] - set obj1 [$@objects get $k1] - mset {x1 y1 x2 y2} [$obj1 io_bbox $from $io1]; set x1 [expr int($x1)] - lappend pos $x1; lappend tab [list $k1 $x1 [list $k2 $io2 $dsp]] - #lappend pos $x1; lappend tab [list $k1 $x1 [list $k2 $io2]] - } - set tab [lsort -index 1 -real $tab]; set foo "" - foreach item $tab {mset {k1 val foo2} $item; if {$foo2 != $foo} {lappend result $foo2}; set foo $foo2} - return $result -} - -def Canvas subpatcherize {} { - set center [$self selection_center] - set rewire_off [llength [$@objectsel values]] - set ins {}; set outs {}; set toins {}; set fromouts {}; set broken {}; set iolist {} - foreach obj [$@objectsel values] { - for {set i 0} {$i < [$obj ninlets]} {incr i} { - mset {brk_wires brk_quads} [$self broken_wires i [$@objects search $obj] $i $self] - if {[llength $brk_wires]} { - foreach wire $brk_quads { - set out_obj_name [[$@objects get [lindex $wire 0]] text] - if {[regexp {~} $out_obj_name]} {set dsp 1} {set dsp 0} - lappend broken [concat i $wire $dsp] - } - } - } - for {set o 0} {$o < [$obj noutlets]} {incr o} { - mset {brk_wires brk_quads} [$self broken_wires o [$@objects search $obj] $o $self] - if {[llength $brk_wires]} { - foreach wire $brk_quads { - set out_obj_name [[$@objects get [lindex $wire 0]] text] - if {[regexp {~} $out_obj_name]} {set dsp 1} {set dsp 0} - lappend broken [concat o $wire $dsp] - } - } - } - } - # $broken stores total number of broken connections, i= need [inlet] o = need [outlet] - foreach c $broken { - mset {type f o t i dsp} $c - if {$type == "i"} { - lappend ins [list $t $i]; lappend toins [list o $f $o $dsp] - } else { - lappend outs [list $f $o]; lappend fromouts [list i $t $i $dsp] - } - } - # figures out the inlet/outlet positioning and num of in/outlet to create - set ins [$self subpatcherize_iopos $toins $ins] - set outs [$self subpatcherize_iopos $fromouts $outs] - # iolist stores in/outlets to be conected inside the subpatch - foreach in $ins {mset {idx p dsp} $in; lappend iolist [list i [$self idx_map $idx] $p $dsp]} - foreach out $outs {mset {idx p dsp} $out; lappend iolist [list o [$self idx_map $idx] $p $dsp]} - puts "\t \t Cutting..............." - $self cut - puts "\t \t Push.................." - netsend [list .$self "push"] - netsend [list #N canvas 0 0 450 300 sub 0] [list $self subpatcherize_id] - puts "\t \t Push clipboard........" - foreach mess [pd_mess_split [$::clipboard value]] {netsend $mess} - - #creating in/outlets - $self subpatcherize_mkio $center $iolist $rewire_off - #netsend [list [concat #X restore $center pd sub]] - netsend [concat #X restore $center pd sub] - puts "\t \t Pop..................." - netsend [list .$self "pop"] [list $self subpatcherize_rewire $broken $ins $outs] -} - -def Canvas subpatcherize_id {id} {set @subpatcherize_id $id} - -def Canvas subpatcherize_rewire {wires inlist outlist bogus} { - set obj $@subpatcherize_id - foreach wire $wires { - mset {type f o t i dsp} $wire - if {$type == "i"} { - set idx [lsearch $inlist [list $t $i $dsp]] - $self connect [list $f $o [$@objects search $obj] $idx] - } else { - set idx [lsearch $outlist [list $f $o $dsp]] - $self connect [list [$@objects search $obj] $idx $t $i] - } - } -} - -def Canvas end_action {} { - switch -- $@action { - none {post "ending action 'none' makes no sense"} - default {$@action delete; set @action "none"} - } -} - -proc shift? {f} {return [expr $f&1]} -proc ctrl? {f} {return [expr $f&2]} -proc alt? {f} {return [expr $f&4]} -proc button_of {f} { -# set f [expr $f>>8] -# set b 1 -# while {[expr $f&1==0} {set f [expr $f>>1]} -# return $f - return [expr $f>>8] -} - -class_new FutureWire {View} -def FutureWire init {canvas x y f target} { - super - set @canvas $canvas - mset {type from port} $target - switch $type { - outlet {set @from $from; set @outlet $port; set @to "" ; set @inlet "" ; set port_name ${from}o${port}} - inlet {set @from "" ; set @outlet "" ; set @to $from; set @inlet $port; set port_name ${from}i${port}} - } - mset {x y} [lmap / [rect_centre [[$@canvas widget] bbox $port_name]] [$@canvas zoom]] - set @x1 $x - set @y1 $y - $self motion $@x1 $@y1 $f $target -} -def FutureWire motion {x y f target} { - set @x2 $x - set @y2 $y - mset [list type foo bar] $target - $self draw -} -def FutureWire unclick {x y f target} { - mset [list type foo bar] $target - mset {obj iox ioy io idx} [$@canvas iohilite] - if {$obj != -1} { - switch $io {i {set type "inlet"} o {set type "outlet"}} - set target [list $type $obj $idx] - } - switch $type { - outlet {mset [list type @from @outlet] $target} - inlet {mset [list type @to @inlet] $target} - default {} - } - set from_idx [[$@canvas objects] search $@from] - set to_idx [[$@canvas objects] search $@to] - if {$from_idx >= 0 && $to_idx >= 0 && $@from != $@to} { - $@canvas connect [list $from_idx $@outlet $to_idx $@inlet] - } - if {![shift? $f]} {$@canvas end_action} -} -def FutureWire draw {} { - $self item WIRE line [xys $@x1 $@y1 $@x2 $@y2] -dash {4 4 4 4} -fill [$self look dash] -smooth yes -} - -class_new GopRect {View} - -def GopRect init {canvas rect} { - set @canvas $canvas - set @rect $rect -} - -def GopRect draw {} { - $self item GOPRECT rectangle $@rect -outline [$self look fg] -} - -class_new SelRect {View} -def SelRect init {canvas x y bf target} { - super - set @x1 $x - set @y1 $y - set @canvas $canvas - $self motion $x $y 0 $target -} -def SelRect motion {x y f target} { - set @x2 $x - set @y2 $y - $self draw -} -def SelRect unclick {x y f target} { - $self motion $x $y 0 $target - set sel {} - set c [$@canvas widget] - mset {x1 y1 x2 y2} [lmap * [list $@x1 $@y1 $@x2 $@y2] [$@canvas zoom]] - set sel [$c find overlapping $x1 $y1 $x2 $y2] - set selrect_index [lsearch $sel [$c find withtag selrect]] - set sel [lreplace $sel $selrect_index $selrect_index] - if {[llength $sel]} { - set objects {} - #set wires {} - foreach tag $sel { - if {[regexp {^[xo]?[0-9a-f]{6,8}} [$c gettags $tag] id]} { - if {[$@canvas == $id]} {continue} - if {[[$id class] <= Box]} {lappend objects $id} - #elseif {[[$id class] <= Wire]} {lappend wires $id} - } - } - set objects [lsort -unique $objects] - #set wires [lsort -unique $wires] - set objects2 {} - #so that objects in gop won't get selected... - foreach obj $objects {if {[$obj canvas] == $@canvas} {lappend objects2 $obj}} - $@canvas selection+= $objects2 - #$@canvas selection_wire+= $wires - } - $@canvas selection_wire+= [$@canvas implicit_wires $objects] - set _($@canvas:keynav_tab_sel) "wire" - $@canvas end_action - -} -def SelRect draw {} { - $self item RECT line [list $@x1 $@y1 $@x2 $@y1 $@x2 $@y2 $@x1 $@y2 $@x1 $@y1] \ - -fill [$self look rect] -dash {3 3 3 3} -dashoffset 3 -} - -def Canvas click {x y f target} { - if {[winfo exists .completion]} { - raise .completion - focus .completion.comp - return - } - mset {type id detail} $target - set c [$self widget] - focus $c - set @click_at [list $x $y] - if {$f&8} {if {$id == ""} {set id $self}; $self right_click $id $x $y; return} - if {!$@editmode} {$self click_runmode $id $x $y $f $target; return} - set in_selection [expr [$@objectsel search $id]>=0] - switch $@action { - mouse_copy {$self move_selection} - } - switch $type { - outlet {} - inlet {} - object {$self click_on_object $id $f} - wire {$self click_on_wire $id $f $x $y} - nothing { - #$self deselect_all - if {[lindex $@iohilite 0] == -1} {$self click_on_nothing $f $target $x $y; return} - } - label {$self click_on_object $id $f} - default {error "BORK: $type"} - } - if {$@iohilite != "" && $type != "wire"} { - mset {obj iox ioy io idx} $@iohilite - if {$obj < 0} {return} - switch $io { - i {set type "inlet"} - o {set type "outlet"} - } - if {$@action == "none" && [$obj canvas] == $self} { - set @action [FutureWire new $self $iox $ioy $f [list $type $obj $idx]] - } - return - } -} - -def Canvas click_runmode {id x y f target} { - foreach obj [$self selection] {if {[[$obj class] <= AtomBox]} {$obj unedit}} - $self deselect_all - #if {$@focus != ""} {if {[[$@focus class] <= TextBox]} {$self selection-= $@focus;$@focus unedit}} - if {[llength $id]} { - if {[$id class] != "Canvas"} { - $id click $x $y $f $target - } else { - if {[$id subpatch]} { - if {![$id mapped]} {$id popup_open} elseif {![$id gop]} {raise .$id} - } - } - } -} - -def Canvas click_on_object {id f} { - set c [$self widget]; set text $c.${id}text - # so that if one clicks on the objectbox when editing the objectname, the focus won't get lost - if {[winfo exists $text]} {focus $text; return} - switch [expr $f&255] { - 0 { - if {[$self action] == "mouse_copy"} {$self action= "none"; return} - # if $id is the content of GOP - if {[$id canvas] != $self} { - set obj [$id get_parent_gop $self] - } else {set obj $id} - if {[$@objectsel search $obj] < 0 || [$@objectsel size] == 0} { - $self deselect_all - $self selection+= $obj - set @action edit - } else {set @action edit} - } - 1 { - if {[$@objectsel search $id] < 0} { - $self selection+= $id - } else { - $self selection-= $id - } - } - 2 { - if {![llength [$id wires2]]} {return} - $self deselect_all - $self selection+= $id - $self remove_obj_from_path - } - 3 { - if {[$id canvas] != $self} { - set obj [$id get_parent_gop $self] - } else {set obj $id} - if {![$@objectsel size]} {$self selection+= $obj} - if {[$@objectsel search $obj] < 0} { - $self deselect_all - $self selection+= $obj - } - $self action= "mouse_copy" - } - } -} -def Canvas click_on_wire {id f x y} { - set obj_selection [$self selection] - if {[llength $obj_selection]} {$self selection-= $obj_selection} - set @keynav_tab_sel "object" - switch [expr $f&255] { - 0 {$self selection_wire= $id} - 1 {$self selection_wire+= $id} - 2 { - set c [$self widget] - set wire [$id connects] - $self disconnect $wire - set from [$@objects get [lindex $wire 0]]; set outlet [lindex $wire 1] - set to [$@objects get [lindex $wire 2]]; set inlet [lindex $wire 3] - set opos [lmap / [rect_centre [$c bbox ${from}o${outlet}]] [$self zoom]] - set ipos [lmap / [rect_centre [$c bbox ${to}i${inlet}]] [$self zoom]] - set pos [list $x $y] - if {[distance $pos $opos] > [distance $pos $ipos]} { - mset {x1 y1} $ipos - set target [list outlet $from $outlet] - } else { - mset {x1 y1} $opos - set target [list inlet $to $inlet] - } - set @action [FutureWire new $self $x1 $y1 $f $target] - } - } -} - -def Canvas click_on_nothing {f target x y} { - # this cget check actually saves a full tk redraw - if {[[$self widget] cget -cursor] != {}} {[$self widget] configure -cursor {}} - if {$@focus != ""} {if {[[$@focus class] <= TextBox]} {$@focus unedit}} - if {$@action == "insert"} {return} - if {![expr $f&255]} { - $self deselect_all - #$self click_deselect_io - } - switch $@action { - edit {} - move {} - none {} - insert {} - chain_obj {} - imove {} - mouse_copy {} - default {$@action unclick $x $y $f $target} - } - set @action [SelRect new $self $x $y $f $target] -} - -def Canvas right_click {id x y} { - set c [$self widget] - set @insert_x $x; set @insert_y $y - if {$id != $self} {set id [$self gop_target $id]} - $self popup $id [winfo pointerx $c] [winfo pointery $c] -} - -def Canvas unclick {x y f target} { - set c [$self widget] - mset {type id detail} $target - if {$@editmode} { - switch $@action { - edit { - if {[$id canvas] != $self} { - set obj [$id get_parent_gop $self] - } else {set obj $id} - if {[$id class] == "Canvas"} {if {[$id text] == "graph"} {set @action none; return}} - set focus [$self focus] - if {$focus != ""} {if {[[$focus class] <= TextBox]} {$focus unedit}} - $obj edit; set @action none; $obj changed action - } - move {$self unclick_move} - none {} - insert {} - chain_obj {} - mouse_copy {$self mouse_copy} - imove {$self unclick_move} - default {$@action unclick $x $y $f $target} - } - } else {$self unclick_runmode $target $f $x $y} - $self adjust_scrollbars - #$self checkgeometry -} - -def Canvas unclick_move {} { - $self move_selection - set @action none -} - -def Canvas move_selection {} { - foreach obj [$@objectsel values] { - if {![[$obj class] <= Box]} { - puts "Canvas unclick warning: trying to move non-Box explicitly" - continue - } - mset {x1 y1} [$obj xy] - switch $@action { - mouse_copy {} - default {$obj position= [$obj backupxy]} - } - $obj moveto $x1 $y1 - if {[$obj edit?]} {focus [[$obj canvas] widget].${obj}text} - } - set objs [$@objectsel values] -} - -def Canvas unclick_runmode {target f x y} { - if {[$self focus] != ""} {[$self focus] unclick $x $y $f $target} - mset {type id detail} $target - if {$id != ""} { - if {[$id class] == "Array"} {$id unclick $x $y $f $target; return} - } -} - -def Canvas get_bbox {} {return $@bbox} - -if {$have_expand} { - def Canvas notice {origin args} {$self child_changed $origin {expand}$args} -} else { - def Canvas notice {origin args} {eval [concat [list $self child_changed $origin] $args]} -} - -def Canvas tab_jump {} { - if {![$@objects size]} {return} - set @keynav 1 - set olength [$@objectsel size] - set wlength [ $@wiresel size] - if {$@keynav_tab_sel == "object"} { - if {[$@wires size]} {set @keynav_tab_sel "wire"} - } else { - set @keynav_tab_sel "object" - } - switch $@keynav_tab_sel { - object {$self tab_jump_object} - wire {$self tab_jump_wire} - } -} - -def Canvas tab_jump_wire {} { - # if no selection done by the mouse - if {![$@wiresel size]} { - # see if the selected object has wire, if yes, use it - # if keynav_current is already a wire, do nothing - if {[$@keynav_current class] != "Wire"} { - #use the last key selected wire as start if there is one - if {$@keynav_last_wire != 0} { - $self deselect_all - set @keynav_current $@keynav_last_wire - } else { - if {[llength [$@keynav_current wires2]]} { - $self deselect_all - set @keynav_current [lindex [$@keynav_current wires2] 0] - set @keynav_last_wire $@keynav_current - } else { - # check if the canvas has wires, if yes, use it - if {[$@wires size]} { - $self deselect_all - set @keynav_current [lindex [$@wires values] 0] - set @keynav_last_wire $@keynav_current - } else {return} - - } - } - } - } - $self selection_wire= $@keynav_current -} - -def Canvas tab_jump_object {} { - set olength [$@objectsel size] - # if there is no selection done by mouse - if {!$olength} { - # if keynav_current is 0, aka the start of key navigation - if {$@keynav_current == 0} { - if {[$@objects size]} {set @keynav_current [lindex [$@objects values] 0]} else {return} - } else { - # if the keynav_current is a wire, set keynav_current to a object - if {[$@keynav_current class] == "Wire"} { - set @keynav_last $@keynav_current - $self deselect_all - # use the last key selected obj as the start if there is one - if {$@keynav_last_obj != 0} { - set @keynav_current $@keynav_last_obj - } else { - set @keynav_current [lindex [$@keynav_current report] 0] - set @keynav_last_obj $@keynav_current - } - } - } - } elseif {$olength == 1} { - set @keynav_current [lindex [$@objectsel values] 0] - $self deselect_all - } else { - $self deselect_all - set @keynav_current [$@objects get 0] - set @keynav_last_obj $@keynav_current - } - $self selection= $@keynav_current -} - -def Canvas key_nav_up {} {$self key_nav +1 -1 0} -def Canvas key_nav_down {} {$self key_nav -1 +1 0} -def Canvas key_nav_right {} {$self key_nav -1 -1 0} -def Canvas key_nav_left {} {$self key_nav +1 +1 0} -def Canvas key_nav_up_shift {} {$self key_nav +1 -1 1} -def Canvas key_nav_down_shift {} {$self key_nav -1 +1 1} -def Canvas key_nav_right_shift {} {$self key_nav -1 -1 1} -def Canvas key_nav_left_shift {} {$self key_nav +1 +1 1} - -def Canvas key_nav {du dv shift} { - if {$@keynav_shift && !$shift} {} - set @keynav_shift $shift - if {[$@objectsel size] > 1} { - if {[llength $@keynav_iosel_i] > 0 || [llength $@keynav_iosel_o] > 0} { - #$self deselect_all - } - } - if {!$@keynav} {$self tab_jump} - switch $@keynav_tab_sel { - object { - set @keynav_next [$self quadrant $du $dv [$@objects values]] - if {!$shift} { - $self selection-= $@keynav_current - $@keynav_current selected?= 0 - set @keynav_last_obj $@keynav_next - } - if {[$@objectsel search $@keynav_next] < 0} {$self selection+= $@keynav_next} - } - wire { - #$@keynav_current selected?= 0 - set @keynav_next [$self quadrant $du $dv [$@wires values]] - if {!$shift} { - $self selection_wire-= $@keynav_current - $@keynav_current selected?= 0 - set @keynav_last_wire $@keynav_next - } - if {[$@wiresel search $@keynav_next] < 0} {$self selection_wire+= $@keynav_next} - } - } - #$self selection+= $@keynav_next - set @keynav_current $@keynav_next -} - -def Canvas victim {} { - if {[$@objectsel size]} {return [$@objectsel values]} - if {[string compare $@keynav_current 0]} {return {}} - return $@keynav_current -} - -def Canvas key_nav_ioselect {} { - if {![$@objectsel size]} {return} - set var [lindex [$@objectsel values] end] - if {$@keynav_iosel != $var} {set @keynav_iocount 0} - if {$@keynav_port != 0 && $@keynav_iosel == $var} { - #set hilitebox $@keynav_port - foreach io $@keynav_port2 {[$self widget] delete ${io}b} - } - set obj [lindex [$@objectsel values] 0] - set ins [$obj ninlets] - set outs [$obj noutlets] - set ports {}; set ports2 {}; set ports3 {} - for {set i 0} {$i < $ins} {incr i} {lappend ports ${obj}i${i}; lappend ports2 "i"; lappend ports3 $i} - for {set i 0} {$i < $outs} {incr i} {lappend ports ${obj}o${i}; lappend ports2 "o"; lappend ports3 $i} - #incr @keynav_iocount - if {$@keynav_iocount >= [llength $ports]} {set @keynav_iocount 0} - set port [lindex $ports3 $@keynav_iocount] - set type [lindex $ports2 $@keynav_iocount] - set @keynav_port ${obj}${type}${port} - set @keynav_port2 {} - # @keynav_port stores the current hilited in/outlets - # @keynav_ports stores the current hilited in/outlets if there are multiple objects - # @keynav_iosel_i stores the selected inlets - # @keynav_iosel_o stores the selected outlets - foreach object [$@objectsel values] { - if {$@keynav_iosel != $var} {set @keynav_iosel $var} - switch $type { - i { - if {[lsearch $@keynav_iosel_i $object] == -1} { - lappend @keynav_iosel_i $object - set find [lsearch $@keynav_iosel_o $object] - if {$find >= 0} {set @keynav_iosel_o [lreplace $@keynav_iosel_o $find $find]} - } - } - o { - if {[lsearch $@keynav_iosel_o $object] == -1} { - lappend @keynav_iosel_o $object - set find [lsearch $@keynav_iosel_i $object] - if {$find >= 0} {set @keynav_iosel_i [lreplace $@keynav_iosel_i $find $find]} - } - } - } - mset {x y x1 y1} [[$self widget] bbox ${object}${type}${port}] - lappend @keynav_port2 ${object}${type}${port} - set _($object:ioselect) [list [lindex $ports3 $@keynav_iocount] [lindex $ports2 $@keynav_iocount]] - #set _($object:ioselect) [lindex $ports3 $@keynav_iocount] - $object hilite_io [lindex $ports2 $@keynav_iocount] [expr $x/$@zoom] [expr $y/$@zoom] - } - incr @keynav_iocount - -} - -def Canvas keyboard_mode {} { - post "loading keyboard-mode...." - if {[file exists kb-mode.tcl]} { - package require kb-mode - $@runcommand defs - if {![info exists @kbcursor]} {set @kbcursor [kb-mode_init $self]} - puts "cursor::: $@kbcursor" - } -} - -def Canvas keyboard_mode_exit {} { - post "exiting keyboard-mode...." - package forget kb-mode - remove_callback kb-mode - $@runcommand defs - $@kbcursor delete - read_ddrc - remove_callback "kb-mode" - unset @kbcursor -} - -def Canvas keyprefix {} { - if {!$@keyprefix} {set @keyprefix 1} else {set @keyprefix 0} -} - -def Canvas click_deselect_io {} { - if {[llength $@keynav_iosel_i] || [llength $@keynav_iosel_o]} { - if {!$@iosel_deselect} {set @iosel_deselect 1} else {$self dehilite_io; set @iosel_deselect 0} - } else { - $self dehilite_io - } -} - -def Canvas dehilite_io {} { - foreach io [concat $@keynav_iosel_i $@keynav_iosel_o] { - puts "$io is a [$io class]" - set box $_($io:ioselect) - set type [lindex $_($io:ioselect) 1] - set port [lindex $_($io:ioselect) 0] - set tag ${io}${type}${port} - [$self widget] delete ${tag}b - set _($io:ioselect) {} - } - set @keynav_iosel_i {} - set @keynav_iosel_o {} - set @keynav_port 0 - set @keynav_iocount 0 -} - -def Canvas incr_scale {} {$self scale out} -def Canvas decr_scale {} {$self scale in} - -def Canvas scale {mode} { - set s $::scale_amount - switch $mode { in { set s [expr 1/$s] }} - set sel [$@objectsel values] - if {![llength $sel]} {set sel [$@objects values]} - foreach child $sel { - mset {x y} [$child xy] - set x1 [expr $x*$s] - set y1 [expr $y*$s] - $child position= [list $x1 $y1] - netsend [list .$self object_moveto $child $x1 $y1] - } - foreach child $sel {$child changed_wires} -} - -def Canvas incr_zoom {} {$self zooming in} -def Canvas decr_zoom {} {$self zooming out} -def Canvas zooming {mode} { - global zoom bar - set spinbox .$self.bbar.scale - set val [string trimright [$spinbox get] %] - set i [lsearch $zoom(canned) $val] - set end [expr [llength $zoom(canned)] - 1] - switch -regexp $mode { - in|up {if {$i<$end} {incr i +1}} - out|down {if {$i>0} {incr i -1}} - } - set per [lindex $zoom(canned) $i] - $spinbox set $per% - set @zoom [expr $per/100.0] ;# @zoom must be float, not int - #$self propagate_zoom $@zoom - $self redraw - if {[$self look gridstate]} {if {$@editmode} {$@grid erase}} - foreach child [$@objects values] {if {[$child class] == "Canvas" && [$child gop]} {$child all_changed}} -} - -def Canvas propagate_zoom {zoom} { - foreach child [$@objects values] { - if {[$child class] == "Canvas"} { - set @zoom $zoom - $child propagate_zoom $zoom - } - } -} - -#-----------------------------------------------------------------------------------# -set lastcanvasconfigured "" -set lastcanvasconfiguration "" - -def Canvas checkgeometry {} { - set topname .$self - set boo [winfo geometry $topname.c] - set boo2 [wm geometry $topname] - global lastcanvasconfigured lastcanvasconfiguration - if {$topname != $lastcanvasconfigured || $boo != $lastcanvasconfiguration} { - set lastcanvasconfigured $topname - set lastcanvasconfiguration $boo - } -} -#-----------------------------------------------------------------------------------# -def Canvas selection_move {dx dy} { - $@history atomically [list move] { - $self selection_move2 $dx $dy - } -} -def Canvas selection_move2 {dx dy} { - if {![$self editmode]} {return} - foreach o [$@objectsel values] { - mset {x1 y1} [$o xy] - if {[[$o class] <= Box]} { - $o moveto [expr $x1+$dx] [expr $y1+$dy] - } else { - puts "selection_move: $o is not a Box, it's a [$o class]" - } - } -} - -def Canvas key {x y key iso shift} { - global tooltip; if {$tooltip ne ""} {$tooltip delete; set tooltip ""} - #if {[modes_callback $self "key" $x $y $key $iso $shift]} {return} - #if {[$self focus] != ""} {[$self focus] key $key $shift} - #if {$iso != ""} {scan $iso %c key} - #set focus [$self focus] - if {!$@editmode && [llength [$self selection]] == 1} { - set obj [$self selection] - if {[[$obj class] <= AtomBox]} { - if {[regexp {^[a-zA-Z0-9~/\._]{1}$} $key]} {$obj text= $key} {return} - $obj edit - $obj clear 0 - return - } - } - if {$shift} { - if {[$self look snap_grid]} {set motion [expr [$self look grid_size]*2]} {set motion 10} - } else { - if {[$self look snap_grid]} {set motion [$self look grid_size]} {set motion 1} - } - set n [$@objectsel size] - switch -regexp -- $key { - BackSpace|Delete|KP_Delete {$self delete_selection} - Up {if {$n} {$self arrow_key 0 -$motion} else {$self scroll y -$motion}} - Down {if {$n} {$self arrow_key 0 +$motion} else {$self scroll y +$motion}} - Left {if {$n} {$self arrow_key -$motion 0} else {$self scroll x -$motion}} - Right {if {$n} {$self arrow_key +$motion 0} else {$self scroll x +$motion}} - Tab {$self tab_jump} - Return {$self return_key $x $y $key $iso $shift} - F1 {$self deselect_all} - F2 {set @keynav 0; $@active hide} - default {} - } -} - -def Canvas return_key {x y key iso f} { - mset {type id detail} [$self identify_target $x $y $f] - if {![llength $@keynav_iosel_i] && ![llength $@keynav_iosel_o]} { - if {[$@objectsel size] == 1} { - mset {bx1 by1 bx2 by2} [[$self selection] bbox] - set x1 [expr ($bx1+$bx2)/2]; set y1 [expr ($by1+$by2)/2] - $self click_wrap $x1 $y1 1 $f - $self unclick_wrap $x1 $y1 1 $f - } - } else { - foreach out_obj $@keynav_iosel_o { - set from [$@objects search $out_obj] - set outlet [lindex $_($out_obj:ioselect) 0] - foreach in_obj $@keynav_iosel_i { - set to [$@objects search $in_obj] - set inlet [lindex $_($in_obj:ioselect) 0] - $self connect [list $from $outlet $to $inlet] - } - } - $self dehilite_io - } - -} - -def Canvas arrow_key {val1 val2} { - if {![$self editmode]} { - if {[$@objectsel size] == 1} { - set o [$@selection values] - if {[[$o class] <= IEMGUI] || [[$o class] == FloatBox]} {$o key_incr $val1 $val2} - } - } else {$self selection_move $val1 $val2} -} - -def Canvas clear_selection {} { - if {[$@objectsel size] > 0 || [$@wiresel size] > 0} { - $self deselect_all - $self dehilite_io - } - if {$@keynav} { - set @keynav 0 - #bogus switch so that keynav remains the same next time.. - if {$@keynav_tab_sel == "object"} {set @keynav_tab_sel "wire"} {set @keynav_tab_sel "object"} - } -} - -#-----------------------------------------------------------------------------------# -def Canvas keynav_current {} {return $@keynav_current} -def Canvas keynav_current= {current} { - set @keynav_current $current - switch [$current class] { - Wire {set @keynav_last_wire $current} - default {set @keynav_last_obj $current} - } -} -def Canvas keynav {} {return $@keynav} -def Canvas keyup {x y key iso shift} { - if {$iso != ""} {scan $iso %c key} - if {$::macro_state} {$::macro state= 1; set ::macro_state 0 } - $@active draw -} - -class_new Active {View} -def Active init {canvas} { - super - set @canvas $canvas - set @length 3 - set @length2 10 -} -def Active draw {} { - set current [$@canvas keynav_current] - if {$current == ""} {return} - if {![string compare $current 0]} {return} - set col [$self look selectframe] - if {[$@canvas keynav]} { - if {[$current class] == "Wire"} { - $self item_delete - set i 0 - foreach side {1.6 -1.6} { - mset {ax1 ay1 ax2 ay2} [$current bbox] - set t [expr atan2($ay2-$ay1, $ax2-$ax1)] - set cx1 [expr $ax1 + (($ax2-$ax1)* 0.15)] - set cy1 [expr $ay1 + (($ay2-$ay1)* 0.15)] - set cx2 [expr ($@length * cos($t+$side)) + $cx1] - set cy2 [expr ($@length * sin($t+$side)) + $cy1] - - for {set n 0} {$n < 2} {incr n} { - set angle [lindex {45 90 -45 -90} [expr $n+$i]] - mset {ax1 ay1 ax2 ay2} [$current bbox] - set t [expr atan2($ay2-$ay1, $ax2-$ax1)] - set bx1 [expr $ax1 + (($ax2-$ax1)* 0.15)] - set by1 [expr $ay1 + (($ay2-$ay1)* 0.15)] - set bx2 [expr ($@length2 * cos($t+$angle)) + $bx1] - set by2 [expr ($@length2 * sin($t+$angle)) + $by1] - set line [list $cx2 $cy2 $bx2 $by2] - $self item LINE$angle line $line -fill $col -width 2 - } - set i [expr $i+2] - } - } else { - $self item_delete - mset {x y} [lmap - [$current xy] 5] - set line1 [list $x $y $x [expr $y + $@length2]] - set line2 [list $x $y [expr $x + $@length2] $y] - $self item LINE1 line $line1 -fill $col -width 2 - $self item LINE2 line $line2 -fill $col -width 2 - - } - } else {$self hide} -} -def Active hide {} {$self item_delete} -def Active bbox {} { - set current [$@canvas keynav_current] - set l [$current xy] - concat $l $l ;# happy now?? -} - -def Canvas update_Active {item} {$self keynav_current= $item} - -#-----------------------------------------------------------------------------------# -class_new Box {View} - -def Box init {{mess {}}} { - super - # @wires2 stores the connections to and from a object - set @wires2 {} - $self reinit $mess -} - -def Box delete {} {if {$@canvas != ""} {[$@canvas objects] unset $@index}; super} - -def Box remove_braces {str} { - # this hack is to remove the "\" in the text - regsub -all {\\} $str "" text - return $text -} - -def Box reinit {mess} { - global classinfo fields - if {[$::macro state] && [llength $mess] > 4} {$::macro append_ref $mess} - if {![llength $mess]} {return} ;# what? - if {[lindex $mess 1] == "obj"} {set i 4} else {set i 1} - set @pdclass [lindex $mess $i] - if {[info exists fields($@pdclass)]} { - set i 0 - foreach f $fields($@pdclass) {set _($self:$f) [lindex $mess $i]; incr i} - } else { - set @text [$self remove_braces [join [lrange $mess 4 end]]] - } - $self outside_of_the_box -} - -def Box update_size {} {} - -# will be so that @wires are updated correctly without breaking encapsulation -def Box connect_out {} {} -def Box connect_in {} {} - -def Box draw {} { - $self draw_box - if {[$@canvas show_id]} {$self draw_id} {$self item_delete ID} - [[$self get_canvas] widget] raise $self - $self update_hilite_io -# if {[$self class] == "Canvas"} {$self restack} - if {[info exists @elapsed]} { - mset {x1 y1 x2 y2} [$self bbox] - $self item ELAPSED text [l+ {10 1} [list $x1 $y2]] -anchor nw -fill "#008800" \ - -text $@elapsed -font {{DejaVu Sans Mono} -8} - } -} - -def Box elapsed {f} { - set @elapsed $f - $self changed -} - -def Canvas get_elapsed {} {netsend [list .$self get_elapsed]} - -def Canvas show_id {} {return $@show_id} -def Canvas show_id= {val} {set @show_id $val; $self redraw} -def Canvas id_toggle {} {if {$@show_id} {set @show_id 0} {set @show_id 1}; $self redraw} - -def Box draw_id {} { - set id [$self index]: - mset {x y} [$self xy] - set fw [font measure [$self look font] 0] - if {[$@canvas editmode]} { - set col [complement [$@canvas look bgedit]] - } else {set col [complement [$@canvas look bgrun]]} - $self item ID text [list [expr $x-([string length $id]*$fw)] [expr $y+2]] \ - -font [$self look font] -text $id \ - -fill $col -anchor nw -} - -def Box draw_box {} {} -def Box edit {} {} -def Box unedit {} {} - -def Box bbox {} { - mset {x y} [$self xy] - set xs $@xs - set ys $@ys - list $x $y [expr {$x+$xs}] [expr {$y+$ys}] -} - -def Box io_bbox {type port} { - mset {x1 y1 x2 y2} [$self bbox] - set xs [expr {$x2-$x1}] - # method calls aren't as fast as we'd want them to be. - #set iowidth [$self look iowidth] - #set fy [$self look iopos] - set iowidth 7 - set fy -1 - switch $type { - o {set n $@noutlets; set y [expr {$y2+$fy }]} - i {set n $@ninlets; set y [expr {$y1-$fy-1}]} - } - set nplus [expr {$n==1 ? 1 : $n-1}] - set onset [expr {$x1+($xs-$iowidth)*$port/$nplus}] - set points [list $onset $y [expr {$onset+$iowidth}] $y] - return $points -} - - -def Box ioselect= {type port} {set @ioselect [list $type $port]} -def Box ioselect {} {return $@ioselect} - -def Box wires2 {} {return $@wires2} -def Box wires2+= {val} {if {[lsearch $@wires2 $val] < 0} {lappend @wires2 $val}} - -def Box changed_wires {} {foreach wire $@wires2 {$wire changed}} - -def Box delete_wire {wire} { - set find [lsearch $@wires2 $wire] - if {$find != -1} {set @wires2 [lreplace $@wires2 $find $find]} -} - -def Box move {dx dy} { - set @x1 [expr {$@x1+$dx}]; set @y1 [expr {$@y1+$dy}] - set zoom [$@canvas zoom] - $self changed ;# until we find a way to avoid rounding errors on [$@canvas widget] move. - $self changed_wires -} - -# temporary hack... only used during the moving of objects. -def Box backupxy= {xy} {set @backupxy $xy} -def Box backupxy {} {return $@backupxy} - -# the only one sending to the server. -# View position= is when getting position from server. -# View xy is virtual (for GOP) -def Box moveto {x1 y1} { - netsend [list .$@canvas object_moveto $self $x1 $y1] - [$@canvas history] add [list $self moveto $@x1 $@y1] - if {[$self class] == "Canvas"} { - if {[$self gop] && ![winfo exists .$self.c]} {foreach x $@visibles {$x changed}} - } - set @x1 $x1 - set @y1 $y1 - $self changed - $self draw_wires -} - -def Box draw_io2 {which n color} { - for {set i 0} {$i<$n} {incr i} { - set points [$self io_bbox $which $i] - $self item [list $which$i $which] rectangle $points -outline $color -fill $color -width 1 - [[$self get_canvas] widget] raise $self$which$i - } -} - -def Box draw_io {} { - $self draw_io2 i $@ninlets [$self look inletfg] - $self draw_io2 o $@noutlets [$self look outletfg] -} - -def Box tips= {tips} {set @tips $tips} - -def Box tip {type port} { - if {[info exists @tips]} { - set tips $@tips - } else { - netsend [list .$@canvas object_get_tips $self] - #after 500 $self tip $type $port - set tips "" - } - switch $type { - i {return "inlet $port: [lindex $tips $port]"} - o {return "outlet $port"} - } -} - -# type is i or o -def Box hilite_io {type x y} { - mset {x1 y1 x2 y2} [$self bbox] - set xs [expr $x2-$x1] - set c [$@canvas widget] - switch $type {i {set ports $@ninlets} o {set ports $@noutlets}} - set port -1 - set iowidth [$self look iowidth] - - for {set n 0} {$n<$ports} {incr n} { - set tag $self$type$n - set area [lmap / [$c bbox $self$type$n] [$@canvas zoom]] - set center [expr ([lindex $area 2] + [lindex $area 0]) / 2 ] - set dist [expr abs($x - $center)] - if {$dist < [expr ($iowidth/2)+5] && $dist > 0} {set port $n} - } - - if {$ports==0 | $port==-1} return - if {$port >= $ports} {set port [expr $ports-1]} - $self hilite_io_2 $type $port - if {[$self look tooltip]} {$@canvas show_tooltip $x $y [$self tip $type $port] $type} - return $port -} - -def Box update_hilite_io {} { - if {![llength $@ioselect]} {return} - set type [lindex $@ioselect 1] - set zoom [$@canvas zoom] - set port [lindex $@ioselect 0] - set p $type$port - $self hilite_io_2 $type $port -} - -def Box hilite_io_2 {type port} { - set outline [switch $type {i {concat [$self look outletfg]} o {concat [$self look inletfg]}}] - set box [l+ [$self io_bbox $type $port] [list -3 -3 +3 +3]] - $self item $type${port}b rectangle $box -outline $outline -width 1 -} - -#def Box popup_help {} {netsend [list pd help $@pdclass]} -def Box popup_help {} {netsend [list .$@canvas object_help $self]} - -def Box show_error {text} { - regsub "\n" $text "" text - #mset {x1 y1 x2 y2} [$self bbox] - #[$self get_canvas] show_tooltip [expr $x2+4] [expr ($y1+$y2)/2] $text object 1 - mset {x1 y1 x2 y2} [$self bbox] - mset {x y} [rect_centre [$self io_bbox i 0]] - [$self get_canvas] show_tooltip $x $y $text i 1 -} - -def Canvas macro_event_append {e obj} { - if {![llength $@macro_q]} {after $@macro_delay [list $self macro_schedule $@macro_delay] $obj} - lappend @macro_q $e -} - -def Canvas get_clipboard {obj} { - puts "get clipboard" - set content [clipboard get] - set l {}; set s ""; set space " "; - set last_newline [string last ";" $content] - #foreach char [split $content ""] {lappend l [scan $char %c]} - set i 0 - foreach char [split $content ""] { - if {$i == $last_newline} {break} - #if {$char == ";"} {set s ${s}${space}list} {set s ${s}$char} - if {$char != ";"} { - if {$char == "\n"} { - set s ${s}${space}$char - } else { - set s ${s}$char - } - } - incr i - } - netsend [concat [list .$obj clipboard_set] $s] -} - - -def Canvas macro_schedule {delay obj} { - if {[llength $@macro_q]} { - set w [focus] - set m [lindex $@macro_q 0] - set fudge 0 - mset {event x y mode k} $m - switch $event { - key {set name [modekey $k $mode]; set fudge 1} - click {set name [modeclick $k $mode ButtonPress]; set fudge 1} - unclick {set name [modeclick $k $mode ButtonRelease]; set fudge 1} - bang { - after $delay [list $self macro_schedule $@macro_delay] $obj - netsend [list .$obj mbang] - set @macro_q [lreplace $@macro_q 0 0] - return - } - default {puts "Error: this event $event should not have been here.."} - } - if {$fudge} {event generate $w <Motion> -x $x -y $y} - event generate $w <$name> -x $x -y $y - #puts "event generate $w <$name> -x $x -y $y" - if {$event=="key"} {event generate $w <KeyRelease-$k> -x $x -y $y} - set @macro_q [lreplace $@macro_q 0 0] - after $delay [list $self macro_schedule $@macro_delay] $obj - } -} - -def Canvas foobar {} {$self macro_schedule 1000} - -def Canvas macro_q {} {puts "$@macro_q"} -#-----------------------------------------------------------------------------------# -class_new Wire {View} - -def Wire canvas= {c} { - super $c - mset {from outlet to inlet} $@connects - set children [$c objects] - set @from [$children get $from] - set @to [$children get $to] - $@from wires2+= $self; $@to wires2+= $self -} - -def Box index= {i} {super $i; if {$@canvas != ""} {[$@canvas objects] set $i $self}} -def Wire index= {i} {super $i; [$@canvas wires] set $i $self } - -def Wire init {mess} { - super - $self reinit $mess -} - -def Wire reinit {mess} { - if {[$::macro state]} {$::macro append_ref $mess} - mset {x msg from outlet to inlet canvas} $mess - set @connects [list $from $outlet $to $inlet] - set @outlet $outlet - set @inlet $inlet - $self outside_of_the_box -} - -def Wire from {} {return $@from} -def Wire outlet {} {return $@outlet} -def Wire to {} {return $@to} -def Wire inlet {} {return $@inlet} -def Wire move {dx dy} {$self changed} - -# DON'T do the former, it's so horribly slow -#def View draw_wires {} {foreach wire $_($@canvas:wires) {$wire changed}} -def View draw_wires {} {foreach wire $@wires2 {$wire changed}} - -def Wire bbox {} { - set from $@from; set outlet $@outlet - set to $@to; set inlet $@inlet - set zoom [$@canvas zoom] - set c [$@canvas widget] - mset {x1 y1} [lmap / [rect_centre [$c bbox ${from}o${outlet}]] $zoom] - mset {x2 y2} [lmap / [rect_centre [$c bbox ${to}i${inlet} ]] $zoom] - list $x1 $y1 $x2 $y2 -} - -def Wire xy {} { - mset {x1 y1 x2 y2} [$self bbox] - list [expr $x1 + (($x2-$x1)*0.05)] [expr $y1 + (($y2-$y1)*0.05)] -} - -def Wire report {} {list $@from $@outlet $@to $@inlet} -def Wire connects {} {return $@connects} -proc xys {x1 y1 x2 y2} { - return [list $x1 $y1 $x2 $y2] ;# just a straight line, no frills - set r {} - lappend r $x1 $y1 - set dx [expr $x2-$x1] - set dy [expr $y2-$y1] - set d [expr sqrt($dx*$dx+$dy*$dy)] - set n [expr 1+$d/10] - for {set i 1} {$i<$n} {incr i} { - set w $i*($n-$i)/(0.0+$n*$n) - lappend r [expr $x1 + $dx*$i/$n + $dy*(rand()-0.5)*$w] - lappend r [expr $y1 + $dy*$i/$n - $dx*(rand()-0.5)*$w] - } - lappend r $x2 $y2 - return $r -} - -def Wire draw {} { - set zoom [$@canvas zoom] - set c [$@canvas widget] - set iowidth [$@from look iowidth] - mset {ox1 oy1 ox2 oy2} [$@from io_bbox o $@outlet] - mset {ix1 iy1 ix2 iy2} [ $@to io_bbox i $@inlet] - set x1 [expr ($ox1+$ox2)/2.0]; set y1 $oy2 - set x2 [expr ($ix1+$ix2)/2.0]; set y2 $iy1 - set xys [xys $x1 $y1 $x2 $y2] - set length [expr sqrt(pow($x2-$x1,2)+pow($y2-$y1,2))] - # how to customise the arrow size/shape? - set arrowsize [expr $length<100 ? $length/10 : 10] - if {$arrowsize < 5} {set arrow none} {set arrow last} - set arrowshape [list $arrowsize [expr $arrowsize*4/5] [expr $arrowsize/3]] - set wire_width [$self look thick] - set wire_color [$self look fg] - if {[$self selected?]} { - set wire_color [$self look fg2] ;# fg2 should be renamed - } else { - if {[info exists _($@from:text)] && [info exists _($@to:text)]} { - if {[regexp -nocase {~$} [lindex $_($@from:text) 0]] && \ - [regexp -nocase {~$} [lindex $_($@to:text) 0]]} { - set wire_width [expr $wire_width*2] - } - } - } - set options {} - if {[$self look wirearrow]} {lappend options -arrow $arrow -arrowshape $arrowshape} - eval [concat [list $self item WIRE line $xys -width $wire_width -smooth yes -fill $wire_color] $options] -} - -def Wire delete {} { - $self unsubscribe $@canvas - $@from delete_wire $self - $@to delete_wire $self - [$@canvas wires] unset $@index - super -} - -def Wire popup_insert {} { - if {![llength [$@canvas selection_wire]]} {$@canvas selection_wire= $self} - mset {x y} [$@canvas insertxy] - $@canvas do_insert_obj $x $y -} - -#-----------------------------------------------------------------------------------# -############ colouring - -# equivalent to color* #c0c0c0 $c -proc darker {c} { - scan $c #%02x%02x%02x r g b - set r [expr $r*3/4] - set g [expr $g*3/4] - set b [expr $b*3/4] - return [format #%02x%02x%02x $r $g $b] -} - -proc brighter {c} { - scan $c #%02x%02x%02x r g b - set r [min 255 [expr $r*4/3]] - set g [min 255 [expr $g*4/3]] - set b [min 255 [expr $b*4/3]] - return [format #%02x%02x%02x $r $g $b] -} - -proc randomise_color {c} { - scan $c #%02x%02x%02x r g b - set r [clip [expr $r+int(rand()*65)-32] 0 255] - set g [clip [expr $g+int(rand()*65)-32] 0 255] - set b [clip [expr $b+int(rand()*65)-32] 0 255] - return [format #%02x%02x%02x $r $g $b] -} - -proc parse_color {c} { - regsub {;$} $c {} c - if {$c<0} { - set c [expr ~$c] - set r [expr round((($c>>12)&63)*255/63)] - set g [expr round((($c>> 6)&63)*255/63)] - set b [expr round((($c>> 0)&63)*255/63)] - return [format #%02x%02x%02x $r $g $b] - } {return #[lindex $::preset_colours2 $c]} -} - -proc unparse_color {c} { - if {[string index $c 0]=="#"} {set c [string replace $c 0 0 0x]} - set r [expr round((($c>>16)&255)*63/255)] - set g [expr round((($c>> 8)&255)*63/255)] - set b [expr round((($c>> 0)&255)*63/255)] - return [expr ~0[format %02o%02o%02o $r $g $b]] -} - -############ data transfer -# note: @pdclass is the server-side class name -# and @_class is the client-side class name - -# abstract classes -set fields1 {foo bar x1 y1 class} -set fields2 {snd rcv lab ldx ldy fstyle fs bcol fcol lcol} - -# real classes -set fields(tgl) [eval list $fields1 w isa $fields2 on nonzero] -set fields(bng) [eval list $fields1 w hold break isa $fields2] -set fields(nbx) [eval list $fields1 w h min max is_log isa $fields2 val log_height] -set fields(hsl) [eval list $fields1 w h min max is_log isa $fields2 val steady] -set fields(hradio) [eval list $fields1 w change isa n $fields2 on] -set fields(vu) [eval list $fields1 w h rcv lab ldx ldy fstyle fs bcol lcol scale isa] -set fields(cnv) [eval list $fields1 hh w h snd rcv lab ldx ldy fstyle fs bcol lcol isa] -set fields(vsl) $fields(hsl) -set fields(vradio) $fields(hradio) -set fields(hdl) $fields(hradio) -set fields(vdl) $fields(hradio) -set fields(coords) {foo bar xfrom yfrom xto yto w h gop x1 y1} ;# goes with #N canvas -set fields(floatatom) {foo bar x1 y1 w min max pos lab rcv snd} -set fields(symbolatom) {foo bar x1 y1 w min max pos lab rcv snd} -set fields(array) {name n elemtype flags} - -proc classinfo {pdclass _class} { - global classinfo classinfo2 - set classinfo($pdclass) $_class - set classinfo2($_class) $pdclass -} - -# basic patchables -classinfo obj ObjectBox -classinfo message MessageBox -classinfo floatatom FloatBox -classinfo symbolatom SymbolBox -classinfo text Comment - -# non-patchables (scalars, arrays, ...) -classinfo array Array - -# GUI patchables -classinfo bng Bang -classinfo tgl Toggle -classinfo nbx NumBox -classinfo hsl Slider -classinfo vsl Slider -classinfo vu Vu -classinfo hradio Radio -classinfo vradio Radio -classinfo hdl Radio -classinfo vdl Radio -classinfo canvas Canvas -classinfo cnv Cnv -classinfo display Display - -# remember, _($foo:$bar) notation should die -# because objects ought to be autonomous. - -# in array objects, number of inlets is bogus? -#X array array1 1 float 3; -#A 0 0; - -def View index= {i} {set @index $i} -def View index {} {return $@index} - -proc change {self canvas index e {ninlets 0} {noutlets 0} {valid 1}} { - foreach mess [pd_mess_split $e] {change_2 $self $mess} - #the server ought to take care of this: - #if {[lindex $e 1] == "array"} {set ninlets 0; set noutlets 0} - if {$canvas != "x0"} {$self canvas= $canvas} - $self index= $index - $self ninlets= $ninlets - $self noutlets= $noutlets - if {[$self class] == "ObjectBox"} {$self valid= $valid} - if {[$self class] == "Canvas"} { - if {[$self subpatch]} {$self valid= $valid} - if {[$self gop]} {$self valid= $valid} - if {[$self abs]} {$self valid= $valid} - } - $self changed -} - -proc change_2 {self mess} { - set isnew [expr ![info exists ::_($self:_class)]] - switch -- [lindex $mess 0] { - "#N" {if {$isnew} {Canvas new_as $self $mess} else {$self reinit $mess}} - "#X" { - set i 1 - # would it be possible to merge floatatom,symbolatom as gatom ? - switch -- [lindex $mess 1] { - obj {set class [lindex $mess 4]} - msg {set class message} - default {set class [lindex $mess 1]}} - if {[info exists ::classinfo($class)]} { - set _class [lindex $::classinfo($class) 0] - } else { - if {[lindex $mess 1] == "connect"} { - set _class Wire - } else { - set _class ObjectBox - } - } - if {$isnew} {$_class new_as $self $mess} else {$self reinit $mess} - switch -- $class { - floatatom {set class gatom} - symbolatom {set class gatom} - array {$self length= [lindex $mess 3]; $self name= [lindex $mess 2]} - default {$self position= [lrange $mess 2 3]}} - $self pdclass= $class - } - "#A" { - #post "#A: $mess" - $self array_set [lrange $mess 2 end] - } - "#V" { - #post "#V: $mess" - } - default {if {$mess != ""} {error "what you say? [lindex $mess 0] in $mess"}} - } -} - -#proc pasting_count {self} { -# global paste _ -# if {$paste(count2) != $paste(count)} {incr paste(count2)} -#} - -# split at message boundaries and atom boundaries, returning a list of lists of atoms. -# spaces get temporary value \x01 -# A_SEMI gets temporary value \x02 -# backslash gets temporary value \x03 -# A_COMMA is not handled yet -proc pd_mess_split {s} { - set s [regsub -all {\\\\} $s "\x03"] - set s [regsub -all {(^|[^\\]);} $s "\\1\x02"] - set s [regsub -all {(^|[^\\])[\s\n]+} $s "\\1\x01"] - set s [regsub -all {^\n} $s "\x01"] ;# oops - set s [regsub -all {\\([\\; \{\}])} $s "\\1\\2"] - set s [regsub -all \x03 $s \\] - set r {} - foreach m [split $s \x02] { - set m [regsub -all "\x01+" $m "\x01"] - set m [regsub -all "^\x01" $m ""] - set t [split $m \x01] - lappend r $t - } - return $r -} - -proc canonical_list {list} { - set r {} - foreach e $list {lappend r $e} - return $r -} - -proc pd_mess_split_want== {a b} { - set b [canonical_list $b] - set c [pd_mess_split $a] - if {[string compare $c $b]} { - puts "[VTred]string $a\nparses to $c\ninstead of $b[VTgrey]" - } else { - puts "[VTgreen]string $a OK[VTgrey]" - } -} - -if 0 { - pd_mess_split_want== {foo;bar;baz;a\;;b\\;c\\\;;d\\\\;e} {foo bar baz {{a;}} {b\\} {{c\;}} {{d\\}} e} - pd_mess_split_want== {foo\ bar} {{{foo bar}}} - pd_mess_split_want== {foo \ bar\ foo\ bar foo} {{foo { } {bar foo bar} foo}} - pd_mess_split_want== {\\ \\\\ \\\\\\ \ \\\ \\\\\ one} [list [list "\\" "\\\\" "\\\\\\" "\ \\\ \\\\\ one"]] - pd_mess_split_want== "\n \n \n foo" foo - pd_mess_split_want== "\\\x7b\\\x7b\\\x7b\\\x7b" [list [list "\x7b\x7b\x7b\x7b"]] - pd_mess_split_want== "\\\x7d\\\x7d\\\x7d\\\x7d" [list [list "\x7d\x7d\x7d\x7d"]] - exit -} - -############ rendering - -class_new MessageBox {TextBox} - -def MessageBox init {mess} { - super $mess - set @w 15 ;# this is useless? - set @xs $@w - set @ys $@w ;# this is a bug -} - -def MessageBox draw_box {} { - mset {x1 y1} [$self xy] - set x2 [expr $x1+$@xs] - set y2 [expr $y1+$@ys] - set points [list $x1 $y1 [expr $x2+4] $y1 $x2 [expr $y1+4] $x2 [expr $y2-4] [expr $x2+4] $y2 $x1 $y2 $x2 $y2 $x1 $y2] - if {[$self selected?]} {set frcol [$self look selectframe]} {set frcol [$self look frame3]} - $self item BASE polygon $points -fill [$self look bg] -outline $frcol -width 1 - [$@canvas widget] lower ${self}BASE ${self}TEXT - [$@canvas widget] raise $self -} - -def MessageBox draw {} { - super - $self draw_io -} - -def MessageBox click {x y f target} { - $self bang 1 - netsend [list .$self bang] - after 150 $self bang 0 -} - -def MessageBox bang {flag} { - if {$flag} {set color #ffff00} {set color [$self look bg]} - [$@canvas widget] itemconfigure ${self}BASE -fill $color -} - -# it was class_new AtomBox {View Box}, which is wrong because already Box<View -# it shouldn't have mattered, but super doesn't support proper pruning yet -#class_new AtomBox {Box} -class_new AtomBox {Labelled TextBox} -def AtomBox label_xy {} { - mset {x1 y1} [$self xy] - switch -- $@pos { - 0 {list [expr {$x1-3}] [expr {$y1+2}]} - 1 {list [expr {$x1+2}] [expr {$y1+2}]} - 2 {list [expr {$x1-1}] [expr {$y1-1}]} - 3 {list [expr {$x1-1}] [expr {$y1+3}]} - } -} -def AtomBox label_anchor {} { - switch -- $@pos { - 0 {return ne} - 1 {return nw} - 2 {return sw} - 3 {return nw} - } -} -def AtomBox label_font {} {list Courier 10 bold} -def AtomBox label_color {} {return -1} - -def AtomBox draw_box {} { - $self update_size - mset {x1 y1 x2 y2} [$self bbox] - set points [list $x1 $y1 [expr $x2-4] $y1 $x2 [expr $y1+4] $x2 $y2 $x1 $y2] - if {[$self selected?]} {set frcol [$self look selectframe]} {set frcol [$self look frame3]} - $self item BASE polygon $points -fill [$self look bg] -outline $frcol - [[$self get_canvas] widget] lower ${self}BASE ${self}TEXT - $self draw_io -} - -def AtomBox clear {var} {set @clear $var} -def AtomBox clear= {} {return $@clear} - -def AtomBox filter_text {{for_edit 0}} { - if {$for_edit} {return ""} - if {[string length $@text] <= $@w} {return $@text} - return [string range $@text 0 [expr $@w-1]] -} - -def AtomBox update_size {} { - set width [font measure [$self look font] 0] - set ls [font metrics [$self look font] -linespace] - set @xs [expr ($width*$@w)+3] - set @ys [expr $ls+3] -} - -class_new Comment {TextBox} - -def Comment draw_box {} { - super - mset {x1 y1} [$self xy] - set x2 [expr $x1+$@xs] - set y2 [expr $y1+$@ys] - set xya [list $x1 $y1 $x2 $y2] - set xyb [l+ [list $x2 $y1 $x1 $y1 $x1 $y2] [list -1 +1 +1 +1 +1 -1]] - set xyc [l+ [list $x2 $y1 $x2 $y2 $x1 $y2] [list -1 +1 -1 -1 +1 -1]] - if {[$@canvas editmode]} { - if {[$self selected?]} {set frcol [$self look selectframe]} {set frcol [$self look frame3]} - $self item BASE rectangle $xya -fill [$self look bg] -outline $frcol - } else { - $self item_delete BASE - } - #$self item BASE1 line $xyb -fill [$self look frame1] - #$self item BASE2 line $xyc -fill [$self look frame2] - if {[$@canvas editmode]} { - [$@canvas widget] lower ${self}BASE ${self}TEXT - #[$@canvas widget] raise ${self}BASE1 ${self}BASE - #[$@canvas widget] raise ${self}BASE2 ${self}BASE - } -} - -class_new Display {Box} - -def Display height= {val} {set @height $val} - -def Display init {{mess {}}} { - set font [$self look font] - set fw [font measure $font 0] - set @max_width 40; #in chars - set @wrap [expr $fw*$@max_width]; #in pixels - set @content {display} - set @height 1 - set @xs [expr [font measure [$self look font] 0]+3] - set @ys [font metrics [$self look font] -linespace] - set @textoffset [list 2 2] - netsend [list .$self height] - super $mess -} - -def Display draw {} { - super - set font [$self look font] - mset {x y} [$self xy] - mset {xf yf} $@textoffset - set fh [font metrics [$self look font] -linespace] - set text [lindex $@content 0]; - for {set i 1} {$i < $@height} {incr i} {set text ${text}\n[lindex $@content $i]} - set h 0; set w 0 - foreach line $@content { - set tw [font measure $font $line] - set h [expr int(ceil($tw/$@wrap.0)+$h)] - set w [min [max $w $tw] $@wrap] - } - set h [max $h 1] - $self item BASE rect [list $x $y [expr $x+$w+$xf+2] [expr $y+($@ys*$h)+$yf+1]] -fill [$self look bg] - $self item TEXT text [l+ $@textoffset [$self xy]] -font $font -text $text -fill [$self look fg] -anchor nw -width $@wrap - $self draw_io -} - -def Display dis {text} { - lappend @content $text - if {[llength $@content] > $@height} {set @content [lrange $@content 1 end]} - $self changed -} - -class_new IEMGUI {} -def IEMGUI text {} { - return [$self class] -} -class_new BlueBox {Labelled IEMGUI Box} -#class_new BlueBox {Box Labelled} - -def BlueBox draw_box {} { - super - set xya [$self bbox] - mset {x1 y1 x2 y2} $xya - set color [parse_color $@bcol] - if {[$self selected?]} {set frcol [$self look selectframe]} {set frcol [$self look frame3]} - $self item BASE rectangle $xya -fill $color -outline $frcol - #below lines draws the 3d box edge - #incr x1 +1; incr y1 +1; incr x2 -1; incr y2 -1 - #$self item BASE2 line [list $x2 $y1 $x1 $y1 $x1 $y2] -fill #ffffff - #$self item BASE3 line [list $x2 $y1 $x2 $y2 $x1 $y2] -fill [darker $color] - $self draw_io -} - -def IEMGUI popup_properties {} {IEMPropertiesDialogue new $self} - -class_new PropertiesDialogue {Dialogue} - -def PropertiesDialogue init {of} { - super cancel apply ok - set @of $of - set f .$self - checkbutton $f.auto_apply -text [say auto_apply] -anchor w -variable @auto_apply - frame $f.buttonsep2 -height 2 -borderwidth 1 -relief sunken - pack $f.auto_apply $f.buttonsep2 -side bottom -fill x - bind $f <KeyPress-Return> "break";#so that Return don't call do_auto_apply after Dialogue ok - #bind $f <KeyPress> [list $self do_auto_apply] ;# too wide: may cause Ok/Cancel to spit errors - #bind $f <ButtonRelease> [list $self do_auto_apply] ;# too wide: may cause Ok/Cancel to spit errors - $self non_resizable -} -class_new IEMPropertiesDialogue {PropertiesDialogue} - -def IEMGUI properties_apply {list {orient -1}} { - set orig [list $self properties_apply] - foreach var [lrange $::fields($@class) 5 end] {lappend orig $@$var} - [$@canvas history] add $orig - foreach v $list {switch -- $v {{} {set v "empty"}}; lappend props $v} - netsend [concat [list .$self reload] $props] - if {$orient >= 0} { - netsend [list .$self orient $orient] - } -} - -def IEMPropertiesDialogue apply {} { - set class $_($@of:class) - set props {} - foreach var [lrange $::fields($class) 5 end] { - set v $@$var - if {[regexp -nocase {^[bfl]col$} $var]} {set v [unparse_color $v]} - lappend props $v - } - if {[[$@of class] <= Slider] || [[$@of class] <= Radio]} { - $@of properties_apply $props $@orient - } else { - $@of properties_apply $props - } -} - -def IEMPropertiesDialogue init {of} { - super $of - set @class $_($of:class) - wm title .$self "\[$@class\] [say popup_properties]" - if {![info exists ::fields($@class)]} {set class obj} - foreach var $::fields($@class) { - set val $_($of:$var) - switch -- $val { empty {set val ""}} - if {[regexp -nocase {^([a-z])col$} $var]} {set val [parse_color $val]} - set @$var $val - } - if {[[$of class] <= Slider] || [[$of class] <= Radio]} { - set @orient $_($of:orient) - $self add .$self [list orient choice -choices {horizontal vertical}] - } - foreach prop [lrange $::fields($@class) 5 end] { - set d [concat [list $prop] [switch $prop { - w {list integer -width 7} - h {list integer -width 7} - hold {list float -width 9} - break {list float -width 9} - min {list float -width 9} - max {list float -width 9} - is_log {list choice -choices {linear logarithmic}} - isa {list choice -choices {no yes}} - n {list integer -width 4} - steady {list choice -choices {steady_no steady_yes}} - snd {list entry -width 20} - rcv {list entry -width 20} - lab {list entry -width 20} - ldx {list integer -width 5} - ldy {list integer -width 5} - fstyle {list choice -choices {Courier Helvetica Times}} - fs {list fontsize -width 5} - bcol {list color} - fcol {list color} - lcol {list color} - val {continue} - on {continue} - change {list choice -choices {no yes}} - nonzero {list float -width 9} - log_height {list float -width 9} - hh {continue} - scale {list toggle} - default {error "huh? ($prop)"} - }]] - $self add .$self $d - } -} - -def IEMPropertiesDialogue dropmenu_open {f name} {super $f} -def IEMPropertiesDialogue dropmenu_set {frame var part val} { - switch $var { - orient {if {[$@of class] == "Slider"} {set tmp $@h; set @h $@w; set @w $tmp}} - default {} - } - set tmp ${var}choices - set textvar ${var}2 - set @$textvar [say [lindex $@$tmp $val]] - super $frame $var $part $val - $self do_auto_apply -} - -class_new CanvasPropertiesDialogue {PropertiesDialogue} - -def CanvasPropertiesDialogue init {of} { - super $of - set @canvas $of - wm title .$self "[say canvas] [say popup_properties]" - set @gop [$of gop] - set @properties [list "gop" "xfrom" "xto" "yfrom" "yto" "width" "height" "xmargin" "ymargin"] - set mess [$of get_mess] - mset [list @xfrom @yfrom @xto @yto @width @height @xmargin @ymargin] $mess - if {!$@width} {set @width 85}; if {!$@height} {set @height 60} - $self add .$self [list gop toggle -command "$self gop_setting"] - for {set i 1} {$i<[llength $@properties]} {incr i} { - $self add .$self [list [lindex $@properties $i] integer -width 7] - } - $self gop_setting -} - -def CanvasPropertiesDialogue gop_setting {} { - set entries [lrange $@properties 1 end] - foreach entry $entries { - if {!$@gop} { - .$self.$entry.entry configure -state disable - } else { - .$self.$entry.entry configure -state normal - } - } -} - -def CanvasPropertiesDialogue apply {} { - if {![$@canvas editmode]} {$@canvas editmode= 1} - netsend [list .$@of coords $@xfrom $@yfrom $@xto $@yto $@width $@height $@gop $@xmargin $@ymargin] -} - -proc gatom_escape {sym} { - if {[string length $sym] == 0} {return "-"} - if {[string equal -length 1 $sym "-"]} {return [string replace $sym 0 0 "--"]} - return $sym -} - -proc gatom_unescape {sym} { - if {[string equal -length 1 $sym "-"]} {return [string replace $sym 0 0 ""]} - return $sym -} - -class_new BoxPropertiesDialogue {PropertiesDialogue} -def Box popup_properties {} {BoxPropertiesDialogue new $self} -def Box popup_clear_wires {} {[$self canvas] selection= $self; [$self canvas] clear_wires} -def Box popup_remove_from_path {} {[$self canvas] selection= $self; [$self canvas] remove_obj_from_path} -def Box popup_delete_from_path {} {[$self canvas] selection= $self; [$self canvas] delete_obj_from_path} -def BoxPropertiesDialogue init {of} { - super $of - wm title .$self "Box Properties" - pack [label .$self.huh -text "huh..."] - pack [label .$self.huh2 -text "this is where some #V properties should go"] -} - -class_new WirePropertiesDialogue {PropertiesDialogue} -def Wire popup_properties {} {WirePropertiesDialogue new $self} -def WirePropertiesDialogue init {of} { - super $of - wm title .$self "Wire Properties" - pack [label .$self.huh -text "huh..."] - pack [label .$self.huh2 -text "this is where some #V properties should go"] -} - -class_new GAtomPropertiesDialogue {PropertiesDialogue} - -def AtomBox popup_properties {} {GAtomPropertiesDialogue new $self} - -# this is buggy due to miller's escapes vs iem's escapes. -def GAtomPropertiesDialogue apply {} { - netsend [list .$@of reload $@w $@min $@max $@pos [gatom_escape $@lab] [gatom_escape $@rcv] [gatom_escape $@snd]] -} - -def GAtomPropertiesDialogue init {of} { - super $of - foreach var {w min max pos} {set @$var $_($of:$var)} - foreach var {lab rcv snd} {set @$var [gatom_unescape $_($of:$var)]} - wm title .$self "Atom" - global properties - $self add .$self \ - {w integer -width 4} \ - {min float -width 8} \ - {max float -width 8} \ - {lab symbol -width 20} \ - {pos side } \ - {snd symbol -width 20} \ - {rcv symbol -width 20} - #foreach name {w min max} {bind .$self.$name.entry <KeyPress-Return> "$self ok"} - .$self.w.entry select from 0 - .$self.w.entry select adjust end - focus .$self.w.entry -} - -class_new GraphPropertiesDialogue {Dialogue} - -def GraphPropertiesDialogue apply {} { - netsend [list .$@of dialog $@x1 $@y1 $@x2 $@y2 $@xpix $@ypix] -} - -def GraphPropertiesDialogue init {of} { - super $of - foreach var {x1 y1 x2 y2 xpix ypix} {set @$var $_($of:$var)} - wm title .$self "Graph" - pack [label .$self.label -text "GRAPH BOUNDS"] -side top - global properties - $self add .$self { - {x1 integer -width 7} \ - {x2 integer -width 7} \ - {xpix entry -width 7} \ - {y2 integer -width 7} \ - {y1 integer -width 7} \ - {ypix entry -width 7} - } - #.$self.xrangef.x2 select from 0 - #.$self.xrangef.x2 select adjust end - #focus .$self.xrangef.x2 -} - -class_new ArrayPropertiesDialogue {Dialogue} - -def ArrayPropertiesDialogue apply {} { - regsub {^\$} $@name "#" name - netsend [list .$@apply arraydialog $name $@n $@saveit $@otherflag] -} - -def ArrayPropertiesDialogue init {of} { - super $of - foreach var {name n saveit} {set @$var $_($of:$var)} - set @otherflag 0 - wm title $id "[say array] [say popup_properties]" - $self add .$self {name entry} {n entry} - pack [checkbutton .$self.saveme -text "save contents" -variable @saveit -anchor w] -side top - if {$newone} { - pack [frame .$self.radio] -side top - foreach {i label} {0 "in new graph" 1 "in last graph"} { - pack [radiobutton .$self.radio.radio$i -value $i -variable @otherflag -text $label] -side top -anchor w - } - } else { - pack [checkbutton .$self.deleteme -text "delete me" -variable @otherflag -anchor w] -side top - } - if {$newone} {.$self.buttonframe.apply configure -state disabled} - bind .$self.name.entry <KeyPress-Return> "$self ok" - bind .$self.n.entry <KeyPress-Return> "$self ok" - .$self.name.entry select from 0 - .$self.name.entry select adjust end - focus .$self.name.entry -} - -class_new FloatBox {AtomBox} -class_new SymbolBox {AtomBox} - -def AtomBox init {mess} { - super $mess - set @clickpos {} - set width [font measure [$self look font] W] - set height [font metrics [$self look font] -linespace] - set @xs [expr ($width*$@w)+3] - set @ys [expr $height+3] -} - -def FloatBox init {mess} {super $mess; set @text 0;} - -def FloatBox calc {x y x1 y1} { - #puts "$@min $@max" - if {!$@min && !$@max} { - set d [expr $@ovalue+($y1-$y)*$@rate] - } else { - set span [expr $@max-$@min] - set l [expr $@max-$@min] - set d [clip [expr $@ovalue+(($y1-$y)*$span/($l+0.0))*$@rate] $@min $@max] - } - return $d -} - -def SymbolBox init {mess} {super $mess; set @text "symbol"} - -def AtomBox set {val} {set @text [format "%g" $val]; $self changed} - -def AtomBox setto {text} { - [$@canvas widget] configure -cursor {} - if { [string is double $text]} { - set @text $text; #so that the text gets updated immediately - netsend [list .$self float $text] - #[$self get_canvas] selection-= $self - } -} -def SymbolBox set {text} {set @text $text} -def SymbolBox setto {text} { - [$@canvas widget] configure -cursor {} - if {![string is double $text]} {netsend [list .$self symbol $text]} -} - -def FloatBox ftoa {} { - set f $@val - set is_exp 0 - if {[string length $@buf]>0} {return $@buf} - set buf [format %g $f] - set bufsize [string length buf] - if {$bufsize >= 5} { - # exponential mode - set is_exp [regexp -nocase e] - } - if {$bufsize > $@w} { - # must shrink number - if {$is_exp} { - #... - } { - #... - } - } - return $buf -} - -def AtomBox click {x y f target} { - set @clickx $x; set @clicky $y - set canvas [$self get_canvas] - set t [$canvas widget].${self}text - set @ovalue [clip $@text $@min $@max] - set @clickpos [list $x $y] - set @mouse [list $x $y] - $canvas focus= $self - set @rate [expr $f&1 ? 0.01 : 1.00] -} - -def AtomBox unclick {x y f target} { - if {$x == $@clickx && $y == $@clicky} {$self edit} - [$self get_canvas] focus= "" -} - -def AtomBox motion {x y f target} { - if {$@edit} {return} - mset {clx cly} $@clickpos - set @text [$self calc $x $y $clx $cly] - netsend [list .$self float [expr {0+$@text}]] -} - -def AtomBox log_ratio {} { - set diff [expr $@is_log ? log($@max/$@min) : ($@max-$@min)] - return [expr $diff / $@max] -} - -def AtomBox key_incr {val1 val2} { - set @text [expr $@text - $val2] - netsend [list .$self float [expr {0+$@text}]] -} - -def SymbolBox motion {x y f target} {} -class_new NumBox {Labelled IEMGUI AtomBox} - -def NumBox init {mess} { - super $mess - set @clicking 0 - set changed 0 - set @buf "" - set @text [clip 0 $@min $@max] -} -def NumBox calc {x y x1 y1} { - set span [expr $@max-$@min] - set l [expr $@is_log ? $@log_height : ($@max-$@min)] - set d [expr {($y1-$y)*$span/($l+0.0)}] - set d [expr $@is_log ? $@ovalue*exp($d*$@rate*[$self log_ratio]) : $@ovalue+$d*$@rate] - set d [clip $d $@min $@max] - return $d -} -def NumBox reinit {mess} { - super $mess - set @text $@val -} -def NumBox draw {} { - super - mset {x1 y1} [$self xy] - set xs [expr 4+10*$@w] - set ys $@h - set x2 [expr $x1+$xs] - set y2 [expr $y1+$ys] - set c [[$self get_canvas] widget] - set points [list $x1 $y1 [expr $x2-4] $y1 $x2 [expr $y1+4] $x2 $y2 $x1 $y2] - set xt [expr $x1+$ys/2+2] - set yt [expr $y1+$ys/2+1+$xs/34] - set points2 [list $x1 $y1 [expr $x1+$ys/2] [expr $y1+$ys/2] $x1 $y2] - set focused [$self == [$@canvas focus]] - if {$focused} {set color4 #00ff00} {set color4 [$self look bg]} - $self item BASE4 polygon $points2 -outline [$self look frame3] -fill $color4 - $c raise ${self}BASE4 -} -def NumBox ftoa {} { - set f $@text - set is_exp 0 - if {[string length $@buf]>0} {return $@buf} - set buf [format %g $f] - set bufsize [string length buf] - if {$bufsize >= 5} { - # exponential mode - set is_exp [regexp -nocase e] - } - if {$bufsize > $@w} { - # must shrink number - if {$is_exp} { - #... - } { - #... - } - } - return $buf -} -def NumBox unfocus {} {set @buf ""; $self changed} - -class_new Radio {BlueBox} -def Radio reinit {mess} { - super $mess - switch [lindex $mess 4] { - hradio {set @orient 0} hdl {set @orient 0} - vradio {set @orient 1} vdl {set @orient 1} - default {set @orient 0} - } -} -def Radio bbox {} { - mset {x1 y1} [$self xy] - set x2 [expr {$x1+$@w*($@orient ?1:$@n)}] - set y2 [expr {$y1+$@w*($@orient ?$@n:1)}] - list $x1 $y1 $x2 $y2 -} -def Radio draw {} { - mset {x1 y1 x2 y2} [$self bbox] - super - $self item_delete BUT ;# would be cool if this didn't delete stuff that we're about to redraw. - for {set i 0} {$i<$@n} {incr i} { - #set coords [list [expr {$x1+3}] [expr {$y1+3}] [expr {$x1+$@w-3}] [expr {$y1+$@w-3}]] - set coords [list $x1 $y1 [expr {$x1+$@w}] [expr {$y1+$@w}]] - $self item [list BUT$i BUT] rectangle $coords -fill [parse_color $@bcol] -outline [parse_color $@fcol] - if {$@orient} {set y1 [expr {$y1+$@w}]} {set x1 [expr {$x1+$@w}]} - } - $self set $@on -} -def Radio set {value} { - set c [$self get_canvas] - mset {x1 y1} [$self xy] - set value [expr round($value)] - if {$@orient} {set y1 [expr $y1+$@w*$value]} {set x1 [expr $x1+$@w*$value]} - set coords [list [expr {$x1+3}] [expr {$y1+3}] [expr {$x1+$@w-2}] [expr {$y1+$@w-2}]] - puts "coords=$coords" - $self item [list CHECK BUT] rectangle $coords -fill [parse_color $@fcol] -width 0 -} -def Radio click {x y f target} { - mset {x1 y1} [$self xy] - set i [expr {int($@orient ?$y-$y1-2:$x-$x1-2)/$@w}] - netsend [list .$self fout $i] -} -def Radio key_incr {val1 val2} {netsend [list .$self fout [expr {$@on-$val2}]]} - -# in sliders, @value is the kind of value that goes thru inlets and outlets -# whereas @val is always measured in "centipixels" (unzoomed). -class_new Slider {BlueBox} -def Slider reinit {mess} { - super $mess - switch [lindex $mess 4] { - hsl {set @orient 0} - vsl {set @orient 1} - } - $self update_value -} -def Slider update_value {} { - set span [expr {$@max-$@min}] - set l [expr $@orient ?$@h:$@w] - set @value [expr $@val*$span/($l-1)/100] - #set t [expr $@val * [$self slider_ratio] * 0.01] - #set @value [expr $@min*exp($t)] -} -def Slider init {mess} { - super $mess - set @oposition $@min - $self update_value -} -def Slider bbox {} { - mset {x1 y1} [$self xy] - if {!$@orient} { - list [expr {$x1-3}] $y1 [expr {$x1+$@w+2}] [expr {$y1+$@h}] - } else { - list $x1 [expr {$y1-2}] [expr {$x1+$@w}] [expr {$y1+$@h+3}] - } -} -#the value/centipixel ratio -def Slider slider_ratio {} { - set diff [expr $@is_log ? log($@max/$@min) : ($@max-$@min)] - return [expr $diff / ($@orient ? ($@h-1) : ($@w-1))] -} -def Slider draw_knob {} { - mset {x1 y1} [$self xy] - set l [expr $@orient ?$@h:$@w] - set span [expr {$@max-$@min}] - set scaled [expr {$@value*($l-1)/$span}] - if {$@orient} { - set y1 [expr $y1+2] - set y [expr $y1+$@h-$scaled-2] - set coords [list [expr {$x1+2}] [expr {$y-1}] [expr {$x1+$@w-2}] [expr {$y+1}]] - } else { - set x1 [expr $x1-1] - set x [expr $x1+$scaled] - set coords [list $x [expr {$y1+2}] [expr {$x+2}] [expr {$y1+$@h-2}]] - } - $self item KNOB rectangle $coords -outline red -fill [darker [$self look bg]] -} -def Slider draw {} { - mset {x1 y1 x2 y2} [$self bbox] - #if {$@orient} {set y1 [expr $y1-2]} {set x1 [expr $x1-2]} - #if {$@orient} {set ys [expr $@h+5]} {set xs [expr $@w+5]} - super - $self draw_knob - $self update_value -} -# not used -def Slider draw_notches {} { - if {$@orient} { - set thick [clip [expr $xs/3] 1 5] - set x3 [expr $x1+$xs-$thick/2-2] - set eighth [expr round($ys/8-1)] - set coords [list $x3 $y1 $x3 [expr $y1+$ys]] - } else { - set thick [clip [expr $ys/3] 1 5] - set y3 [expr $y1+$ys-$thick/2-2] - set eighth [expr $xs/8] - set coords [list $x1 $y3 [expr $x1+$xs] $y3] - } - # there were supposed to be 7 notches... i don't remember what happened here. - $@canvas item NOTCH $coords -dash [list 1 $eighth 1 $eighth] -width $thick -fill [darker [$self look bg]] -} -def Slider click {x y f target} { - set canvas [$self get_canvas] - mset {type id detail} [$canvas identify_target $x $y $f] - if {$type == "label"} {return} - $canvas focus= $self - set @click_at [list $x $y] - set @rate [expr $f&1 ? 0.01 : 1.00] - if {!$@steady} { - mset {x1 y1 x2 y2} [$self bbox] - set t [expr [$self calc $x $y $x1 $y2]*$@rate] - set @value [expr $@is_log ? [expr $@min*exp($t*[$self slider_ratio])] : $t] - set @oposition $t - netsend [list .$self float $@value] - } else {set @oposition $@value} -} -def Slider unclick {x y f target} { - ### keep focus if only clicked. do we want that feature? - # if {[distance $@click_at [list $x $y]] == 0} {return} - set canvas [$self get_canvas] - $canvas focus= "" -} -def Slider motion {x y f target} { - set canvas [$self get_canvas] - set focused [$self == [$canvas focus]] - if {!$focused} {return} - mset {clx cly} $@click_at - set d [$self calc $x $y $clx $cly] - set t ($@oposition+$d*$@rate) - set value [expr $@is_log ? [expr $@min*exp($t*[$self slider_ratio])] : $t] - set out [clip $value $@min $@max] - netsend [list .$self float $out] -} -def Slider key_incr {val1 val2} { - set @value [expr {$@value-$val2}] - netsend [list .$self float $@value] -} -def Slider calc {x y x1 y1} { - set span [expr {$@max-$@min}] - set l [expr {$@orient ?$@h:$@w}] - set d [expr {($@orient ?$y1-$y:$x-$x1)*$span/($l+0.0)}] - return $d -} -def Slider unfocus {} {$self draw} - -class_new Labelled {} -def Labelled draw {} { - super - mset {lx ly} [$self label_xy] - set label $@lab; switch -- $label {empty {set label ""} - {set label ""}} - set lfont [$self label_font] - set lcolor [parse_color [$self label_color]] - if {$::leet} { - set text [string map -nocase {a 4 e 3 t 7 s 5 i 1 o 0 g 9} $label] - } else { - set text $label - } - $self item LABEL text [list $lx $ly] -text $text -anchor [$self label_anchor] -font $lfont -fill $lcolor -} -def Labelled label_xy {} {mset {x1 y1} [$self xy]; list [expr {$x1+$@ldx}] [expr {$y1+$@ldy}]} -def Labelled label_anchor {} {return w} -def Labelled label_font {} {list [lindex {courier helvetica times} $@fstyle] $@fs bold} -def Labelled label_color {} {return $@lcol} - -#-----------------------------------------------------------------------------------# -class_new Bang {BlueBox} -def Bang init {mess} { - super $mess - set @flash 0 - set @count 0 -} -def Bang bbox {} { - mset {x1 y1} [$self xy] - list $x1 $y1 [expr {$x1+$@w}] [expr {$y1+$@w}] -} -def Bang draw {} { - super - mset {x1 y1 x2 y2} [$self bbox] - set rect [list [expr {$x1+1}] [expr {$y1+1}] [expr {$x2-1}] [expr {$y2-1}]] - if {$@flash} { - #$self item BUT oval $rect -fill [parse_color $@fcol] - set fcol [] - set bcol [] - $self item BUT oval $rect -fill $fcol - after 100 [list $self item BUT oval $rect -fill $bcol] - set @flash 0 - } else { - set colour [parse_color $@bcol] - $self item BUT oval $rect -fill $colour -outline [$self look frame3] - } -} -def Bang unclick {x y f target} {} -def Bang click {x y f target} {netsend [list .$self bang]} -def Bang bang {count} {set @count $count; set @flash 1} -def Bang key_incr {val1 val2} {netsend [list .$self bang]} - -class_new Toggle {BlueBox} -def Toggle bbox {} { - mset {x1 y1} [$self xy] - list $x1 $y1 [expr $x1+$@w] [expr $y1+$@w] -} -def Toggle draw {} { - super - mset {x1 y1 x2 y2} [$self bbox] - set colour [parse_color $@bcol] - set t [expr {int(($@w+29)/30)}] - set fill $colour - set x3 [expr {$x1+$t+2}]; set y3 [expr {$y1+$t+2}] - set x4 [expr {$x2-$t-2}]; set y4 [expr {$y2-$t-2}] - if {$@on} { - set fill [parse_color $@fcol] - } { - set fill [parse_color $@bcol] - } - $self item X1 line [list $x3 $y3 [expr {$x4+1}] [expr {$y4+1}]] -width $t -fill $fill - $self item X2 line [list $x3 $y4 [expr {$x4+1}] [expr {$y3-1}]] -width $t -fill $fill -} -def Toggle unclick {x y f target} {} -def Toggle click {x y f target} { - if {!$@on} {set @on 1} {set @on 0} - netsend [list .$self float $@on] - $self changed -} - -class_new Vu {Labelled IEMGUI Box} -set vu_col { - 0 17 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 - 15 15 15 15 15 15 15 15 15 15 14 14 13 13 13 13 13 13 13 13 13 13 13 19 19 19 -} -def Vu init {mess} { - super $mess - set @value 0 - set @peak 0 -} -def Vu bbox {} { - mset {x1 y1} [$self xy] - list $x1 $y1 [expr $x1+$@w] [expr $y1+$@h] -} -def Vu led_size {} { - set n [expr $@h/40] - if {$n < 2} {set n 2} - return [expr $n-1] -} -def Vu draw {} { - global vu_col - mset {x1 y1 x2 y2} [$self bbox] - set colour [parse_color $@bcol] - super - $self draw_io - set led_size [$self led_size] - set x3 [expr $x1+$@w/4] - set x4 [expr $x2-$@w/4] - $self item BASE rectangle [list $x1 $y1 $x2 $y2] -width 0 -fill $colour - for {set i 1} {$i<=40} {incr i} { - set y [expr $y1 + ($led_size+1)*(41-$i) - ($led_size+1)/2] - $self item RMS${i} rectangle [list $x3 $y $x4 [expr $y+$led_size]] \ - -fill [parse_color [lindex $vu_col $i]] -width 0 - } - #if {!$@zoom} {return} - set lfont [list [lindex {courier helvetica times} $@fstyle] $@fs bold] - set lcolor [parse_color $@lcol] - set i 0 - foreach level { <-99 -50 -30 -20 -12 -6 -2 -0dB +2 +6 >+12 } { - set k1 [expr $led_size+1] - set k2 41 - set k3 [expr $k1/2] - set k4 [expr $y1-$k3] - set yyy [expr $k4 + $k1*($k2-4*$i)] - $self item SCALE{$level} text [list [expr $x2+4] [expr $yyy+$k3-3]] \ - -text $level -anchor w -font $lfont -fill $lcolor - incr i - } - set y [expr $y1 + ($led_size+1)*(41-$@value) - ($led_size+1)/2] - $self item MASK rectangle [list $x3 $y1 $x4 $y] -width 0 -fill $colour - set c [lindex $vu_col [expr int($@peak)]] - set y [expr $y1 + ($led_size+1)*(41-$@peak) - ($led_size+1)/2] - $self item PEAK rectangle [list $x1 $y $x2 [expr $y+$led_size]] -fill [parse_color $c] -width 0 -} -def Vu rms= {rms } {set @value $rms; $self changed rms} -def Vu peak= {peak} {set @peak $peak; $self changed peak} -def Vu set {i j} { - set @value $i - set @peak $j - $self changed -} - -if {![catch { - package require tkdnd - dnd bindtarget . text/uri-list <Drop> {open_file %D} -}]} { - puts "warning: tkdnd package not found" -} - -class_new Cnv {Labelled IEMGUI Box} -def Cnv draw {} { - mset {x1 y1} [$self xy] - $self item BASE rectangle [list $x1 $y1 [expr {$x1+$@w+1}] [expr {$y1+$@h+1}]] -fill [parse_color $@bcol] -width 0 - super -} -def Cnv bbox {} { - mset {x1 y1} [$self xy] - return [list $x1 $y1 [expr $x1+$@w] [expr $y1+$@h]] -} - -class_new Array {Box} -def Array init {mess} { - super $mess - set @name [lindex $mess 2] - set @length 0 - set @data {} - set @draw 0 -} -def Array bbox {} { - return {0 0 1 1} ;# huh? -} -def Array draw_name {} { - mset {x_off y_off} [$@canvas xy] - $self item TEXT text [lmap + [list $x_off $y_off] 2] \ - -font [View_look $self font] -text $@name \ - -fill [View_look $self fg] -anchor nw -} -def Array draw {} { - $self draw_name - mset {x_off y_off} [$@canvas xy] - set m [$@canvas get_mess] - mset {xfrom yto xto yfrom pixwidth pixheight} $m - if {[winfo exists [$@canvas widget]]} { - mset {c_width c_height} [$@canvas get_dimen] - set width [expr $c_width / $@length] - set i 0 - foreach val $@data { - if {!$val} {set val 0.0} - set y [expr $c_height - (((double($val)+abs($yfrom))/($yto-$yfrom) * $c_height))] - set x1 [expr $width * $i] - set x2 [expr $x1 + $width] - set line [list $x1 $y $x2 $y] - $self item elem${i} line $line -fill [$@canvas look compfg] -width 2 -tags "$self ${self}elem${i}" - #.$self.c raise ${self}elem${i} - incr i - } - } else { - set width [expr $pixwidth / $@length] - set canvas [$self get_canvas] - set i 0 - foreach val $@data { - if {!$val} {set val 0.0} - #set val2 [lindex $@data [expr $i+1]] - set y [expr ($pixheight - ((double($val)+abs($yfrom))/($yto-$yfrom) * $pixheight)) + $y_off] - #set y2 [expr ($pixheight - ((double($val2)+abs($yfrom))/($yto-$yfrom) * $pixheight)) + $y_off] - set x1 [expr ($width * $i) + $x_off] - set x2 [expr $x1 + $width] - set line [list $x1 $y $x2 $y] - $self item ${self}ELEM${i} line $line -fill [$self look fg] -width 2 - incr i - } - [$canvas widget] raise $self - #set width [expr $pixwidth / [expr $@length-1]] - #set canvas [$self get_canvas] - #set i 0 - #for {set i 0} {$i < [expr $@length-1]} {incr i} { - # #if {!$val} {set val 0.0} - # set val [lindex $@data [expr $i]] - # set val2 [lindex $@data [expr $i+1]] - # set y [expr ($pixheight - ((double($val)+abs($yfrom))/($yto-$yfrom) * $pixheight)) + $y_off] - # set y2 [expr ($pixheight - ((double($val2)+abs($yfrom))/($yto-$yfrom) * $pixheight)) + $y_off] - # set x1 [expr ($width * $i) + $x_off] - # set x2 [expr $x1 + $width] - # set line [list $x1 $y $x2 $y2] - # $self item ${self}ELEM${i} line $line -fill [$self look fg] -width 0 - #} - } -} -def Array click {x y f target} { - if {[winfo exists [$@canvas widget]]} {set canvas $@canvas} else {set canvas [$@canvas canvas]} - $canvas focus= $self - set @draw 1 -} -def Array unclick {x y f target} { - if {[winfo exists [$@canvas widget]]} {set canvas $@canvas} else {set canvas [$@canvas canvas]} - $canvas focus= "" - set @draw 0 -} -def Array motion {x y f target} { - if {!$@draw} return - if {[winfo exists [$@canvas widget]]} { - mset {c_width c_height} [$@canvas get_dimen] - mset {xfrom yto xto yfrom pixwidth pixheight} [$@canvas get_mess] - set width [expr $c_width / $@length] - set i [format %d [expr int($x/$width)]] - set x1 [expr $width * $i] - set x2 [expr $x1 + $width] - set line [list $x1 $y $x2 $y] - set val [expr (($c_height-$y)/$c_height) * ($yto-$yfrom) + $yfrom] - netsend [list .$self $i $val] - } else { - mset {xfrom yto xto yfrom pixwidth pixheight} [$@canvas get_mess] - mset {x_off y_off} [$@canvas xy] - set width [expr $pixwidth / $@length] - set i [format %d [expr int(($x-$x_off)/$width)]] - set val [expr (($pixheight-$y+$y_off)/$pixheight) * ($yto-$yfrom) + $yfrom] - netsend [list .$self $i $val] - } -} -def Array length= {val} {set @length [format %f $val]} -def Array name= {val} {set @name $val} -def Array array_set {data_list} { - if {[llength $data_list] == $@length} { - set @data {} - for {set i 0} {$i < $@length} {incr i} { - lappend @data [lindex $data_list $i] - } - } else { - puts "error..." - } -} - -############ evaluator - -class_new Listener {Thing} -def Listener init {serf name command} { - set @history [History new 20] - set @command $command - set @expanded 0 - set @serf $serf - set font $::look(View:font) - frame $serf - pack [frame $serf.1] -side left -fill y - pack [frame $serf.1.1] -side bottom - pack [button $serf.1.1.expander -image icon_plus -command "$self toggle_expand"] -side left - pack [label $serf.1.1.label -width 11 -font $font -text "$name: "] -side left - pack [entry $serf.entry -width 40 -font $font] -side left -fill x -expand yes - pack $serf -fill x -expand no - bind $serf.entry <Up> "$self scroll_history +1" - bind $serf.entry <Down> "$self scroll_history -1" - bind $serf.entry <Return> "$self eval" -} -def Listener toggle_expand {} { - set @expanded [expr 1-$@expanded] - if {$@expanded} {$self expand} {$self unexpand} -} -def Listener expand {} { - set e $@serf.entry - set text [$e get] - destroy $e - pack [text $e -width 40 -height 8] -side left -fill x -expand yes - $e insert 0.0 $text - $@serf.1.1.expander configure -image icon_minus - bind $e <Alt-Return> "$self eval" -} -def Listener unexpand {} { - set e $@serf.entry - set text [$e get 0.0 end] - regsub "\n$" $text "" text - destroy $e - pack [entry $e -width 40] -side left -fill x -expand yes - $e insert 0 $text - $@serf.1.1.expander configure -image icon_plus - bind $e <Up> "$self up" - bind $e <Down> "$self down" - bind $e <Return> "$self eval" -} -def Listener replace {stuff} { - $@serf.entry delete 0 end - $@serf.entry insert 0 $stuff - $@serf.entry icursor end -} -def Listener scroll_history {incr} { - if {![$@history histi]} {$@history set_hist 0 [$self get_command]} - $self replace [$@history traverse $incr] - -} -def Listener append {v} { - $@history prepend $v - lappend @hist $v; set @histi [llength $@hist] -} -def Listener get_command {} { - set e $@serf.entry - if {$@expanded} { - set l [$e get 0.0 end]; return $l - } else { - set l [$e get]; return $l - } - -} -def Listener eval {} { - set e $@serf.entry - $@history histi= 0 - set l [$self get_command] - $self append $l - if {$@expanded} {$e delete 0.0 end} {$e delete 0 end} - $@command $self $l -} - -proc tcl_eval {self l} {post %s "tcl: $l"; post %s "returns: [uplevel [info level] $l]"} -proc pd_eval {self l} {post %s "pd: $l"; netsend $l} -proc canvas_eval {self l} {post %s "tcl: $l"; post %s "returns: [uplevel [info level] [join [list [$self canvas] $l]]]"} -############ button bar - -set butt { - {ObjectBox Object {obj}} - {MessageBox Message {msg}} - {FloatBox Number {floatatom}} - {SymbolBox Symbol {symbolatom}} - {CommentBox Comment {text}} - {bng bng {obj bng}} - {tgl tgl {obj tgl}} - {nbx nbx {obj nbx}} - {vsl vsl {obj vsl}} - {hsl hsl {obj hsl}} - {vradio vradio {obj vradio}} - {hradio hradio {obj hradio}} - {vu vu {obj vu}} - {cnv cnv {obj cnv}} - {Graph graph {graph}} - {Array array {menuarray 0}} -} - -proc button_bar_add {x y} {lappend ::butt [list $x $y noload]} -if {$tk} { - set dir $cmdline(icons) - foreach icon {mode_edit mode_run pd_32} {image create photo icon_$icon -file $dir/$icon.gif} - foreach b $butt {mset {icon name cmd} $b; image create photo icon_$icon -file $dir/$icon.gif} -} -class_new ButtonBar {View} -def ButtonBar init {canvas} { - set @canvas $canvas - set bb .$@canvas.bbar - frame $bb - pack [button $bb.edit -image icon_mode_edit -border 1 -command [list $@canvas editmodeswitch]] -side left - foreach e $::butt { - mset {icon name cmd} $e - pack [button $bb._$name -image icon_$icon -border 1 -command "$@canvas new_object $cmd"] -side left - balloon $bb._$name [say $name] - } - pack [entry $bb.name -font {helvetica -12} -width 8 -border 0] -side right - pack [spinbox $bb.scale -width 5 -command "$canvas zooming %d" -state readonly] -side right - $bb.scale set [format %d%% [expr int(100*[$@canvas zoom])]] - $bb.name insert 0 $@canvas -} -def ButtonBar widget {} {return .$@canvas.bbar} -proc obj_create {c flag} {} - -############ crosshair - -class_new Crosshair {View} -def Crosshair classtags {} {return {}} -def Crosshair init {canvas} { - super - set @canvas $canvas - $self data= 0 0 {none} -} -def Crosshair data= {x y target} { - set @x $x - set @y $y - set @target $target -} -def Crosshair draw {} { - mset {type id detail} $@target - set x $@x; set y $@y - if {[$@canvas look hairsnap]} { - switch -regexp -- $type {^object|outlet|inlet$ {mset {x y x3 y3} [$id bbox]}} - } - mset {x1 y1 x2 y2} [$self display_area] - set h1 [list $x1 $y $x2 $y] - set v1 [list $x $y1 $x $y2] - $self item VHAIR1 line $v1 -fill [$@canvas look crosshair] -width 1 -dash {4 4 4 4} - $self item HHAIR1 line $h1 -fill [$@canvas look crosshair] -width 1 -dash {4 4 4 4} -} - -#def Crosshair erase {} {$self item_delete VHAIR1; $self item_delete HHAIR1} -class_new Sense {View} -def Sense init {canvas} { - super - set @canvas $canvas - $self data= 0 0 0 red -} -def Sense data= {x y range col} { - set @x $x - set @y $y - set @range $range - set @col $col -} -def Sense flash {x y sense col} { - $self data= $x $y $sense $col - $self draw - after 500 $self erase -} -def Sense draw {} { - set c [$@canvas widget] - set x1 [expr $@x-$@range]; set y1 [expr $@y-$@range] - set x2 [expr $@x+$@range]; set y2 [expr $@y+$@range] - $self item SENSE oval [list $x1 $y1 $x2 $y2] -fill $@col -outline yellow -} -def View display_area {} { - set c [$@canvas widget]; set z [$@canvas zoom] - set edge 10 - set x1 [expr {int([$c canvasx $edge]/$z)}] - set y1 [expr {int([$c canvasy $edge]/$z)}] - set x2 [expr {int(([$c canvasx [winfo width $c]]-$edge)/$z)}] - set y2 [expr {int(([$c canvasy [winfo height $c]]-$edge)/$z)}] - return [list $x1 $y1 $x2 $y2] -} - -class_new Grid {View} -def Grid init {canvas} { - super - set @canvas $canvas - set c [$@canvas widget] - set @width [winfo width $c] - set @height [winfo height $c] - set @size [$@canvas look grid_size] - set @col [$@canvas look grid] - set @gap 5 -} -def Grid classtags {} {return {}} -def Grid update {h w} {set @width $w; set @height $h} -def Grid size= {size} {set @size $size} -def Canvas snap_grid {} {return [$self look snap_grid]} -def Canvas snap_grid= {val} {set ::look(Canvas:snap_grid) $val} -def Canvas snap_objs2grid {} { - if {![$self editmode]} {return} - foreach obj [$@objects values] { - mset {x y} [$obj xy] - set grid [$self look grid_size] - set x [expr floor($x/$grid)*$grid] - set y [expr floor($y/$grid)*$grid] - $obj moveto $x $y - } -} -def Grid draw {} { - mset {x1 y1 x2 y2} [$self display_area] - set c [$@canvas widget] - set lowest [$@canvas lowest_item] - $self draw_lines $x1 $x2 $y1 $y2 VL - $self draw_lines $y1 $y2 $x1 $x2 HL - if {$lowest != -1} {$c lower $self $lowest} -} -def Grid draw_lines {v1 v2 v3 v4 tag} { - set s $@size; set g $@gap - for {set i $v1} {$i < $v2} {incr i} { - #if {$l%$g == 0} {set width 1;set dash [list 7 1]} {set width 1;set dash [list 1 4 1 4]} - if {![expr {$i % int($s*$g)}]} {set w 1;set d [list 7 1]} {set w 1;set d [list 1 4 1 4]} - if {![expr {$i % int($s)}]} { - switch $tag {VL {set line [list $i $v3 $i $v4]} HL {set line [list $v3 $i $v4 $i]}} - $self item ${tag}$i line $line -fill $@col -width $w -dash $d - } - } -} - -def Canvas lowest_item {} { - set c [$self widget] - set all [$c find withtag foo] - if {![llength $all]} {return -1} - set lowest [lindex [$c gettags [lindex $all 0]] 0] - return $lowest -} -#def Canvas grid_size {} {return [$self look grid_size]} -def Canvas grid_size= {size} { - set ::look(Canvas:grid_size) $size - if {[$self editmode]} {$@grid size= $size; $@grid erase; after 0 $@grid draw} -} -############ tooltips (only those that are drawn as canvas items) - -class_new Tooltip {View} -def Tooltip init {canvas pos curpos text type iserror} { - set @canvas $canvas - set @pos $pos - set @curpos $curpos - set @text $text - set @type $type - set @iserror $iserror -} -def Tooltip iserror {} {return $@iserror} -def Tooltip curpos {} {return $@curpos} -def Tooltip text {} {return $@text} -def Tooltip draw {} { - set c [$@canvas widget] - if {$@iserror} { - set fg "#ffffff"; set bg "#dd0000" - } else { - set fg "#000000"; set bg "#ffffcc" - } - mset {x y} $@pos - switch -- $@type { - o {set ny [expr {$y+24}]} - i {set ny [expr {$y-24}]} - } - $self item TEXT text [list [expr $x+12] $ny] -fill $fg -text $@text -anchor sw -width 300 - mset {x1 y1 x2 y2} [l+ [$c bbox ${self}TEXT] [list -4 -4 +4 +4]] - switch -- $@type { - o {set coords [list $x1 $y1 [expr $x1+8] $y1 $x $y [expr $x1+16] $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1]} - i {set coords [list $x1 $y1 $x2 $y1 $x2 $y2 [expr $x1+16] $y2 $x $y [expr $x1+8] $y2 $x1 $y2 $x1 $y1]} - } - $self item RECT polygon $coords -fill $bg -outline $fg - $c lower ${self}RECT ${self}TEXT -} -# $c delete tooltip_bg tooltip_fg -set tooltip "" -def Canvas show_tooltip {x y text type {iserror 0}} { - global tooltip - if {$tooltip ne "" && [$tooltip text] eq $text} {return} - if {$tooltip ne ""} {$tooltip delete} - set tooltip [Tooltip new $self [list $x $y] $@curpos $text $type $iserror] - $tooltip draw -} - -############ class browser - -# future use, maybe: -#class_new ServerClassDict {Observable Thing} -#def ServerClassDict init {} {} - -# Completion/Browser init can be cleaned up a bit more, do it later... -class_new ClassBrowser {Dialogue} -class_new Browser {ClassBrowser} -def Browser init {name x y textbox} {super $name $x $y $textbox} - -class_new Completion {ClassBrowser} -def Completion init {name x y textbox} {super $name $x $y $textbox} -def Completion cancel {} { - bind $@textbox <Key> "$@textself key_input %W %x %y %K %A 0" - bind $@textbox <Control-Return> "$@textself key_input %W %x %y 10 %A 0" - bind $@textbox <Return> "$@textself unedit" - bind $@textbox <Tab> "$@textself key_input %W %x %y %K %A 0" - focus $@textbox - $self delete -} -def ClassBrowser delete {} {set @exist 0; super} -def ClassBrowser init {name x y textbox} { - set @name $name - set @width 0 - set @height 0 - # so that in completion mode, it know which textbox to switch the focus to - set @textbox $textbox - netsend [list pd update-path] - netsend [list pd update-class-list $self list_callback] -} -def ClassBrowser fill_box {s} { - $@listbox delete 0 end - foreach class [lsort $::class_list] { - if {[string length $s]==0 || [string first $s $class]>=0} { - set t "\[$class\]" - if {[can_say $class]} {append t " [say $class]"} - $@listbox insert end $t - #if {[string length $t] > [string length $@width]} {set @width [string length $t]} - if {[string length $t] > $@width} {set @width [string length $t]} - } - } - set none [say no_matches] - if {![$@listbox size]} {$@listbox insert 0 $none; set @width [string length $none]} - $@listbox selection set 0 0 -} - -def Completion fill_box {s} { - super $s - wm maxsize .$self [winfo reqwidth .$self.comp] [winfo reqheight .$self.comp] -} - -def Browser fill_box {s} { - super $s - .$self.title configure -text [format [say how_many_object_classes] [$@listbox size] [llength $::class_list]] -} - -proc search_for_externs {} { - foreach dir $::pd_path { - catch { - #set xs [glob "$dir/*.pd*"] - set xs [glob "$dir/*.pd_*"] - foreach x $xs { - set fn [lindex [file split $x] end] - set fn [join [lrange [split $fn .] 0 end-1] .] - lappend ::class_list $fn - } - } - } -} - -def ClassBrowser info {listbox} { - set class [$self current_class] - if {$class != ""} {netsend [list pd update-class-info $class $self info_callback]} -} - -def Browser list_callback {} { - search_for_externs - set class_list [luniq [lsort $::class_list]] - - toplevel .$self - set f .$self.cl - pack [frame $f] -side top -fill both -expand yes - pack [label .$self.title -text ""] -side top - listbox $f.1 -width 50 -height 20 -yscrollcommand "$f.2 set" -activestyle none - scrollbar $f.2 -command "$f.1 yview" - text $f.3 -width 30 -height 20 -yscrollcommand "$f.4 set" - scrollbar $f.4 -command "$f.3 yview" - set @listbox $f.1 - - frame $f.5 - button $f.5.help -text [say help] -command [list $self help] - pack $f.5.help -side top - pack $f.5 -side left -fill y -expand no - pack $f.1 -side left -fill both -expand yes - pack $f.2 -side left -fill y -expand no - pack $f.3 -side left -fill both -expand yes - pack $f.4 -side left -fill y -expand no - - set b .$self.butt - frame $b - pack [label $b.1 -text [say filter]] -side left - pack [entry $b.2 -width 15] -side left - pack [button $b.close -text [say close] -command "destroy .$self"] -side right - pack $b -side bottom -fill x -expand no - set @textbox $b.2 - $self fill_box "" - #bind $f.1 <Button-1> "after 1 \"$self info $f.1 \"" - foreach w [list $f.1 $b.2] { - bind $w <KeyPress> "after 1 \"$self key %K 0\"" - bind $w <Shift-KeyPress> "after 1 \"$self key %K 1\"" - bind $w <Return> [list $self help] - } - focus $@textbox -} - -def Browser help {} { - set f .$self.cl - netsend [list pd help [$self current_class]] -} - -def Completion list_callback {} { - search_for_externs - set class_list [luniq [lsort $::class_list]] - toplevel .$self - wm protocol .$self WM_DELETE_WINDOW "$self cancel" - wm overrideredirect .$self 1 - set canvas $@name - set f .$self.comp - set @listbox $f - set @rootx [winfo rootx .$@name.c] - set @rooty [winfo rooty .$@name.c] - set @max [wm maxsize .$self] - if {[regexp {(x[0-9a-z]{6,8})text$} $@textbox dummy textself]} {set @textself $textself} - if {[$canvas look showcomp] <= 20} {set @height [$canvas look showcomp]} else {set @height 20} - listbox $f -width $@width -height $@height -relief flat -activestyle dotbox -font $::look(View:font) \ - -bg [$@textself look bg] -selectbackground [$@textself look fg] \ - -fg [$@textself look fg] -selectforeground [$@textself look bg] - $self adjust_box - bind $f <Button-1> "after 1 \"$self complete\"" - bind $f <Return> "after 1 \"$self complete\"" - bind $f <KeyPress> "$self key %K 0" - bind $f <Shift-KeyPress> "$self key %K 1" - bind $@textbox <Tab> "$self key %K; break" - bind $@textbox <KeyPress> "$self key %K " - focus .$self.comp -} - -def Completion adjust_box {} { - mset {x1 y1 x2 y2} [lmap * [$@textself bbox] [$@name zoom]] - set x1 [format %0.f $x1];set y1 [format %0.f $y1] - set x2 [format %0.f $x2];set y2 [format %0.f $y2] - $self fill_box [$@textbox get 1.0 1.end] - set f .$self.comp - $f configure -width $@width - set box_width [winfo reqwidth $f] - set box_height [winfo reqheight $f] - pack $f -side left -expand yes - - .$self configure -width $box_width - .$self configure -height $box_height - - #test the right edge of the screen, assuming the left edge has enough space - if {[expr $x1+$@rootx+$box_width] < [lindex $@max 0]} { - set box_x [expr $x1+$@rootx] - } else { - set box_x [expr $x2 - $box_width + $@rootx] - } - #test the lower edge of the screen, assuming the upper edge has enough space - if {[expr $y2+$@rooty+$box_height] < [lindex $@max 1]} { - set box_y [expr $y2 + 5 + $@rooty] - } else { - set box_y [expr $y1 - $box_height - 2 + $@rooty] - } - - wm geometry .$self [winfo reqwidth .$self]x[winfo reqheight .$self]+$box_x+$box_y - -} - -def ClassBrowser current_class {} { - set i [$@listbox curselection] - if {$i == ""} {return {}} - return [string range [lindex [$@listbox get $i] 0] 1 end-1] -} - -def ClassBrowser complete {} { - if {[regexp {x([0-9a-z]{6,8})text$} $@textbox obj]} { - set cut [string first "text" $obj] - set obj [string range $obj 0 [expr $cut -1]] - } - set class [$self current_class] - $@textbox delete 1.0 1.end - $@textbox insert 1.0 $class - $obj unedit - destroy .$self -} - -def ClassBrowser key {key {shift 0}} { - switch -regexp -- $key { - Up|Down { - if {[focus] != $@listbox} { - focus $@listbox - event generate $@listbox <KeyPress> -keysym $key - } else { - if {$self == "browser"} {$self info $@listbox} - } - } - Escape {after 1 "$self cancel"} ;# doesn't really work - Tab { - focus $@listbox - set next [$@listbox index active] - incr next - if {$next >= [$@listbox size]} {set next 0} - $@listbox activate $next - $@listbox selection clear 0 [expr [$@listbox size] - 1] - $@listbox selection set $next $next - #if {$next >= [expr $@height - 1]} {$@listbox yview scroll 1 units} - $@listbox see $next - if {$self == "browser"} {$self info $@listbox} - } - BackSpace { - if {[focus] == $@listbox} {focus $@textbox} - #classbrowser uses entry as input widget, where as completion is text widget... - switch $self { - browser {$self fill_box [$@textbox get]} - completion {$self adjust_box; $@textself resize; $@textself changed} - } - } - default { - $self key_default $key - } - } -} - -def Browser key_default {key} { - if {[focus] == $@listbox} { - if {[regexp {^[a-zA-Z0-9~/\._]{1}$} $key]} { - .$self.butt.2 insert end $key - $self fill_box [$@textbox get] - } - } else {$self fill_box [$@textbox get]} -} - -def Completion key_default {key} { - if {[focus] == $@listbox} { - if {[regexp {^[a-zA-Z0-9~/\._]{1}$} $key]} { - $@textbox insert 1.end $key - $@textself after_key $@textbox - $self adjust_box - focus $@textbox - } - } - if {[focus] == $@textbox & $key != "Tab"} { - $self adjust_box - $@textself resize - #hum, no idea why i need after 1 for it to work... - after 1 $@textself after_key $@textbox - } -} - -def ClassBrowser info_callback {class} { - global class_info - set f .browser.cl - set class [$self current_class] - $f.3 delete 0.0 end - $f.3 insert end "class $class\n" - foreach {k v} $class_info($class) {$f.3 insert end "$k=\"$v\"\n"} -} - -def TextBox propose_completions {} { - set c [$@canvas widget] - set widget $c.${self}text - set propose $c.${self}propose - #$propose configure -state normal - if {![info exists ::class_list]} { - netsend [list pd update-class-list $self propose_completions] - return - } - set r {} - set c {} - set n 0 - set prev "" - foreach class [luniq [lsort $::class_list]] { - if {[string length $@text]==0 || [string first $@text $class]>=0} { - if {[string compare [say $class] "{{$class}}"]} { - lappend r "$class : [say $class]" - } { - lappend r $class - } - lappend c $class - incr n - } - if {$n > 16} {lappend r ...; break} - } - set r [join $r "\n"] - mset {x1 y1 x2 y2} [$self bbox] - set @action [Completion new_as completion $@canvas $x1 $y1 $widget] -} - -############ properties_dialog ######### -proc change_entry {self val} { - set v [expr [$self get]+$val] - $self delete 0 end - $self insert 0 $v -} - -class_new Dialogue {View} -def Dialogue add_stuff {f name label} { - frame $f -# frame $f.label -width $@label_width -borderwidth 2 -# pack [button $f.label.0 -image "icon_empty" -width $@label_width] -side left -# place [message $f.label.1 -text $label -width $@label_width] -x 0 -y 0 -# puts [$f.label.1 cget -height] - pack [label $f.label -text $label -width [expr $@label_width/7] -wraplength $@label_width -anchor e] -side left - balloon $f.label $name -} -def Dialogue add_side {f name label} { - $self add_stuff $f $name $label - frame $f.side -relief ridge -borderwidth 2 - foreach {i side} {0 left 1 right 2 top 3 bottom} { - radiobutton $f.side.$side -value $i -variable @$name -text $side - } - pack $f.side.left -side left -fill y - pack $f.side.right -side right -fill y - pack $f.side.top -side top - pack $f.side.bottom -side bottom - pack $f.side -side left -} -def Dialogue add_color {f name label} { - $self add_stuff $f $name $label - set v $@$name - set text_color [complement $v] - button $f.color -text $v -font {Courier 10} -width 10 -pady 2 -fg $text_color \ - -command [list $self choose_col $f $name $v] -relief sunken -background $v -highlightbackground $v -activebackground $v - button $f.preset -text [say "preset"] -pady 2 -font {Helvetica 8} \ - -command [list $self color_popup $f $name 10] - bind $f.preset <Return> "$self color_popup $f $name 10" - pack $f.color $f.preset -side left -} -def Dialogue add_choice {f name label choices} { - $self add_stuff $f $name $label - menu $f.menu -tearoff 0 - set i 0 - foreach part $choices { - $f.menu add command -label [say $part] -command [list $self dropmenu_set $f $name $part $i] - incr i - } - set trim_name [string trimleft $name "-"] - set _($self:${name}choices) $choices - set choice $@$name - if {[string is integer $choice]} {set choice [lindex $choices $choice]} - label $f.butt -text [say $choice] -relief raised -width 20 - balloon $f.butt "click to change setting" - pack $f.label $f.butt -side left - bind $f.butt <1> [list $self dropmenu_open $f $name] -} -def Dialogue add_key {f name label} { - set text "" - set n 0 - foreach item $name { - if {$n != 0} {append text " & " [say $item]} else {set text [say $item]} - incr n - } - $self add_stuff $f $name $text - #balloon $f.label $name - foreach item $name { - set v $_($self:$item) ;# bug in objtcl - set item_lower [string tolower $item] - entry $f.$item_lower -width 15 -textvariable @$item - pack $f.$item_lower -side left - } -} -def Dialogue add_folders {f name label} { - $self add_stuff $f $name $label - set v $_($self:$name) ;# bug in poetcl - frame $f.a - listbox $f.a.list -width 40 -height 8 -yscrollcommand "$f.a.yscroll set" \ - -activestyle none -xscrollcommand "$f.a.xscroll set" - foreach line $v {$f.a.list insert end $line} - set @$name $f.a.list ;# save the listbox path at @$name instead - scrollbar $f.a.yscroll -command "$f.a.list yview" - scrollbar $f.a.xscroll -command "$f.a.list xview" -orient horizontal - pack $f.a.xscroll -side bottom -fill x - pack $f.a.list -side left -fill both -expand 1 - pack $f.a.yscroll -side left -fill y - pack $f.a -side left - frame $f.b -borderwidth 0 - foreach {cmd lab} {dir_add add listbox_remove remove listbox_up up listbox_down down} { - pack [button $f.b.$cmd -command "$self $cmd $f.a.list" -text [say $lab] -width 6] -side top - balloon $f.b.$cmd [say dir_$lab] - } - pack $f.b -side top -} -def Dialogue add_libraries {f name label} { - $self add_stuff $f $name $label - set v $_($self:$name) ;# bug in poetcl. is it still there? - frame $f.a - listbox $f.a.list -width 32 -height 16 -yscrollcommand "$f.a.yscroll set" \ - -activestyle none -xscrollcommand "$f.a.xscroll set" - #foreach line $@$name {$f.a.list insert end $line} - foreach line $v {$f.a.list insert end $line} - # save the listbox path at @$name instead - set @$name $f.a.list - pack [scrollbar $f.a.yscroll -command "$f.a.list yview"] -side right -fill y - pack $f.a.list -side top -fill both -expand 1 - pack [scrollbar $f.a.xscroll -command "$f.a.list xview" -orient horizontal] -side bottom -fill x - pack $f.a -side left - - frame $f.b -borderwidth 0 - pack [entry $f.b.entry -width 15 -borderwidth 5 -relief ridge] -side top - bind $f.b.entry <Return> "$self lib_add $f.a.list" - - foreach {cmd lab} {lib_add add listbox_remove remove listbox_up up listbox_down down} { - pack [button $f.b.$cmd -command "$self $cmd $f.a.list" -text [say $lab] -width 6] -side top - #balloon $f.b.$cmd [say dir_$lab] - } - pack $f.b -side top -} -def Dialogue dir_add {listbox} { - set dir [tk_chooseDirectory -initialdir ~ -title "Choose a folder" -parent .$self] - if {$dir == ""} {return} - $listbox insert end $dir - $listbox yview end - focus .$self -} -# doesn't work with toplevel widget -proc upwidget {levels name} { - set l [split $name .] - return [join [lrange $l 0 end-$levels] .] -} -def Dialogue lib_add {f} { - set f [upwidget 2 $f] - set listbox $f.a.list - set entry $f.b.entry - set var [$entry get] - if {$var != ""} {$listbox insert end $var} - $listbox yview end - $entry delete 0 end - focus $entry -} -def Dialogue listbox_remove {listbox} { - set sel [$listbox curselection] - if {$sel == ""} {return} - $listbox delete $sel - $listbox selection set $sel -} -def Dialogue listbox_swap {listbox dir} { - set sel [$listbox curselection] - if {$sel == ""} {return} - if {![inside [expr $sel+$dir] 0 [$listbox size]]} {return} - set line [$listbox get $sel] - $listbox delete $sel - incr sel $dir - $listbox insert $sel $line - $listbox selection set $sel - $listbox see $sel -} -def Dialogue add_devlist {f name label} { - $self add_stuff $f $name $label - menu $f.menu -tearoff 0 - set i 0 - set trim_name [string trimleft $name "-"] - set part none ;# in case there are none - foreach part $@$trim_name { - $f.menu add command -label $part -command [list $self dropmenu_set $f $name $part $i] - incr i - } - #label $f.butt -text [lindex $@$trim_name 0] -relief raised -width 20 - label $f.butt -textvariable _($self:${trim_name}0) -relief raised -width 20 - balloon $f.butt "click to change setting" - pack $f.label $f.butt -side left - bind $f.butt <1> [list $self dropmenu_open $f $name] -} -def Dialogue add_spins {f name label option} { - $self add_stuff $f $name $label - set i 0 - set trim_name [string trimleft $name "-"] - set n [llength $@$option] - foreach part $@$trim_name { - if {$i < $n} {set s "readonly"} else {set s "disabled"} - set v "::_($self:$trim_name${i})" - spinbox $f.$i -width 2 -command "$self spinning %d $v" -state $s -textvariable $v - pack $f.$i -side left - balloon $f.$i "Device [expr $i+1]" - incr i - } -} -def Dialogue spinning {mode v} { - switch $mode { - up {incr $v; puts " incr $v"} - down {incr $v -1} - } -} -def Dialogue listbox_up {listbox} {$self listbox_swap $listbox -1} -def Dialogue listbox_down {listbox} {$self listbox_swap $listbox +1} -def Dialogue add {w args} { - foreach row $args { - set name [lindex $row 0] - set type [lindex $row 1] - set options [lrange $row 2 end] - set f $w.$name - set label "[say $name]: " - set k [lsearch $options -choices] - if {$k>=0} { - set choices [lindex $options [expr $k+1]] - set options [lreplace $options $k [expr $k+1]] - } - #set v $@$name - #set v $_($self:$name) ;# bug in poetcl - switch -- $type { - side {$self add_side $f $name $label} - color {$self add_color $f $name $label} - font {$self add_font $f $name $label $options} - choice {$self add_choice $f $name $label $choices} - key {set f $w.[string tolower [lindex $name 0]] - $self add_key $f $name $label} - folders {$self add_folders $f $name $label} - libraries {$self add_libraries $f $name $label} - devlist {$self add_devlist $f $name $label} - spins {$self add_spins $f $name $label $options} - section {label $f -text $label -bg "#0000aa" -fg "#ffff55" -font {helvetica -10 bold}} - subsection {label $f -text $label -bg "#0000aa" -fg "#ffff55" -font {helvetica -10 bold}} - toggle { - $self add_stuff $f $name $label - eval [concat [list checkbutton $f.toggle -variable @$name] $options] - pack $f.toggle -side left - } - default { - $self add_stuff $f $name $label - set trim_name [string trimleft $name "-"] - eval [concat [list entry $f.entry -textvariable _($self:$trim_name)] $options] - pack $f.entry -side left - bind $f.entry <Return> "$self ok" - switch -regexp -- $type { - integer|float|fontsize { - frame $f.b -borderwidth 0 - button $f.b.1 -image icon_wedge_up -command "change_entry $f.entry +1" - button $f.b.2 -image icon_wedge_down -command "change_entry $f.entry -1" - pack $f.b.1 $f.b.2 -side top - pack $f.b -side left - bind $f.entry <Button-4> "change_entry $f.entry +1" - bind $f.entry <Button-5> "change_entry $f.entry -1" - } - entry {} - default { - label $f.type -text "($type)" -fg "#808080" - pack $f.type -side right -anchor e - } - } - } - } - pack $f -side top -fill x - } -} - -proc logvar {args} { - set r {} - foreach var $args { - regsub {^_\(.*:(.*)\)$} $var {@\1} var2 - lappend r "$var2=[uplevel 1 list \$$var]" - } - puts [join $r "; "] -} - -def Dialogue spinbox_update {mode} {puts " $mode"} -def Dialogue add_font {f name label class} { - $self add_stuff $f $name $label - set v $@$name - label $f.font -text $v -font [lreplace $v 1 1 -10] -width [string length $v] -height 1 -pady 3 -fg black \ - -relief sunken -bg white - button $f.preset -text [say "edit"] -pady 2 -font {Helvetica 8} \ - -command "FontDialogue new_as $name $class $f.font" - pack $f.font $f.preset -side left -} - -def Canvas fd {} {FontDialogue new_as view_font [$self look font] "View"} - -class_new FontDialogue {Dialogue} -def FontDialogue init {class orig} { - if {[winfo exists .$self]} {return} - super cancel ok - set f .$self - set @class $class - set @orig $orig - bind all <KeyPress-F1> help - set font $::look($@class:font) - set @family [lindex $font 0] - set @size [expr -[lindex $font 1]] - set @bold [expr [lsearch $font bold ]>=0] - set @italic [expr [lsearch $font italic]>=0] - set @str $font - pack [label $f.label -text [say font_family] -anchor w] -side top -fill x - - frame $f.list -bd 2 - pack [listbox $f.list.box -relief sunken -yscrollcommand "$f.list.scroll set" -width 30] -side left -expand yes -fill both - pack [scrollbar $f.list.scroll -relief sunken -command "$f.list.box yview" -takefocus 0] -side right -fill y - bind $f.list.box <<ListboxSelect>> "$self font_update $f" - foreach name [lsort [font families]] {$f.list.box insert end $name} - set fontlist [$f.list.box get 0 end] - set find [max 0 [lsearch $fontlist $@family]] - $f.list.box selection set $find $find - $f.list.box activate $find - $f.list.box see $find - bind $f.list.box <ButtonRelease-1> "$self font_update $f" - bind $f.list.box <ButtonPress-1> "focus $f.list.box" - pack $f.list -side left -expand yes -fill both - - #pack [ttk::separator $f.sep -orient vertical] -side left -fill y - #pack [ttk::sizegrip $f.sep] -side left -fill y - #ttk::panedwindow - - frame $f.var - frame $f.var.size - pack [label $f.var.size.label -text [say font_size]] -side left - pack [spinbox $f.var.size.entry -relief sunken -textvariable fontsize -width 4 \ - -command "$self font_changesize $f %d"] -side left - bind $f.var.size.entry <KeyPress-Return> "$self font_update_size $f" - $f.var.size.entry delete 0 end - $f.var.size.entry insert 0 $@size - - frame $f.var.style - pack [label $f.var.style.label -text [say font_style]] -side left - set cmd [list $self font_update $f] - pack [checkbutton $f.var.style.bold -text [say font_bold] -variable @bold -command $cmd] -side top - pack [checkbutton $f.var.style.italic -text [say font_italic] -variable @italic -command $cmd] -side top - - pack $f.var.size -side left - pack $f.var.style -side left -padx 20 - - frame $f.preview - pack [label $f.preview.label -text [say font_preview]] -side left - pack [canvas $f.preview.canvas -width 250 -height 50 -relief sunken -borderwidth 1] -side left -fill x - $f.preview.canvas create text 4 4 -tags ${self}TEXT -anchor nw -text [say font_preview_2] -font $font - - pack $f.var -side top -fill x - pack $f.preview -side top -pady 10 - focus $f.list.box - #$self non_resizable -} -def FontDialogue font_update {f} { - global font - set lb $f.list.box - set @family [$lb get [$lb curselection]] - set @str [list $@family [expr -$@size]] - if {$@bold } {lappend @str bold } - if {$@italic} {lappend @str italic} - # logvar @str - $f.preview.canvas itemconfigure ${self}TEXT -font $@str -} -def FontDialogue font_changesize {f mode} { - switch $mode { - up {set @size [expr $@size+1]} - down {set @size [expr $@size-1]} - } - $f.var.size.entry delete 0 end - $f.var.size.entry insert 0 $@size - $self font_update $f -} -def FontDialogue font_style {f bold} { - set @bold $bold - $self font_update $f -} -def FontDialogue font_update_size {f} { - set size [$f.var.size.entry get] - if [regexp {^[0-9]+$} $size] {set @size $size} - $self font_update $f -} -def FontDialogue apply {} { - set ::look($@class:font) $@str - $@orig configure -font [lreplace $@str 1 1 -10] -text $@str -width [string length $@str] -} - -############ .pdrc editor -#Turns #rgb into 3 elem list of decimal vals. -proc rgb2dec {c} { - set c [string tolower $c] - if {[regexp -nocase {^#([0-9a-f])([0-9a-f])([0-9a-f])$} $c x r g b]} { - # double'ing the value make #9fc == #99ffcc - scan "$r$r $g$g $b$b" "%x %x %x" r g b - } else { - if {![regexp {^#([0-9a-f]+)$} $c junk hex] || \ - [set len [string length $hex]]>12 || $len%3 != 0} { - if {[catch {winfo rgb . $c} rgb]} { - return -code error "bad color value \"$c\"" - } else { - return $rgb - } - } - set len [expr {$len/3}] - scan $hex "%${len}x%${len}x%${len}x" r g b - } - return [list $r $g $b] -} -#Returns a complementary color -proc complement {orig {grays 1}} { - foreach {r g b} [rgb2dec $orig] {break} - set R [expr {(~$r)%256}] - set G [expr {(~$g)%256}] - set B [expr {(~$b)%256}] - if {$grays && abs($R-$r) < 32 && abs($G-$g) < 32 && abs($B-$b) < 32} { - set R [expr {($r+128)%256}] - set G [expr {($g+128)%256}] - set B [expr {($b+128)%256}] - } - return [format "\#%02x%02x%02x" $R $G $B] -} - -# this makes the tooltip -proc balloon {w help} { - bind $w <Any-Enter> "after 500 [list balloon:show %W [list $help]]" - #bind $w <Any-Leave> "destroy %W.balloon; puts \"destroy balloon\" " - bind $w <Any-Leave> "destroy %W.balloon" -} - -proc balloon:show {w arg} { - if {[eval winfo containing [winfo pointerxy .]]!=$w} {return} - set top $w.balloon - catch {destroy $top} - toplevel $top -bd 1 -bg black - wm overrideredirect $top 1 - if {$::tcl_platform(platform) == "macintosh"} {unsupported1 style $top floating sideTitlebar} - pack [message $top.txt -aspect 10000 -bg lightyellow -font fixed -text $arg] - set wmx [expr [winfo rootx $w]+[winfo width $w]] - set wmy [winfo rooty $w] - wm geometry $top [winfo reqwidth $top.txt]x[winfo reqheight $top.txt]+$wmx+$wmy - raise $top -} - -def Dialogue ok {} {$self apply; $self cancel} -def Dialogue cancel {} {$self delete} -def Dialogue close {} {$self delete} -def Dialogue apply {} {} -def Dialogue delete {} {destroy .$self; super} -def Dialogue erase {} {}; # so that it doesn't call View erase -def Dialogue init {args} { - super - set f .$self - set @label_width 160 ;# 20 - toplevel $f - frame $f.buttonsep -height 2 -borderwidth 1 -relief sunken - frame $f.buttonframe - set i 0 - foreach a $args { - if {[llength $args]<=1 || $i>0} { - pack [label $f.buttonframe.$i -width 1] -side left -fill x -expand 1 - } - pack [button $f.buttonframe.$a -text [say $a] -command "$self $a"] -side left - bind $f.buttonframe.$a <Return> "$self $a" - incr i - } - pack $f.buttonframe -side bottom -fill x -pady 2m - pack $f.buttonsep -side bottom -fill x - wm protocol $f WM_DELETE_WINDOW "$self cancel" - bind .$self <Tab> "$self traversal %K %W forward" - bind .$self <Control-Tab> "$self traversal %K %W back" - set @auto_apply 0 -} -def Dialogue do_auto_apply {} {if {$@auto_apply} {$self apply}} -def Dialogue non_resizable {} {wm resizable .$self 0 0} -def Dialogue traversal {k w direction} { - switch $direction { - forward {focus [tk_focusNext $w]} - back {focus [tk_focusPrev $w]} - } -} -def Dialogue dropmenu_open {frame} { - set x [winfo rootx $frame.butt] - set y [expr [winfo height $frame.butt] + [winfo rooty $frame.butt]] - tk_popup $frame.menu $x $y -} -def Dialogue dropmenu_set {frame var part val} { - #if {$say} {set text [say $part]} else {set text $part} - set @$var $val - $frame.butt configure -text [say $part] -} -def Dialogue color_popup_select {frame var color} { - set @$var $color - set col [format #%6.6x $color] - if {$self == "ddrc"} {set @$var $col} ;#!@#$ fishy - $frame.color configure -background $col -activebackground $col -highlightbackground $col \ - -foreground [complement $col] -text $col - destroy $frame.color.popup - $self do_auto_apply -} -def Dialogue color_popup {frame var i} { - set w $frame.color.popup - if [winfo exists $w] {destroy $w} - #menu $w -tearoff false - toplevel $w -bg "#000000" - wm overrideredirect $w 1 - wm geometry $w +[expr [winfo rootx $frame.preset]]+[expr {[winfo rooty $frame.preset]+[winfo height $frame.preset]}] - for {set i 0} {$i<3} {incr i} { - pack [frame $w.$i -bd 0 -bg "#000000"] - for {set j 0} {$j<10} {incr j} { - set c [lindex $::preset_colors [expr {$i*10+$j}]] - pack [frame $w.$i.$j -width 24 -height 24 -background "#$c" -relief raised] -side left - bind $w.$i.$j <ButtonRelease> [list $self color_popup_select $frame $var [expr 0x$c]] - } - } -} -def Dialogue choose_col {frame var val} { - set c 0xFFFFFF - set color [tk_chooseColor -title $val -initialcolor $val] - if {$color != ""} { - $frame.color configure -text $color - $self color_popup_select $frame $var [expr [string replace $color 0 0 "0x"]&0xFFFFFF] - } -} - -class_new PagedDialogue {Dialogue} -def PagedDialogue init {args} { - eval [concat [list super] $args] - set @nb [ttk::notebook .$self.1] - set @nbs $@nb - pack $@nb -expand 1 -fill both - $self non_resizable -} - -# numbers in section are for the % of space taken by labels -set pdrc_options { - section {section_audio 50} - integer -r - devlist -audioindev|-soundindev - devlist -audiooutdev|-soundoutdev - spins {-inchannels audioindev} - spins {-outchannels audiooutdev} - integer -audiobuf|-soundbuf - integer -blocksize - integer -sleepgrain - void -nodac - void -noadc - choice {audio_api_choice} - void -32bit - - section {section_midi 50} - void -nomidiin - void -nomidiout - devlist -midiindev - devlist -midioutdev - - section {section_externals 20} - libraries -lib - - section {section_paths 20} - folders -path - folders -helppath - - section {section_other 50} - files -open - void -verbose - integer -d - void -noloadbang - string -send - void -listdev - void -realtime|-rt -} - -proc pdtk_audio_dialog {indevlist indevs inchans outdevlist outdevs outchans sr dspblock advance multi longform} { - pdrc audio_properties $indevlist $indevs $inchans $outdevlist $outdevs $outchans $sr $dspblock $advance $multi -} - -class_new ServerPrefsDialogue {PagedDialogue} -def ServerPrefsDialogue apply {} { - set audio_props [$self audio_properties=?] - #pd pd audio-dialog $audio_props - netsend [list "pd" "audio-dialog" $audio_props] - $self write -} -def ServerPrefsDialogue init_reverse_hash {} { - foreach {type names} $::pdrc_options { - set name [lindex $names 0] - if {[info exists @$name]} { - if {$name != "audio_api_choice"} {set @$name ""} - } else {set @$name ""} - foreach alias $names {set ::pdrc_options_h($alias) [list $type $name]} - if {$name == "audio_api_choice"} { - foreach alias [lrange $::pd_apilist2 1 end] {set ::pdrc_options_h($alias) [list $type $name]} - } - } -} -def ServerPrefsDialogue audio_properties {indevlist indevs inchans outdevlist outdevs outchans sr dspblock advance multi} { - set @audioindev $indevlist - set @audiooutdev $outdevlist - # the following @audioindev* is used as -textvariable for devlist - set @audioindev0 [lindex $@audioindev 0] - set @audiooutdev0 [lindex $@audiooutdev 0] - set @inchannels $inchans - set @outchannels $outchans - set @audiobuf $advance - set @blocksize $dspblock - set @usemulti $multi - set @r $sr - set @midiindev "midione" - set @midioutdev "miditwo" - # below are also used as -textvariable - mset [list @inchannels0 @inchannels1 @inchannels2 @inchannels3] $@inchannels - mset [list @outchannels0 @outchannels1 @outchannels2 @outchannels3] $@outchannels - set @audio_api_choice2 [say [lindex $::pd_apilist2 $@audio_api_choice]] - if {![winfo exists .$self.1.1]} {$self init_content} else {$self update_content} -} -def ServerPrefsDialogue audio_properties=? {} { - set indev0 [lsearch $@audioindev $@audioindev0] - set outdev0 [lsearch $@audiooutdev $@audiooutdev0] - return [list $indev0 0 0 0 $@inchannels0 $@inchannels1 $@inchannels2 $@inchannels3 \ - $outdev0 0 0 0 $@outchannels0 $@outchannels1 $@outchannels2 $@outchannels3 \ - $@r $@blocksize $@audiobuf] -} -def ServerPrefsDialogue read_one {type name contents i} { - switch -- $type { - folders {incr i; lappend @$name [lindex $contents $i]} - libraries {incr i; lappend @$name [lindex $contents $i]} - files {incr i; lappend @$name [lindex $contents $i]} - choice { - if {$name == "audio_api_choice"} { - if {$@$name == ""} {set @$name [lsearch $::pd_apilist2 [lindex $contents $i]]} - } else {set @$name [lindex $contents $i]} - } - void { set @$name 1} - default {incr i; set @$name [lindex $contents $i]} - } - incr i - return $i -} -def ServerPrefsDialogue read {} { - global pdrc_options pdrc_options_h cmdline - set fd [open $cmdline(rcfilename) "RDONLY CREAT"] - set contents {} - foreach line [split [read $fd] "\n"] { - if {[string index $line 0] != "#"} {lappend contents $line} - } - close $fd - set contents [concat [join $contents " "]] ;# concat casts to list type (faster) (?) - set i 0 - - # prevent Tk8.5 from showing grey checkmarks - foreach name {-nodac -noadc -32bit -nomidiin -nomidiout -verbose -noloadbang -listdev -realtime} {set _($self:$name) 0} - - while {$i < [llength $contents]} { - set op [lindex $contents $i] - if {[string length $op]==0} {break} - if {![info exists pdrc_options_h($op)]} {post "unknown option: %s" $op; incr i; continue} - mset {type name} $pdrc_options_h($op) - set name [lindex [split $name "|"] 0] - set i [$self read_one $type $name $contents $i] - } -} -def ServerPrefsDialogue write {} { - set fd [open $::cmdline(rcfilename) w] - #set fd stdout; puts "WOULD SAVE:" - foreach {type names} $::pdrc_options { - set name [lindex [split [lindex $names 0] "|"] 0] - if {[info exists _($self:$name)]} {set v $_($self:$name)} ;# bug in objective.tcl ? - switch $type { - folders {foreach item [$v get 0 end] {puts $fd "$name $item"}} - libraries {foreach item [$v get 0 end] {puts $fd "$name $item"}} - #files {foreach item $v {puts $fd "$name $item"}} - void {if {$v != ""} {if {$v} {puts $fd $name}}} - choice { - if {$name != "audio_api_choice"} {set vv [lindex $names [expr 1+$v]]} \ - else {set vv [lindex $::pd_apilist2 $v] } - if {$vv != "default"} {puts $fd $vv} - } - devlist {} - default {if {[string length $v]} {puts $fd "$name $v"}} - } - } - close $fd - #puts "THE END" -} -#def ServerPrefsDialogue reset {} {} -def ServerPrefsDialogue init_content {} { - set f .$self.1 - set section 0 - set @label_width 200 ;# 24 - foreach {type names} $::pdrc_options { - set name [lindex [split [lindex $names 0] "|"] 0] - switch $type { void { set type toggle }} - switch $type { - section { - set @label_width [expr 6*[lindex $names 1]] ;# % of 600 px - frame .$self.1.[incr section] - $@nb add .$self.1.$section -text [say $name] - } - choice { - if {$name == "audio_api_choice"} { - set ops $::pd_apilist2 - } else { - set ops [lrange $names 1 end] - } - $self add $f.$section [list $name choice -choices $ops] - } - devlist {$self add $f.$section [list $name devlist] } - spins {$self add $f.$section [list $name spins [lindex $names 1]] } - default {$self add $f.$section [list $name $type]} - } - } -} -def ServerPrefsDialogue update_content {} {$self update_channels} -def ServerPrefsDialogue update_channels {} { - set indev_len [llength $@audioindev] - set outdev_len [llength $@audiooutdev] - set i 0 - foreach chan $@inchannels { - if {$i< $indev_len} {set s "readonly"} else {set s "disabled"} - .$self.1.1.-inchannels.$i configure -state $s - incr i - } - set i 0 - foreach chan $@outchannels { - if {$i<$outdev_len} {set s "readonly"} else {set s "disabled"} - .$self.1.1.-outchannels.$i configure -state $s - incr i - } -} -def ServerPrefsDialogue init {} { - netsend [list pd audio-properties] - $self init_reverse_hash - $self read - super reset cancel apply ok - # pd pd midi-properties -} -def ServerPrefsDialogue dropmenu_set {frame var part val} { - set trim_part [string trimleft $part "-"] - set trim_var [string trimleft $var "-"] - if {$var == "audio_api_choice"} { - foreach api $::pd_apilist { - if {$trim_part == [string tolower [lindex $api 0]]} { - netsend [list pd audio-setapi [lindex $api 1]] - after 1 [netsend [list pd audio-properties]] - } - } - } else { - set ::_($self:${trim_var}0) $part - } - super $frame $var $part $val -} -#used by choice and devlist -def ServerPrefsDialogue dropmenu_open {f name} { - set trim_name [string trimleft $name "-"] - if {$trim_name != "audio_api_choice"} { - set i 0 - set m $f.menu - $m delete 0 end - foreach part $@$trim_name { - $m add command -label $part -command [list $self dropmenu_set $f $name $part $i] - incr i - } - } - super $f -} - -#################### ClientPrefsDialogue -set ddrc_options { -section Client section_color - subsection Client canvas_color - color Canvas bgedit - color Canvas bgrun - color Canvas grid - subsection Client object_color - color View bg - color View fg - color View frame1 - color View frame2 - color View frame3 - color Comment bg - color Comment fg - color Comment frame1 - color Comment frame2 - color Comment frame3 - color View selectframe - font View font - subsection Client wire_color - color Wire fg - color Wire dspfg - color Wire fg2 - color FutureWire dash - subsection Client others_color - color Box inletfg - color Box outletfg - color SelRect rect - font KeyboardDialogue font - font Console font -section Client keys - subsection Client put - key Canvas Object - key Canvas Message - key Canvas {Number nbx} - key Canvas Symbol - key Canvas Comment - key Canvas bng - key Canvas tgl - key Canvas {vsl hsl} - key Canvas {vradio hradio} - key Canvas vu - key Canvas cnv - key Canvas Graph - key Canvas Array - subsection Client edit - key Canvas {cut copy} - key Canvas {undo redo} - key Canvas {paste duplicate} - key Canvas select_all - key Canvas clear_selection - key Canvas {reload redraw} - key Canvas editmodeswitch - key Canvas {insert_object chain_object} - key Canvas {clear_wires auto_wire} - key Canvas subpatcherize - subsection Client general - key Canvas Pdwindow - key Canvas {new_file open_file} - key Canvas {save save_as} - key Client {server_prefs client_prefs} - key Canvas {close quit} - key Canvas {find find_again} - key Canvas {audio_on audio_off} - key Client {audio_settings midi_settings} - key Client test_audio_and_midi - key Canvas {load_meter latency_meter} - key Canvas about - subsection Canvas keynav - key Canvas {key_nav_up key_nav_up_shift} - key Canvas {key_nav_down key_nav_down_shift} - key Canvas {key_nav_right key_nav_right_shift} - key Canvas {key_nav_left key_nav_left_shift} - key Canvas key_nav_ioselect -section Client others - toggle Canvas hairstate - toggle Canvas hairsnap - toggle Canvas gridstate - integer Canvas grid_size - toggle Canvas snap_grid - toggle Canvas buttonbar - toggle Canvas statusbar - toggle Canvas menubar - toggle Canvas scrollbar - toggle View tooltip - toggle Wire wirearrow - integer Client console - language View language - language View language2 - integer Canvas pointer_sense -} - -class_new ClientPrefsDialogue {PagedDialogue} -def ClientPrefsDialogue apply {} {$self write; $self do_apply} -def ClientPrefsDialogue read {} {read_ddrc} -def ClientPrefsDialogue do_apply {} { - foreach canvas $::window_list { - if {[$canvas class] == "Canvas"} { - $canvas activate_menubar= [$canvas look menubar] - $canvas activate_buttonbar= [$canvas look buttonbar] - $canvas activate_statusbar= [$canvas look statusbar] - $canvas activate_scrollbars= [$canvas look scrollbar] - $canvas activate_grid= [$canvas look gridstate] - $canvas redraw - } - } -} -def ClientPrefsDialogue write {} { - global look key - $self get_val - set fd [open $::cmdline(ddrcfilename) w] - foreach category {look key} { - set class_list {} - puts $fd "$category \{" - foreach name [array names $category] { - mset {class var} [split $name ":"] - lappend class_list $class - } - set class_list [luniq [lsort $class_list]] - foreach class $class_list { - puts $fd " $class \{" - foreach name [lsort [array names $category -glob $class:*]] { - mset {class var} [split $name ":"] - # the eval here annoys me a bit because of possible special chars -- matju - puts $fd " $var [eval list \$${category}($class:$var)]" - #puts " $var $category $class $var" - } - puts $fd " \}" - } - puts $fd "\}" - } - close $fd -} -#this retrieves the values set in the editor -def ClientPrefsDialogue get_val {} { - global ddrc_options look key accels - set check_key {} - foreach {type class name} $ddrc_options { - switch -regexp -- $type { - color { - set str [string tolower $class$name] - set look($class:$name) $@$str - } - key { - foreach item $name { - set new_key $@$item - set old_key $key($class:$item) - if {$key($class:$item) != $new_key} { - if {[dict exists $accels $old_key]} { - set cmd [dict get $accels $old_key] - set accels [dict remove $accels $old_key] - dict set accels $new_key $cmd - } - } - if {[dict exists $check_key $new_key] && $new_key != ""} { - error "$new_key already assigned" - } else {dict set check_key $new_key key($item)} - set key($class:$item) $new_key - } - } - toggle {set look($class:$name) $@$name} - integer {set look($class:$name) $@$name} - choice|language { - if {$@$name == "autolanguage"} {set l auto} {set l $@$name} - set look($class:$name) $l - } - #font {set look(View:font) $@str} - } - } -} -def ClientPrefsDialogue reset {} { - # this should reload defaults.ddrc ? -} -def ClientPrefsDialogue revert {} { - # this should reload currently used settings ? -} -def ClientPrefsDialogue init {} { - global look key - super cancel apply ok - #super cancel reset revert apply ok - set f .$self.1 - set section 0 - set subsection 0 - set @label_width 200 ;# 24 - foreach {type class names} $::ddrc_options { - set name [lindex [split $names |] 0] - switch $type { void { set type toggle }} - switch $type { - section { - incr section - $@nb add [ttk::notebook $@nb.$section] -text [say $name] - set which_section $f.$section - set which_self $self - set subsection 0 - } - subsection { - set subself $self.1.$section - .$subself add [frame .$subself.[incr subsection]] -text [say $name] - set which_section .$subself.$subsection - set which_self $subself - } - language { - set @$name $look(View:$name) - say autolanguage "[say auto] ([say [lindex [figure_out_language [guess_lang]] 1]])" - $self add $which_section [list $name choice -choices [concat autolanguage $::langoptions]] - } - color { - set str [string tolower $class$name] - set @$str $look($class:$name) - $self add $which_section [list $str $type] - } - key { - foreach item $name {set @$item $key($class:$item)} - $self add $which_section [list $name $type] - } - toggle { - set @$name $look($class:$name) - $self add $which_section [list $name $type] - } - font { - set str [string tolower $class$name] - set @$str $look($class:$name) - $self add $which_section [list $str $type $class] - } - default { - switch $name { - console {set @$name $look(Client:console)} - pointer_sense {set @$name $look(Canvas:pointer_sense)} - grid_size {set @$name $look(Canvas:grid_size)} - default {} - } - $self add $which_section [list $name $type] - } - } - } -} -def ClientPrefsDialogue dropmenu_set {frame var part val} {set @$var $part; $frame.butt configure -text [say $part]} -def ClientPrefsDialogue dropmenu_open {f name} {super $f} - -############ find dialogue ########### - -class_new FindDialogue {Dialogue} -def FindDialogue init {canvas} { - super cancel find - set @canvas $canvas - set @break 0 - set f .$self - $self add $f [list "string" "entry"] - focus .find.string.entry -} -def FindDialogue find {} {$self ok} -def FindDialogue ok {} { - $@canvas find_string= $@string - $@canvas search - super -} -############ other stuff ######### - -def Client client_class_tree {} {ClientClassTreeDialogue new} -class_new ClientClassTreeDialogue {Dialogue} - -proc* place_stuff {args} {} - -def ClientClassTreeDialogue make_row {w tree} { - pack [frame $w] -fill x - pack [frame $w.row] -side top -fill x - pack [button $w.row.butt -image icon_minus] -side left - pack [label $w.row.label -text [lindex $tree 0]] -side left -fill x - pack [frame $w.dent -width 32] -side left - set i 1 - foreach node [lrange $tree 1 end] { - $self make_row $w.$i $node - incr i - } -} -def ClientClassTreeDialogue init {} { - super close - pack [frame .$self.1 -width 600 -height 400] -fill y -expand y - pack [frame .$self.1.1 -width 600 -height 400 -bg "#6688aa"] -side left -fill y -expand y - # "$w.1.scroll set" - # i'd like a scrollable frame - pack [scrollbar .$self.1.scroll -command "ClientClassTreeDialogue_scroll $self"] -side left -fill y -expand y - place [frame .$self.1.1.tree] -x 0 -y 0 - set w .$self.1.1.tree.1 - $self make_row $w [Thing get_hierarchy] - after 100 "$self update_scrollbar" -} -def ClientClassTreeDialogue update_scrollbar {} { - set w .$self.1.1 - set zy [winfo height $w] - set sy [winfo height $w.tree] - set y1 [expr 0.0-[winfo y $w.tree]] - set y2 [expr 0.0+$y1+$zy] - .$self.1.scroll set [expr $y1/$sy] [expr $y2/$sy] -} -def ClientClassTreeDialogue scroll {args} { - set w .$self.1.1 - set zy [winfo height $w] - set sy [winfo height $w.tree] - switch [lindex $args 0] { - moveto { - set y [clip [expr (0.0-[lindex $args 1])*$sy] [expr $zy-$sy] 0] - place .$self.1.1.tree -x 0 -y $y - puts "args=[list $args] zy=$zy sy=$sy y=$y" - } - scroll { - } - } - after 100 "$self update_scrollbar" -} - -class_new AboutDialogue {Dialogue} -def AboutDialogue init {} { - super close - wm title .$self "About DesireData" - pack [label .$self.title -text $::pd_version -font {helvetica 18}] -side top - pack [text .$self.text -yscrollcommand ".$self.scroll set" -width 72 -height 36] -side left -fill both -expand yes - pack [scrollbar .$self.scroll -command ".$self.text yview"] -side right -fill y -expand yes -#12345678901234567890123456789012345678901234567890123456789012345678901 <- 72 chars - .$self.text insert 0.0 \ -"DesireData is a free (libre) real-time computer programming language -interpreter focused on realtime audio and video. -You can get DesireData from http://desiredata.goto10.org/ - -DesireData and PureData work on Linux, MacOSX, Windows, and others. - -PureData is copyrighted, but is free for you to use for any reasonable -purpose, according to the SIBSD license. DesireData's client section -also is free, according to the GPL license. DesireData's server section -is an adaptation of the PureData code and is also using the SIBSD -license. - -(insert here: links to both licenses) - -Credits: - DesireData server: Mathieu Bouchard - DesireData client: Mathieu Bouchard & Chun Lee - PureData: Miller Puckette feat. Thomas Musil, - Gnther Geiger, Krzysztof Czaja, Iohannes Zmlnig & others. - - Translations: - Franais (French): Patrice Colet - Catal (Catalan): Nria Verges - Espaol (Spanish): Mario Mora, Ramiro Cosentino - Deutsch (German): Max Neupert, Georg Holzmann, Thomas Grill - Norsk Bokml (Norwegian): Gisle Frysland - Portugus (Portuguese): Nuno Godinho - Portugus do Brasil (Brazilian Portuguese): Carlos Paulino - Italiano (Italian): Davide Morelli, Federico Ferri - Euskara (Basque): Ibon Rodriguez Garcia - Nihongo (Japanese): Kentaro Fukuchi - Polski (Polish): Michal Seta - Dansk (Danish): Steffen Leve Poulsen - Zong wen (Chinese): Chun Lee - Nederlands (Dutch): Tim Vets - Trke (Turkish): Koray Tahiroglu - Russkij (Russian): Ilya Dmitrichenko - -Much more documentation and other resources at http://puredata.info/ -The Pd mailing list archive at http://lists.puredata.info/pipermail/pd-list/ - -(insert here: link to \"reference documentation for Pd\", that is, chapter 1)" - - # this looks bad on OSX, iirc - .$self.text configure -state disabled -} - -set manager [Manager new] - -def Class post_hierarchy {{i 0}} { - post %*s%s [expr $i*2] "" $self - foreach sub $@subclasses {$sub post_hierarchy [expr $i+1]} -} -def Class get_hierarchy {} { - set l [list $self] - foreach sub $@subclasses {lappend l [$sub get_hierarchy]} - return $l -} - -# Thing post_hierarchy - -#---------------------------------------------------------------- -class_new ClipboardDialogue {Dialogue} -def ClipboardDialogue init {clipboard} { - super close - set @clipboard $clipboard - wm title .$self "Clipboard" - pack [text .$self.text -yscrollcommand ".$self.scroll set" -width 72] -side left -fill both -expand yes - pack [scrollbar .$self.scroll -command ".$self.text yview"] -side right -fill y - $@clipboard subscribe $self - $self notice -} -def ClipboardDialogue notice {args} { - .$self.text delete 0.0 end - .$self.text insert 0.0 [$@clipboard value] -} -def ClipboardDialogue delete {} { - $@clipboard unsubscribe $self - super -} - -#---------------------------------------------------------------- -class_new ListDialogue {Dialogue} -def ListDialogue init {history title} { - super close - set @history $history - wm title .$self $title - frame .$self.1 - pack [listbox .$self.1.list -yscrollcommand ".$self.1.scroll set" -width 72 -height 20] -side left -fill both -expand yes - pack [scrollbar .$self.1.scroll -command ".$self.1.list yview"] -side right -fill y - pack .$self.1 - $@history subscribe $self - $self notice -} -def ListDialogue listbox {} {return .$self.1.list} -def ListDialogue notice {args} { - set w [$self listbox] - $w delete 0 end - foreach e [$@history list] {$w insert end $e} - $w see end -} -def ListDialogue delete {} { - $@history unsubscribe $self - super -} - -class_new EventHistoryDialogue {ListDialogue} -def EventHistoryDialogue init {history} { - super $history [say event_history_view] - pack [checkbutton .$self.hide -text [say hide_key_release]] -fill x - [$self listbox] configure -font {Mono -10} -} - -#---------------------------------------------------------------- -#class_new Splash {Thing} -#def Splash init {} { -# toplevel .$self -# frame .$self.f -# canvas .$self.f.canvas -# image create photo .dd -format GIF -file desiredata.gif -# .$self.f.canvas create image 0 0 -image .dd -# pack .$self.f.canvas -# pack .$self.f -#} - -class_new KeyboardDialogue {Dialogue} - -set keyboard_layouts { - { - {9 " " 67 68 69 70 " " 71 72 73 74 " " 75 76 95 96} - {49 10 11 12 13 14 15 16 17 18 19 20 21 22} - {23 24 25 26 27 28 29 30 31 32 33 34 35 51} - {66 38 39 40 41 42 43 44 45 46 47 48 36} - {50 52 53 54 55 56 57 58 59 60 61 62} - {37 115 64 65 113 116 117 109} - } { - {" " " " 98 " "} - {100 " " " " 102} - {" " " " 104 " "} - {" "} - {" " " " 4 " "} - {1 2 3} - {" " " " 5 " "} - } -} - -foreach {k v} { - 9 5 - 22 5 - 23 4 51 4 - 66 5 36 7 - 50 8 62 8 - 37 4 115 4 64 4 65 24 113 4 116 4 117 4 109 4 - 98 2 100 2 102 2 104 2 - 1 2 2 2 3 2 4 2 5 2 -} {set keyboard_width_of($k) $v} - -proc namekey {i args} {foreach name $args {set ::keyboard_text_of($i) $name; incr i}} -namekey 9 Esc -namekey 67 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 -namekey 95 F11 F12 -namekey 49 ` -namekey 10 "1 !" "2 @" "3 #" "4 \$" "5 %" "6 ^" "7 &" "8 *" "9 (" "0 )" "- _" "= +" BkSp -namekey 23 Tab Q W E R T Y U I O P "\{ \[" "\} \]" -namekey 51 "\\ |" -namekey 66 Caps -namekey 38 A S D F G H J K L "\; :" "' \"" -namekey 36 Return -namekey 50 Shift -namekey 52 Z X C V B N M ", <" ". >" "/ ?" Shift -namekey 37 Ctrl -namekey 115 Sup -namekey 64 Alt Space -namekey 113 AltGr -namekey 116 Sup Menu -namekey 109 Ctrl -namekey 98 (up) -namekey 100 (left) -namekey 102 (right) -namekey 104 (down) -namekey 1 1 2 3 4 5 -#mouse clicks - -def KeyboardDialogue init {history} { - super close - set @history $history - set @fade [dict create] - wm title .$self "Keyboard View" ;# say - set i 0; set j 0 - set @names {key misc} - frame .$self.board - set layouts {::keyboard_layout ::keyboard_layout2} - set @keycount 0 - foreach layout $::keyboard_layouts { - $self pack_keys $layout [lindex $@names $i] [llength [lindex $::keyboard_layouts [expr $i-1]]] - incr i - } - pack .$self.board - $@history subscribe $self - $self fade -} - -def KeyboardDialogue pack_keys {keys name off} { - set i $off - frame .$self.board.$name - foreach row $keys { - frame .$self.board.$name.$i - foreach key $row { - if {$key==" "} { - pack [label .$self.board.$name.$i.shim$@keycount -image icon_empty] -side left - incr @keycount - continue - } - set ::keyboard_row_of($key) $i - if {[info exists ::keyboard_width_of($key)]} {set width $::keyboard_width_of($key)} else {set width 3} - if {[info exists ::keyboard_text_of($key)]} {set text $::keyboard_text_of($key) } else {set text $key} - if {[regexp {\((\w+)\)} $text foo bar]} { - set font [$self look font] - pack [label .$self.board.$name.$i.key$key -image icon_$bar -relief raise -border 4 \ - -side left -bg "#dddddd" -width [expr $width*[font measure $font 0]] \ - -height [font metrics $font -linespace]] - } else { - pack [label .$self.board.$name.$i.key$key -text " $text " -relief raise -border 4 \ - -side left -bg "#dddddd" -width $width -font [$self look font]] - } - } - pack .$self.board.$name.$i -fill x - if {$i==0} {pack [label .$self.board.$name.shim -image icon_empty] -fill x -expand yes} - incr i - } - switch $name { - key {pack .$self.board.key -side left} - misc {pack .$self.board.misc -side right} - } -} - -def KeyboardDialogue notice {origin add event} { - mset {type W x y mod K k} $event - if {![info exists ::keyboard_row_of($k)]} {puts "unknown key $k"; return} - set i $::keyboard_row_of($k) - if {$i<[llength [lindex $::keyboard_layouts 0]]} {set section "key"} else {set section "misc"} - switch -regexp -- $type { - ^KeyPress|ButtonPress$ { - if { [dict exists $@fade $k]} {dict unset @fade $k} - .$self.board.$section.$i.key$k configure -bg "#ff0000" - } - ^KeyRelease|ButtonRelease$ {if {![dict exists $@fade $k]} {dict set @fade $k 255}} - } -} - -def KeyboardDialogue fade {} { - foreach {k v} $@fade { - incr v -85 - if {$v<0} {set v 0} - set r [expr 221+$v*2/15] - set g [expr 221-$v*13/15] - set i $::keyboard_row_of($k) - if {$i<[llength [lindex $::keyboard_layouts 0]]} {set section "key"} else {set section "misc"} - .$self.board.$section.$i.key$k configure -bg [format #%02x%02x%02x $r $g $g] - if {$v} {dict set @fade $k $v} {dict unset @fade $k} - } - set @after [after 100 "$self fade"] -} - -def KeyboardDialogue delete {} { - $@history unsubscribe $self - after cancel $@after - super -} - -#---------------------------------------------------------------- -# Deconstructors - -def Wire deconstruct {{selcanvas ""}} { - # the selcanvas system could be abstracted out using an ObjectList such that - # Canvas<ObjectList and $selection class == ObjectList - if {$selcanvas == ""} { - list #X connect \ - [[$@canvas objects] search $@from] $@outlet \ - [[$@canvas objects] search $@to] $@inlet - } { - list #X connect \ - $::obj_index_sel($@canvas:$@from) $@outlet \ - $::obj_index_sel($@canvas:$@to) $@inlet - } -} - -def MessageBox deconstruct {} {concat [list #X msg $@x1 $@y1] $@text} -def FloatBox deconstruct {} {concat [list #X floatatom $@x1 $@y1] $@w $@min $@max $@pos $@lab $@snd $@rcv} -def SymbolBox deconstruct {} {concat [list #X symbolatom $@x1 $@y1] $@w $@min $@max $@pos $@lab $@snd $@rcv} -def Comment deconstruct {} {concat [list #X text $@x1 $@y1] $@text} - -def Box deconstruct {} { - if {[array names ::fields -exact $@pdclass] == ""} { - return [concat [list #X obj $@x1 $@y1] $@text] - } { - set r {} - foreach field $::fields($@pdclass) {lappend r $_($self:$field)} - return $r - } -} - -def View deconstruct_to {stream args} { - $stream << [philtre [eval [concat [list $self deconstruct] $args]]] - $stream << ";\n" -} - -def Canvas deconstruct {} { - return [concat [list #X restore $@x1 $@y1] $@text] -} -def Canvas deconstruct_to {stream args} { - set r [concat [list #N canvas] $@canvas_pos $@canvas_size] - if {$@subpatch || $@abs} {lappend r $@name $@mapped} else {lappend r $@fontsize} - $stream << "[philtre $r];\n" - foreach i [lsort -integer [$@objects keys]] {eval [concat [list [$@objects get $i] deconstruct_to $stream]]} - foreach i [lsort -integer [ $@wires keys]] {eval [concat [list [ $@wires get $i] deconstruct_to $stream]]} - $stream << [philtre [eval [concat [list $self deconstruct] $args]]] - $stream << ";\n" -} - -#---------------------------------------------------------------- -# openpanel & savepanel - -proc pdtk_openpanel {target localdir} { - if {$localdir == ""} {set localdir $::pd_opendir} - set filename [tk_getOpenFile -parent $::current_window -initialdir $localdir] - if {$filename != ""} { - set directory [string range $filename 0 [expr [string last / $filename]-1]] - set pd_opendir $directory - netsend [list $target callback [enquote $filename]] - } -} - -proc pdtk_savepanel {target localdir} { - if {$localdir == ""} { - set filename [tk_getSaveFile -parent $::current_window] - } else { - set filename [tk_getSaveFile -parent $::current_window -initialdir $localdir] - } - if {$filename != ""} { - netsend [list $target callback [enquote $filename]] - } -} - -#---------------------------------------------------------------- -# To err is human. - -#proc bgerror {err} { -# set info [error_dump] -# tk_messageBox2 -message "$err: $info" -type ok -#} - -class_new OopsDialogue {Dialogue} - -def OopsDialogue init {sig1 sig2 where} { - super damn - wm title .$self [say oops] - pack [label .$self.head -text $sig2 -font {Helvetica -14 bold}] -side top - pack [label .$self.note -text [say oops_text]] -side top - pack [text .$self.text -yscrollcommand ".$self.scroll set" -width 108 -height 15] -side left -fill both -expand 1 - pack [scrollbar .$self.scroll -command ".$self.text yview"] -side right -fill y - .$self.text insert 0.0 $where -} - -# Nous sommes donc en prsence d'un incendie. C'est normal... -def OopsDialogue damn {} {$self ok} - -#---------------------------------------------------------------- - -set main [Client new] -set window_list [list $main] - -def Canvas auto_test {} { - $self editmode= 1 - $self select_all - $self selection_move +10 0 - $self selection_move +10 0 - $self selection_move +10 0 -} - -#----------------------------------------------------------------- -def Canvas visual_diff {} { - if {$@blinky != ""} { - .$self.c delete BLINKY - after cancel $@blinky - set @blinky "" - return - } - set filename [$self name] - set initialfile "" - foreach suffix {gif jpg jpeg png} { - set t [$self folder]/$filename.$suffix - post %s $t - if {[file exist $t]} {set initialfile $filename.$suffix; break} - } - set filename [tk_getOpenFile -parent $::current_window -defaultextension .pd \ - -filetypes $::image_filetypes -initialdir [$self folder] -initialfile $initialfile] - if {$filename == ""} {return} - image create photo image_$self -file $filename - $self blink_image -} - -def Canvas blink_image {} { - set @blinky [after 300 [list $self blink_image]] - if {[llength [.$self.c gettags BLINKY]]} { - .$self.c delete BLINKY - } else { - # there's something that causes the pd screenshot to be off by 1 pixel. i don't know what. - .$self.c create image 0 -1 -image image_$self -tag BLINKY -anchor nw - } -} - -#----------------------------------------------------------------- - -proc widget_tree {w {indent 0}} { - foreach element [winfo children $w] { - puts [format "%*s%s" [expr 2*$indent] "" $element] - widget_tree $element [expr 2+$indent] - } -} - -if 0 { -def Canvas :-) {} { - if {![info exists ::pd_path]} {netsend [list pd update-path]} - if {![info exists ::class_list]} {return [netsend [list pd update-class-list $self :-)]]} - search_for_externs - set class_list [luniq [lsort $::class_list]] - set n 0 - post "there are [llength $::class_list] classes" - foreach c $::class_list { - netsend [list .$self obj [expr int(1050*rand())] [expr int(650*rand())] $c] - incr n - if {$n>1500} {return "stopped at $n"} - } - return "finished" -} -} - -def Canvas :-) {} { - if {![info exists ::pd_path]} {netsend [list pd update-path]} - if {![info exists ::class_list]} {return [netsend [list pd update-class-list $self :-)]]} - search_for_externs - set ::class_list [luniq [lsort $::class_list]] - post "there are [llength $::class_list] classes" - $self :-)2 1000 "" -} - -def Canvas :-)2 {n meuh} { - if {$n >= [llength $::class_list]} {return} - set c [lindex $::class_list $n] - set x [expr int(1050*rand())]; set y [expr int(650*rand())] - set x [expr int($n/36)*16]; set y [expr ($n%36)*18] - puts ":-) $c" - netsend [list .$self obj $x $y $c] [list $self :-)2 [expr {$n+1}]] - #if {$n>1500} {post "stopped at %d" $n} -} - -proc pd {args} {post %s "what is 'proc pd' ?"} diff --git a/desiredata/src/dzinc.tcl b/desiredata/src/dzinc.tcl deleted file mode 100644 index f85f5539..00000000 --- a/desiredata/src/dzinc.tcl +++ /dev/null @@ -1,157 +0,0 @@ -package provide dzinc 0.1 -package require Tkzinc - -class_new Zinc {Thing} -def Zinc init {} { - set @group [eval old_$self add group 1] -} -def Zinc unknown {args} { - upvar 1 selector selector - old_$self $selector {expand}$args -} - -rename canvas old_canvas - -proc option_replace {argz} { - #set new_args {} - foreach {option val} $argz { - switch -- $option { - -bg {set option -backcolor} - -background {set option -backcolor} - -bd {set option -borderwidth} - } - lappend new_args $option $val - } - puts "new_args:::: $new_args" - return $new_args -} -#.bgerrorDialog.bitmap create oval 0 0 31 31 -fill red -outline black -#.x80e1c00.c -width 446 -height 296 -background white -proc canvas {name args} { - set result [eval [concat [list zinc $name] [option_replace $args] -highlightthickness 1]] - Zinc new_as $name - return $result -} - -def Zinc remove {orig mess} { - set idx [lsearch $mess $orig] - if {$idx < 0} {return $mess} - set mess [lreplace $mess $idx $idx+1] - return $mess -} - - -def Zinc replace {orig new mess} { - set idx [lsearch $mess $orig] - if {$idx < 0} {return $mess} - set mess [lreplace $mess $idx $idx $new] - return $mess -} - -def Zinc replace2 {orig new mess} { - set idx [lsearch $mess $orig] - if {$idx < 0} {return $mess} - set mess [lreplace $mess $idx $idx+1] - foreach item [lreverse $new] {set mess [linsert $mess $idx $item]} - return $mess -} - -def Zinc insert {orig new mess} { - set idx [lsearch $mess $orig] - if {$idx < 0} {return $mess} - #set mess [lreplace $mess $idx $idx+1] - foreach item [lreverse $new] {set mess [linsert $mess $idx $item]} - return $mess -} - - -def Zinc canvasx {val} { - return $val -} - -def Zinc canvasy {val} { - return $val -} - -def Zinc substitude {args} { - set args [$self replace -width -linewidth $args] - set args [$self replace -fill -linecolor $args] - set args [$self replace2 -dash [list -linestyle dotted] $args] - set args [$self replace -outline -linecolor $args] - set args [$self remove -dashoffset $args] - return $args -} - -def Zinc create {args} { - set i 0 - foreach item $args { - if {[regexp {^-} $item]} {break} - incr i - } - switch [lindex $args 0] { - line { - set type curve - set args [$self replace -width -linewidth $args] - set args [$self replace -fill -linecolor $args] - set args [$self replace2 -dash [list -linestyle dotted] $args] - set args [$self remove -dashoffset $args] - } - oval { - set type arc - set args [$self replace -fill -fillcolor $args] - set args [$self replace -outline -linecolor $args] - } - window { - set type window - } - rectangle { - set type rectangle - set args [$self replace -fill -fillcolor $args] - set args [$self replace -outline -linecolor $args] - set args [$self replace -width -linewidth $args] - set args [$self replace2 -dash [list -linestyle dotted] $args] - } - text { - set type text - set args [$self replace -fill -color $args] - } - default { - puts "UNKNOWN ITEM.. [lindex $args 0]" - } - } - if {$i == 2} { - set mess [concat $type $@group [lrange $args 1 end]] - } else { - set mess [concat $type $@group [list [lrange $args 1 $i-1]] [lrange $args $i end]] - } - if {$type == "window" || $type == "text"} {set mess [linsert $mess 2 -position]} - #puts "mess >> $mess" - eval [concat [list old_$self add] $mess] -} - -def Zinc itemconfigure {args} { - set mess [$self substitude $args] - eval [concat [list old_$self itemconfig] $mess] -} - -def Zinc coords {args} { - eval [concat [list old_$self coords] [lindex $args 0] [list [lrange $args 1 end]]] -} - - -def Zinc configure {args} { - eval [concat [list old_$self configure] [option_replace $args]] -} - -def Zinc delete {args} { - eval [concat [list old_$self remove] $args] -} - -def Zinc gettags {args} { - set result {} ;# bogus - catch {set result [eval [concat [list old_$self gettags] $args]]} - return $result -} - -def Zinc lower {tag args} { -}
\ No newline at end of file diff --git a/desiredata/src/icons/array.gif b/desiredata/src/icons/array.gif Binary files differdeleted file mode 100644 index 1a5ecfb2..00000000 --- a/desiredata/src/icons/array.gif +++ /dev/null diff --git a/desiredata/src/icons/bang.gif b/desiredata/src/icons/bang.gif Binary files differdeleted file mode 100644 index 28f708e1..00000000 --- a/desiredata/src/icons/bang.gif +++ /dev/null diff --git a/desiredata/src/icons/canvas.gif b/desiredata/src/icons/canvas.gif Binary files differdeleted file mode 100644 index bcff6924..00000000 --- a/desiredata/src/icons/canvas.gif +++ /dev/null diff --git a/desiredata/src/icons/comment.gif b/desiredata/src/icons/comment.gif Binary files differdeleted file mode 100644 index f40d6bf2..00000000 --- a/desiredata/src/icons/comment.gif +++ /dev/null diff --git a/desiredata/src/icons/graph.gif b/desiredata/src/icons/graph.gif Binary files differdeleted file mode 100644 index e543e1d3..00000000 --- a/desiredata/src/icons/graph.gif +++ /dev/null diff --git a/desiredata/src/icons/hradio.gif b/desiredata/src/icons/hradio.gif Binary files differdeleted file mode 100644 index 16040321..00000000 --- a/desiredata/src/icons/hradio.gif +++ /dev/null diff --git a/desiredata/src/icons/hslider.gif b/desiredata/src/icons/hslider.gif Binary files differdeleted file mode 100644 index 4a08a376..00000000 --- a/desiredata/src/icons/hslider.gif +++ /dev/null diff --git a/desiredata/src/icons/message.gif b/desiredata/src/icons/message.gif Binary files differdeleted file mode 100644 index 57983c53..00000000 --- a/desiredata/src/icons/message.gif +++ /dev/null diff --git a/desiredata/src/icons/mode_edit.gif b/desiredata/src/icons/mode_edit.gif Binary files differdeleted file mode 100644 index 30902f10..00000000 --- a/desiredata/src/icons/mode_edit.gif +++ /dev/null diff --git a/desiredata/src/icons/mode_run.gif b/desiredata/src/icons/mode_run.gif Binary files differdeleted file mode 100644 index 1d6ea182..00000000 --- a/desiredata/src/icons/mode_run.gif +++ /dev/null diff --git a/desiredata/src/icons/number.gif b/desiredata/src/icons/number.gif Binary files differdeleted file mode 100644 index 7830e949..00000000 --- a/desiredata/src/icons/number.gif +++ /dev/null diff --git a/desiredata/src/icons/number2.gif b/desiredata/src/icons/number2.gif Binary files differdeleted file mode 100644 index 027562fe..00000000 --- a/desiredata/src/icons/number2.gif +++ /dev/null diff --git a/desiredata/src/icons/object.gif b/desiredata/src/icons/object.gif Binary files differdeleted file mode 100644 index ddec4903..00000000 --- a/desiredata/src/icons/object.gif +++ /dev/null diff --git a/desiredata/src/icons/symbol.gif b/desiredata/src/icons/symbol.gif Binary files differdeleted file mode 100644 index 0169009f..00000000 --- a/desiredata/src/icons/symbol.gif +++ /dev/null diff --git a/desiredata/src/icons/toggle.gif b/desiredata/src/icons/toggle.gif Binary files differdeleted file mode 100644 index 90c1fc05..00000000 --- a/desiredata/src/icons/toggle.gif +++ /dev/null diff --git a/desiredata/src/icons/vradio.gif b/desiredata/src/icons/vradio.gif Binary files differdeleted file mode 100644 index 5649c31f..00000000 --- a/desiredata/src/icons/vradio.gif +++ /dev/null diff --git a/desiredata/src/icons/vslider.gif b/desiredata/src/icons/vslider.gif Binary files differdeleted file mode 100644 index 5920c207..00000000 --- a/desiredata/src/icons/vslider.gif +++ /dev/null diff --git a/desiredata/src/icons/vu.gif b/desiredata/src/icons/vu.gif Binary files differdeleted file mode 100644 index bbc6142f..00000000 --- a/desiredata/src/icons/vu.gif +++ /dev/null diff --git a/desiredata/src/install-sh b/desiredata/src/install-sh deleted file mode 100644 index e9de2384..00000000 --- a/desiredata/src/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/desiredata/src/iostream.txt b/desiredata/src/iostream.txt deleted file mode 100644 index 5ed2bf25..00000000 --- a/desiredata/src/iostream.txt +++ /dev/null @@ -1,61 +0,0 @@ -------------------8<--------cut-here--------8<------------------ -Dec 26 2005 - -1.1. a OutByteStream object is one that accepts those messages on inlet 0: - * float: seen as a byte (0..255) - * list of floats: seen as a sequence of float messages. - * symbol: seen as a \0-terminated string. - * bang: forces buffer-flushing if there's a buffer. - -1.2. a OutByteStream object may also optionally respond to string - messages, in my dreams. However, in the meanwhile, it may be more - appropriate to use a new special C function that accepts a pair of - int and const char * (\0 is not honored: the int specifies the size). - This is so that there is no speed disincentive to switch to decoupled - I/O objects. - -2.1. an InByteStream object is one that accepts those messages on inlet 0: - * bang: polls for more input (unlimited size). - * float: treated as int. polls for at most N bytes. - * auto 0: requires bang for getting more input. - * auto 1: uses a t_clock (hidden [metro]) for auto-polling. - -2.2. an InByteStream may produce those messages: - * float: seen as a byte (0..255) - * list of floats: seen as a sequence of float messages. - -and when in "auto 0" mode, it will only send it when receiving a bang or -float. - -2.2. an InByteStream object may also optionally produce string - messages, in my dreams, etc. What would the C function(s) look like - in this case? - -3. an IOByteStream object is just an InByteStream object and an -OutByteStream object at the same time. There is no conflict between the -two. - -4. there would be object classes called [tcp] and [udp] which would be - InputOutputStream objects (supporting in, out and bidi connections). - They would also respond to "connect" and "disconnect" (or maybe "open" - and "close" instead) and also "listen" for enabling server mode. - -5. there would be an object class called [fudiin] which would be an -OutByteStream and [fudiout] which would be an InByteStream. Thus, to get a -bidirectional [netsend] [netreceive], use this triad: - - | -[fudiout] - | -[tcp] - | -[fudiin] - | - -Leaving out the first or the last object gives you [netsend] and -[netreceive] respectively. - -6. a [tcp]<->[fudiin] pair can replace the server-side of the GUI - connection as long as the [tcp] object supports char* input as - suggested in part 1.2. (if the rest of this proposal is not - implemented, then use a slightly modified [netreceive] instead) diff --git a/desiredata/src/kb-mode.tcl b/desiredata/src/kb-mode.tcl deleted file mode 100644 index 08adce28..00000000 --- a/desiredata/src/kb-mode.tcl +++ /dev/null @@ -1,210 +0,0 @@ -package provide kb-mode 0.1 - -set kbmode 1 - -proc kb-mode_init {canvas} { - puts "init kb-mode" - set self "kbcursor" - append_callback kb-mode key kb-mode_key - Kb_cursor new_as $self $canvas - $self draw - return $self -} - -def Canvas kb-mode_key {x y key iso shift} { - set c [$self widget] - set step [$@kbcursor step] - if {$@keyprefix} { - $@kbcursor get_key $key - set @keyprefix 0 - } - switch $key { - BackSpace {$self delete_selection} - Up {$@kbcursor move 0 -$step; if {$shift} {$self arrow_key 0 -$step}} - Down {$@kbcursor move 0 +$step; if {$shift} {$self arrow_key 0 +$step}} - Left {$@kbcursor move -$step 0; if {$shift} {$self arrow_key -$step 0}} - Right {$@kbcursor move +$step 0; if {$shift} {$self arrow_key +$step 0}} - t {$self kbcursor_select} - Return {$self return_key $x $y $key $iso $shift} - default {} - } -} - -def Canvas kbcursor_move_up {} {$@kbcursor move 0 -[$@kbcursor step]} -def Canvas kbcursor_move_down {} {$@kbcursor move 0 [$@kbcursor step]} -def Canvas kbcursor_move_left {} {$@kbcursor move -[$@kbcursor step] 0} -def Canvas kbcursor_move_right {} {$@kbcursor move [$@kbcursor step] 0} - -def Canvas move_selection_up {} {$self arrow_key 0 -[$@kbcursor step]} -def Canvas move_selection_down {} {$self arrow_key 0 +[$@kbcursor step]} -def Canvas move_selection_left {} {$self arrow_key -[$@kbcursor step] 0} -def Canvas move_selection_right {} {$self arrow_key 0 +[$@kbcursor step] 0} - -class_new Kb_cursor {View} - -def Kb_cursor init {canvas} { - super - set @canvas $canvas - set @x 200 - set @y 200 - set @h [expr [font metrics [$self look font] -linespace]+3] - set @step [expr ceil($@h*1.5)] - set @prefixkeys {} - $self init_keys - $self recenter -} - - -def Kb_cursor xy {} {return [list $@x $@y]} -def Kb_cursor step {} {return $@step} - -def Kb_cursor draw {} { - set c [$@canvas widget] - set line1 [list $@x $@y $@x [expr $@y+$@h]] - set line2 [list $@x $@y [expr $@x+3] $@y] - set line3 [list $@x [expr $@y+$@h-1] [expr $@x+3] [expr $@y+$@h-1]] - $self item LINE1 line $line1 -fill red -width 2 - $self item LINE2 line $line2 -fill red -width 1 - $self item LINE3 line $line3 -fill red -width 1 - - $c raise $self -} - -def Kb_cursor move {x y} { - set @x [expr $@x + $x] - set @y [expr $@y + $y] - $self test_bounds - $self draw - set action [$@canvas action] - if {$action != "none"} { - if {[$action class] == "SelRect"} { - $action motion $@x $@y 256 "none" - } - - } -} - -def Kb_cursor scroll_canvas {} { - set c [$@canvas widget] - mset {x1 y1 x2 y2} [$c bbox all] - puts "xview [$c xview]" - set x2 [expr $x2]; set y2 [expr $y2] -} - -def Kb_cursor test_bounds {} { - set c [$@canvas widget] - set width [winfo width $c]; set height [winfo height $c] - set x1 [$c canvasx 2]; set y1 [$c canvasy 2] - set x2 [expr $x1+$width-2] - set y2 [expr $y1+$height-2] - if {$@x >= $x2} {$self scroll r [expr int($@x-$x2)]} - if {$@x <= $x1} {$self scroll l [expr int($@x-$x1)]} - if {$@y >= $y2} {$self scroll b [expr int($@y-$y2)]} - if {$@y <= $y1} {$self scroll t [expr int($@y-$y1)]} -} - -def Kb_cursor scroll {direction diff} { - set c [$@canvas widget] - set width [winfo width $c]; set height [winfo height $c] - set x1 [$c canvasx 2]; set y1 [$c canvasy 2] - mset {l r} [$c xview] - mset {t b} [$c yview] - foreach {n0 n1 n2 n3 region} [$c configure -scrollregion] {mset {rx1 ry1 rx2 ry2} $region} - switch $direction { - r {set axis "x"; if {$r == 1} {set rx2 [expr $rx2+$width]}} - l {set axis "x"; if {$l == 0} {set rx1 [expr $rx1-$width]}} - b {set axis "y"; if {$b == 1} {set ry2 [expr $ry2+$height]}} - t {set axis "y"; if {$t == 0} {set ry1 [expr $ry1-$height]}} - } - $c configure -scrollregion [list $rx1 $ry1 $rx2 $ry2] - $c [list $axis]view scroll $diff units -} - -def Canvas kbcursor_recenter {} {$@kbcursor recenter} - -def Kb_cursor recenter {} { - set c [$@canvas widget] - set width [winfo width $c]; set height [winfo height $c] - set x1 [$c canvasx 2]; set y1 [$c canvasy 2] - set x2 [expr $x1+$width] - set y2 [expr $y1+$height] - set @x [expr $x1+($width/2)] - set @y [expr $y1+($height/2)] - $self draw -} - -def Canvas kbcursor_Object {} {mset {x y} [$@kbcursor xy]; $self new_objectxy [expr $x+4] $y obj} -def Canvas kbcursor_Message {} {mset {x y} [$@kbcursor xy]; $self new_objectxy [expr $x+4] $y msg} -def Canvas kbcursor_bng {} {mset {x y} [$@kbcursor xy]; $self new_objectxy [expr $x+4] $y obj bng} -def Canvas kbcursor_tgl {} {mset {x y} [$@kbcursor xy]; $self new_objectxy [expr $x+4] $y obj tgl} -def Canvas kbcursor_nbx {} {mset {x y} [$@kbcursor xy]; $self new_objectxy [expr $x+4] $y obj nbx} - -def Canvas kbcursor_select {} { - mset {x y} [lmap + [$@kbcursor xy] 4]; set x [expr $x+4] - mset {type id detail} [$self identify_target $x $y 0] - puts "type:: $type || id:: $id || detail:: $detail" - if {$type == "object"} { - if {![$id selected?]} {$self selection+= $id} else {$self selection-= $id} - } -} - -def Kb_cursor init_keys {} { - global newkey accels - #@keys used for prefix keycommands - dict set @prefixkeys "1" "kbcursor_Object" - dict set @prefixkeys "2" "kbcursor_Message" - dict set @prefixkeys "b" "kbcursor_bng" - dict set @prefixkeys "t" "kbcursor_tgl" - dict set @prefixkeys "3" "kbcursor_nbx" - #@ctrlkeys overwrites the existing keybindings - foreach {key command} $newkey { - if {[catch {set vars [dict get $accels $key]}]} {puts "$key not bound yet......";set vars {}} - set new_val {} - foreach item $vars { - mset {class cmd} [split $item ":"] - if {$class == [$@canvas class]} { - set n $class:$command - lappend new_val $n - } else { - lappend new_val $item - } - } - if {$new_val == ""} {set new_val [$@canvas class]:$command} - dict set accels $key $new_val - } - -} - -def Kb_cursor get_key {key} { - if {[catch {set command [dict get $@prefixkeys $key]}]} { - post "key Ctrl-x $key not bound" - } { - puts "run $command" - $@canvas $command - } -} - -set newkey { - Ctrl+p {kbcursor_move_up} - Ctrl+n {kbcursor_move_down} - Ctrl+f {kbcursor_move_right} - Ctrl+b {kbcursor_move_left} - Ctrl+P {move_selection_up} - Ctrl+N {move_selection_down} - Ctrl+F {move_selection_right} - Ctrl+B {move_selection_left} - Alt+f {} - Alt+b {} - Ctrl+space {kbcursor_mark} -} - -def Canvas kbcursor_mark {} { - mset {x y} [$@kbcursor xy] - if {$@action == "none"} { - set @action [SelRect new $self $x $y 256 "none"] - } else { - if {[$@action class] == "SelRect"} { - $@action unclick $x $y 236 "none" - } - } -}
\ No newline at end of file diff --git a/desiredata/src/kernel.c b/desiredata/src/kernel.c deleted file mode 100644 index 08a869e2..00000000 --- a/desiredata/src/kernel.c +++ /dev/null @@ -1,2373 +0,0 @@ -/* $Id: kernel.c,v 1.1.2.92 2007/09/09 21:34:56 matju Exp $ - * Copyright 2006-2007 Mathieu Bouchard. - * Copyright (c) 1997-2006 Miller Puckette. - * For information on usage and redistribution, and for a DISCLAIMER OF ALL - * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* IOhannes : - * changed the canvas_restore in "g_canvas.c", so that it might accept $args as well (like "pd $0_test") - * so you can make multiple & distinguishable templates - * 1511:forum::fr::umlute:2001 - * change marked with IOhannes - */ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include "m_simd.h" -#include "config.h" -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <sstream> -#include <vector> -#include <algorithm> -#include <fcntl.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include <pthread.h> -#ifdef UNISTD -#include <unistd.h> -#endif -#ifdef MSW -#include <io.h> -#endif - -#define a_float a_w.w_float -#define a_symbol a_w.w_symbol -#define a_gpointer a_w.w_gpointer -#define a_index a_w.w_index - -using namespace std; - -/* T.Grill - bit alignment for signal vectors (must be a multiple of 8!) */ -/* if undefined no alignment occurs */ -#ifdef SIMD_BYTEALIGN - #define VECTORALIGNMENT (SIMD_BYTEALIGN*8) -#else - #define VECTORALIGNMENT 128 -#endif - -void *getbytes(size_t nbytes) { - if (nbytes < 1) nbytes = 1; - void *ret = (void *)calloc(nbytes, 1); - if (!ret) error("pd: getbytes() failed -- out of memory"); - return ret; -} - -void *copybytes(void *src, size_t nbytes) { - void *ret = getbytes(nbytes); - if (nbytes) memcpy(ret, src, nbytes); - return ret; -} - -void *resizebytes(void *old, size_t oldsize, size_t newsize) { - if (newsize < 1) newsize = 1; - if (oldsize < 1) oldsize = 1; - void *ret = (void *)realloc((char *)old, newsize); - if (newsize > oldsize && ret) memset(((char *)ret) + oldsize, 0, newsize - oldsize); - if (!ret) error("pd: resizebytes() failed -- out of memory"); - return ret; -} - -void freebytes(void *old, size_t nbytes) {free(old);} - -/* in the following size_t is assumed to have the same size as a pointer type !!! */ - -/* T.Grill - get aligned memory */ -void *getalignedbytes(size_t nbytes) { - /* to align the region we also need some extra memory to save the original pointer location - it is saved immediately before the aligned vector memory */ - void *vec = getbytes(nbytes+(VECTORALIGNMENT/8-1)+sizeof(void *)); - if (!vec) return 0; - t_int alignment = ((t_int)vec+sizeof(void *))&(VECTORALIGNMENT/8-1); - void *ret = (unsigned char *)vec+sizeof(void *)+(alignment == 0?0:VECTORALIGNMENT/8-alignment); - *(void **)((unsigned char *)ret-sizeof(void *)) = vec; - return ret; -} - -/* T.Grill - free aligned vector memory */ -void freealignedbytes(void *ptr,size_t nbytes) { - free(*(void **)((unsigned char *)ptr-sizeof(void *))); -} - -/* T.Grill - resize aligned vector memory */ -void *resizealignedbytes(void *ptr,size_t oldsize, size_t newsize) { - if (newsize<1) newsize=1; - void *ori = *(void **)((unsigned char *)ptr-sizeof(void *)); - void *vec = realloc(ori,newsize+(VECTORALIGNMENT/8-1)+sizeof(void *)); - t_int alignment = ((t_int)vec+sizeof(void *))&(VECTORALIGNMENT/8-1); - void *ret = (unsigned char *)vec+sizeof(void *)+(alignment == 0?0:VECTORALIGNMENT/8-alignment); - *(void **)((unsigned char *)ret-sizeof(void *)) = vec; - return ret; -} - -/* TB: copy to aligned vector memory */ -void *copyalignedbytes(void *src, size_t nbytes) { - void *ret = getalignedbytes(nbytes); - if (nbytes) memcpy(ret, src, nbytes); - return ret; -} - -t_class *hash_class; - -/*extern "C"*/ void hash_setup () { - hash_class = class_new(gensym("#V"), (t_newmethod)0 /*hash_new*/, - 0 /*(t_method)hash_free*/, sizeof(t_object), CLASS_PD, A_GIMME, 0); -} - -/* convenience routines for checking and getting values of atoms. - There's no "pointer" version since there's nothing safe to return if there's an error. */ - -t_float atom_getfloat( t_atom *a) {return a->a_type==A_FLOAT ? a->a_float : 0;} -t_int atom_getint( t_atom *a) {return (t_int)atom_getfloat(a);} -t_symbol * atom_getsymbol(t_atom *a) {return a->a_type==A_SYMBOL ? a->a_symbol : &s_symbol;} -const char *atom_getstring(t_atom *a) {return atom_getsymbol(a)->name;} - -t_symbol *atom_gensym(t_atom *a) { /* this works better for graph labels */ - if (a->a_type == A_SYMBOL) return a->a_symbol; - if (a->a_type == A_FLOAT) {char buf[30]; sprintf(buf, "%g", a->a_float); return gensym(buf);} - return gensym("???"); -} - -t_float atom_getfloatarg( int which, int argc, t_atom *argv) {return argc<=which ? 0 : atom_getfloat( argv+which);} -t_symbol * atom_getsymbolarg(int which, int argc, t_atom *argv) {return argc<=which ? &s_ : atom_getsymbol(argv+which);} -t_int atom_getintarg( int which, int argc, t_atom *argv) {return t_int(atom_getfloatarg(which,argc,argv));} -const char *atom_getstringarg(int which, int argc, t_atom *argv) {return atom_getsymbolarg(which,argc,argv)->name;} - -/* convert an atom into a string, in the reverse sense of binbuf_text (q.v.) - special attention is paid to symbols containing the special characters - ';', ',', '$', and '\'; these are quoted with a preceding '\', except that - the '$' only gets quoted at the beginning of the string. */ - -//static int should_quote(char *s) {return strchr(";,\\{}\"",*s) || isspace(*s) || (*s=='$' && isdigit(s[1]));} -static int should_quote(char *s) {return strchr(";,\\{}\" ",*s) || (*s=='$' && isdigit(s[1]));} - -void atom_ostream(t_atom *a, ostream &buf) { - switch(a->a_type) { - case A_SEMI: buf << ";"; break; - case A_COMMA: buf << ","; break; - case A_POINTER: buf << "(pointer)"; break; - case A_FLOAT: buf << a->a_float; break; - case A_SYMBOL: { - bool quote=0; - for (char *sp = a->a_symbol->name; *sp; sp++) if (should_quote(sp)) {quote = 1; break;} - if (quote) { - for (char *sp = a->a_symbol->name; *sp; sp++) { - if (should_quote(sp)) buf << '\\'; - buf << *sp; - } - } else buf << a->a_symbol->name; - } break; - case A_DOLLAR: buf << "$" << a->a_index; break; - case A_DOLLSYM: buf << a->a_symbol->name; break; - default: bug("%s",__PRETTY_FUNCTION__); - } -} - -/* this is not completely compatible with Miller's, as it won't do anything special for short bufsizes. */ -void atom_string(t_atom *a, char *buf, unsigned int bufsize) { - ostringstream b; - atom_ostream(a,b); - strncpy(buf,b.str().data(),bufsize); - buf[bufsize-1]=0; -} - -void atom_init(t_atom *a, size_t n) { - for (size_t i=0; i<n; i++) { - a[i].a_type = A_FLOAT; - a[i].a_float = 0.0; - } -} - -void atom_copy(t_atom *a, t_atom *b, size_t n) { - memcpy(a,b,n*sizeof(t_atom)); - /* here I should handle incref */ -} - -void atom_delete(t_atom *a, size_t n) { - /* here I should handle decref */ -} - -/* in which the value has bit 0 set if the key object is not a zombie, - and has bit 1 set if the object has been uploaded to the client */ -t_hash<t_pd *,long> *object_table; - -t_pd *pd_new(t_class *c) { - if (!c) bug("pd_new: apparently called before setup routine"); - t_pd *x = (t_pd *)getbytes(c->size); - x->_class = c; - object_table->set(x,1); - if (c->gobj) ((t_gobj *)x)->g_adix = appendix_new((t_gobj *)x); - if (c->patchable) { - ((t_object *)x)->inlet = 0; - ((t_object *)x)->outlet = 0; - } - return x; -} - -void pd_free_zombie(t_pd *x) { - t_class *c = x->_class; - if (c->gobj) appendix_free((t_gobj *)x); - if (c->size) free(x); - object_table->del(x); -} - -void pd_free(t_pd *x) { - t_class *c = x->_class; - if (c->freemethod) ((t_gotfn)(c->freemethod))(x); - if (c->patchable) { - t_object *y = (t_object *)x; - while (y->outlet) outlet_free(y->outlet); - while (y-> inlet) inlet_free(y-> inlet); - if (y->binbuf) binbuf_free(y->binbuf); - } - /* schedule for deletion if need to keep the allocation around */ - if (c->gobj && (object_table->get(x)&2)) { - object_table->set(x,object_table->get(x)&~1); - gobj_changed((t_gobj *)x,""); - //char *xx = (char *)x; for (int i=0; i<c->size; i++) xx[i]="\xde\xad\xbe\xef"[i&3]; - } else pd_free_zombie(x); -} - -void gobj_save(t_gobj *x, t_binbuf *b) { - t_class *c = x->g_pd; - if (c->savefn) c->savefn(x, b); -} - -/* deal with several objects bound to the same symbol. If more than one, - we actually bind a collection object to the symbol, which forwards messages sent to the symbol. */ - -static t_class *bindlist_class; - -struct t_bindelem { - t_pd *who; - t_bindelem *next; -}; - -struct t_bindlist : t_pd { - t_bindelem *list; -}; - -#define bind_each(e,x) for (t_bindelem *e = x->list; e; e = e->next) -static void bindlist_bang (t_bindlist *x) {bind_each(e,x) pd_bang(e->who);} -static void bindlist_float (t_bindlist *x, t_float f) {bind_each(e,x) pd_float(e->who,f);} -static void bindlist_symbol (t_bindlist *x, t_symbol *s) {bind_each(e,x) pd_symbol(e->who,s);} -static void bindlist_pointer (t_bindlist *x, t_gpointer *gp) {bind_each(e,x) pd_pointer(e->who, gp);} -static void bindlist_list (t_bindlist *x, t_symbol *s, int argc, t_atom *argv) {bind_each(e,x) pd_list(e->who, s,argc,argv);} -static void bindlist_anything(t_bindlist *x, t_symbol *s, int argc, t_atom *argv) {bind_each(e,x) pd_typedmess(e->who, s,argc,argv);} - -static t_bindelem *bindelem_new(t_pd *who, t_bindelem *next) { - t_bindelem *self = (t_bindelem *)malloc(sizeof(t_bindelem)); - self->who = who; - self->next = next; - return self; -} - -void pd_bind(t_pd *x, t_symbol *s) { - if (s->thing) { - if (s->thing->_class == bindlist_class) { - t_bindlist *b = (t_bindlist *)s->thing; - b->list = bindelem_new(x,b->list); - } else { - t_bindlist *b = (t_bindlist *)pd_new(bindlist_class); - b->list = bindelem_new(x,bindelem_new(s->thing,0)); - s->thing = b; - } - } else s->thing = x; -} - -/* bindlists always have at least two elements... if the number - goes down to one, get rid of the bindlist and bind the symbol - straight to the remaining element. */ -void pd_unbind(t_pd *x, t_symbol *s) { - if (s->thing == x) {s->thing = 0; return;} - if (s->thing && s->thing->_class == bindlist_class) { - t_bindlist *b = (t_bindlist *)s->thing; - t_bindelem *e, *e2; - if ((e = b->list)->who == x) { - b->list = e->next; - free(e); - } else for (e = b->list; (e2=e->next); e = e2) if (e2->who == x) { - e->next = e2->next; - free(e2); - break; - } - if (!b->list->next) { - s->thing = b->list->who; - free(b->list); - pd_free(b); - } - } else error("%s: couldn't unbind", s->name); -} - -t_pd *pd_findbyclass(t_symbol *s, t_class *c) { - t_pd *x = 0; - if (!s->thing) return 0; - if (s->thing->_class == c) return s->thing; - if (s->thing->_class == bindlist_class) { - t_bindlist *b = (t_bindlist *)s->thing; - int warned = 0; - bind_each(e,b) if (e->who->_class == c) { - if (x && !warned) {post("warning: %s: multiply defined", s->name); warned = 1;} - x = e->who; - } - } - return x; -} - -/* stack for maintaining bindings for the #X symbol during nestable loads. */ - -#undef g_next - -struct t_gstack { - t_pd *what; - t_symbol *loading_abstr; - t_gstack *next; - long base_o_index; -}; - -static t_gstack *gstack_head = 0; -static t_pd *lastpopped; -static t_symbol *pd_loading_abstr; - -int pd_setloadingabstraction(t_symbol *sym) { - t_gstack *foo = gstack_head; - for (foo = gstack_head; foo; foo = foo->next) if (foo->loading_abstr == sym) return 1; - pd_loading_abstr = sym; - return 0; -} - -int gstack_empty() {return !gstack_head;} - -long canvas_base_o_index() { - return gstack_head ? gstack_head->base_o_index : 0; -} - -void pd_pushsym(t_pd *x) { - t_gstack *y = (t_gstack *)malloc(sizeof(*y)); - y->what = s__X.thing; - y->next = gstack_head; - y->loading_abstr = pd_loading_abstr; - y->base_o_index = x->_class == canvas_class ? ((t_canvas *)x)->next_o_index : -666; - pd_loading_abstr = 0; - gstack_head = y; - s__X.thing = x; -} - -void pd_popsym(t_pd *x) { - if (!gstack_head || s__X.thing != x) {bug("gstack_pop"); return;} - t_gstack *headwas = gstack_head; - s__X.thing = headwas->what; - gstack_head = headwas->next; - free(headwas); - lastpopped = x; -} - -static void stackerror(t_pd *x) {error("stack overflow");} - -/* to enable multithreading, make those variables "thread-local". this means that they have to go in - a thread-specific place instead of plain global. do not ever use tim's atomic counters for this, - as they count all threads together as if they're one, and they're especially incompatible with - use of the desiredata-specific stack[] variable. */ -int pd_stackn = 0; /* how much of the stack is in use */ -t_call pd_stack[STACKSIZE]; - -static inline uint64 rdtsc() {uint64 x; __asm__ volatile (".byte 0x0f, 0x31":"=A"(x)); return x;} - -//#define PROFILER -#ifdef PROFILER -#define ENTER_PROF uint64 t = rdtsc(); -#define LEAVE_PROF if (x->_class->gobj && ((t_gobj *)x)->dix) ((t_gobj *)x)->dix->elapsed += rdtsc() - t; -#else -#define ENTER_PROF -#define LEAVE_PROF -#endif - -#define ENTER(SELECTOR) if(pd_stackn >= STACKSIZE) {stackerror(x); return;} \ - pd_stack[pd_stackn].self = x; pd_stack[pd_stackn].s = SELECTOR; pd_stackn++; ENTER_PROF -#define LEAVE pd_stackn--; LEAVE_PROF - -/* matju's 2007.07.14 inlet-based stack check needs to be implemented in: - pd_bang pd_float pd_pointer pd_symbol pd_string pd_list pd_typedmess */ -void pd_bang(t_pd *x) {ENTER(&s_bang); x->_class->bangmethod(x); LEAVE;} -void pd_float(t_pd *x, t_float f) {ENTER(&s_float); x->_class->floatmethod(x,f); LEAVE;} -void pd_pointer(t_pd *x, t_gpointer *gp) {ENTER(&s_pointer); x->_class->pointermethod(x,gp); LEAVE;} -void pd_symbol(t_pd *x, t_symbol *s) {ENTER(&s_symbol); x->_class->symbolmethod(x,s); LEAVE;} -/* void pd_string(t_pd *x, const char *s){ENTER(&s_symbol); x->_class->stringmethod(x,s); LEAVE;} future use */ -void pd_list(t_pd *x, t_symbol *s, int ac, t_atom *av) {ENTER(s); x->_class->listmethod(x,&s_list,ac,av); LEAVE;} - -/* this file handles Max-style patchable objects, i.e., objects which -can interconnect via inlets and outlets; also, the (terse) generic -behavior for "gobjs" appears at the end of this file. */ - -union inletunion { - t_symbol *symto; - t_gpointer *pointerslot; - t_float *floatslot; - t_symbol **symslot; - t_sample floatsignalvalue; -}; - -struct _inlet : t_pd { - struct _inlet *next; - t_object *owner; - t_pd *dest; - t_symbol *symfrom; - union inletunion u; - t_symbol* tip; -}; - -static t_class *inlet_class, *pointerinlet_class, *floatinlet_class, *symbolinlet_class; - -#define ISINLET(pd) ( \ - pd->_class == inlet_class || \ - pd->_class == pointerinlet_class || \ - pd->_class == floatinlet_class || \ - pd->_class == symbolinlet_class) - -/* --------------------- generic inlets ala max ------------------ */ - -static void object_append_inlet(t_object *owner, t_inlet *x) { - t_inlet *y = owner->inlet, *y2; - if (y) { - while ((y2 = y->next)) y = y2; - y->next = x; - } else owner->inlet = x; -} - -t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1, t_symbol *s2) { - t_inlet *x = (t_inlet *)pd_new(inlet_class); - x->owner = owner; - x->dest = dest; - if (s1 == &s_signal) x->u.floatsignalvalue = 0; else x->u.symto = s2; - x->symfrom = s1; - x->next = 0; - x->tip = gensym("?"); - object_append_inlet(owner,x); - return x; -} - -t_inlet *signalinlet_new(t_object *owner, t_float f) { - t_inlet *x = inlet_new(owner, owner, &s_signal, &s_signal); - x->u.floatsignalvalue = f; - return x; -} - -static void inlet_wrong(t_inlet *x, t_symbol *s) { - error("inlet: expected '%s' but got '%s'", x->symfrom->name, s->name); -} - -void inlet_settip(t_inlet* i,t_symbol* s) {i->tip = s;} - -const char *inlet_tip(t_inlet* i,int num) { - if (num < 0) return "???"; - while (num-- && i) i = i->next; - if (i && i->tip) return i->tip->name; - return "?"; -} - -static void inlet_bang(t_inlet *x) { - if (x->symfrom == &s_bang) pd_vmess(x->dest, x->u.symto, ""); - else if (!x->symfrom) pd_bang(x->dest); - else inlet_wrong(x, &s_bang);} -static void inlet_pointer(t_inlet *x, t_gpointer *gp) { - if (x->symfrom == &s_pointer) pd_vmess(x->dest, x->u.symto, "p", gp); - else if (!x->symfrom) pd_pointer(x->dest, gp); - else inlet_wrong(x, &s_pointer);} -static void inlet_float(t_inlet *x, t_float f) { - if (x->symfrom == &s_float) pd_vmess(x->dest, x->u.symto, "f", (t_floatarg)f); - else if (x->symfrom == &s_signal) x->u.floatsignalvalue = f; - else if (!x->symfrom) pd_float(x->dest, f); - else inlet_wrong(x, &s_float);} -static void inlet_symbol(t_inlet *x, t_symbol *s) { - if (x->symfrom == &s_symbol) pd_vmess(x->dest, x->u.symto, "s", s); - else if (!x->symfrom) pd_symbol(x->dest, s); - else inlet_wrong(x, &s_symbol);} -static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv) { - if (x->symfrom == &s_list || x->symfrom == &s_float || x->symfrom == &s_symbol || x->symfrom == &s_pointer) - typedmess(x->dest, x->u.symto, argc, argv); - else if (!x->symfrom) pd_list(x->dest, s, argc, argv); - else inlet_wrong(x, &s_list);} -static void inlet_anything(t_inlet *x, t_symbol *s, int argc, t_atom *argv) { - if (x->symfrom == s) typedmess(x->dest, x->u.symto, argc, argv); - else if (!x->symfrom) typedmess(x->dest, s, argc, argv); - else inlet_wrong(x, s);} - -void inlet_free(t_inlet *x) { - t_object *y = x->owner; - if (y->inlet == x) y->inlet = x->next; - else for (t_inlet *x2 = y->inlet; x2; x2 = x2->next) if (x2->next == x) {x2->next = x->next; break;} - pd_free(x); -} - -/* ----- pointerinlets, floatinlets, syminlets: optimized inlets ------- */ - -static void pointerinlet_pointer(t_inlet *x, t_gpointer *gp) { - gpointer_unset(x->u.pointerslot); - *(x->u.pointerslot) = *gp; - if (gp->o) gp->o->refcount++; -} - -static void floatinlet_float( t_inlet *x, t_float f) {*x->u.floatslot = f;} -static void symbolinlet_symbol(t_inlet *x, t_symbol *s) {*x->u.symslot = s;} - -#define COMMON(qlass,sym,slot) \ - t_inlet *x=(t_inlet *)pd_new(qlass); \ - x->symfrom=&sym; \ - x->u.slot = p; \ - x->owner = owner; \ - x->dest = 0; \ - x->next = 0; \ - object_append_inlet(owner,x); \ - return x; - -t_inlet * floatinlet_new(t_object *owner, t_float * p) {COMMON( floatinlet_class,s_float ,floatslot )} -t_inlet * symbolinlet_new(t_object *owner, t_symbol ** p) {COMMON( symbolinlet_class,s_symbol ,symslot )} -t_inlet *pointerinlet_new(t_object *owner, t_gpointer *p) {COMMON(pointerinlet_class,s_pointer,pointerslot)} -#undef COMMON - -/* ---------------------- routine to handle lists ---------------------- */ - -/* objects interpret lists by feeding them to the individual inlets. Before you call this, - check that the object doesn't have a more specific way to handle lists. */ -void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv) { - t_atom *ap; - int count; - t_inlet *ip = ((t_object *)x)->inlet; - if (!argc) return; - for (count = argc-1, ap = argv+1; ip && count--; ap++, ip = ip->next) { - if (ap->a_type == A_POINTER) pd_pointer(ip,ap->a_gpointer); - else if (ap->a_type == A_FLOAT) pd_float(ip,ap->a_float); - else pd_symbol(ip,ap->a_symbol); - } - if (argv->a_type == A_POINTER) pd_pointer(x,argv->a_gpointer); - else if (argv->a_type == A_FLOAT) pd_float(x,argv->a_float); - else pd_symbol(x,argv->a_symbol); -} - -void obj_init () { - inlet_class = class_new(gensym("inlet"), 0, 0, sizeof(t_inlet), CLASS_PD, 0); - floatinlet_class = class_new(gensym("inlet"), 0, 0, sizeof(t_inlet), CLASS_PD, 0); - symbolinlet_class = class_new(gensym("inlet"), 0, 0, sizeof(t_inlet), CLASS_PD, 0); - pointerinlet_class = class_new(gensym("inlet"), 0, 0, sizeof(t_inlet), CLASS_PD, 0); - class_addbang(inlet_class, inlet_bang); - class_addpointer(inlet_class, inlet_pointer); - class_addfloat(inlet_class, inlet_float); - class_addsymbol(inlet_class, inlet_symbol); - class_addlist(inlet_class, inlet_list); - class_addanything(inlet_class, inlet_anything); - class_addfloat( floatinlet_class, floatinlet_float); - class_addsymbol( symbolinlet_class, symbolinlet_symbol); - class_addpointer(pointerinlet_class, pointerinlet_pointer); -} - -/* --------------------------- outlets ------------------------------ */ - -/* this is fairly obsolete stuff, I think */ -static int outlet_eventno; -void outlet_setstacklim () {outlet_eventno++;} -int sched_geteventno( void) {return outlet_eventno;} - -t_inlet *t_object:: in(int n) {t_inlet *i= inlet; while(n--) i=i->next; return i;} -t_outlet *t_object::out(int n) {t_outlet *o=outlet; while(n--) o=o->next; return o;} - -t_class *wire_class; -t_wire *wire_new (t_symbol *s, int argc, t_atom *argv) { - t_wire *self = (t_wire *)pd_new(wire_class); - self->g_adix = appendix_new((t_gobj *)self); - return self; -} -void wire_free (t_wire *self) {/* nothing here */} - -/* this is only used for pd_upload yet, right? so, it can use the new indices instead already */ -void wire_save (t_wire *self, t_binbuf *b) { -// t_canvas *c = self->dix->canvas; - binbuf_addv(b,"ttiiii;","#X","connect", -// canvas_getindex(c,self->from), self->outlet, -// canvas_getindex(c,self->to ), self-> inlet); - self->from->dix->index, self->outlet, - self->to ->dix->index, self-> inlet); - appendix_save((t_gobj *)self,b); -} - -t_outlet *outlet_new(t_object *owner, t_symbol *s) { - t_outlet *x = (t_outlet *)malloc(sizeof(*x)), *y, *y2; - x->owner = owner; - x->next = 0; - y = owner->outlet; - if (y) { - while ((y2 = y->next)) y = y2; - y->next = x; - } else owner->outlet = x; - x->connections = 0; - x->sym = s; - return x; -} - -#define each_connect(oc,x) for (t_outconnect *oc = x->connections; oc; oc = oc->next) -void outlet_bang(t_outlet *x) {each_connect(oc,x) pd_bang( oc->oc_to);} -void outlet_pointer(t_outlet *x, t_gpointer *v) {t_gpointer gp = *v; each_connect(oc,x) pd_pointer(oc->oc_to,&gp);} -void outlet_float(t_outlet *x, t_float v) {each_connect(oc,x) pd_float( oc->oc_to,v);} -void outlet_symbol(t_outlet *x, t_symbol *v) {each_connect(oc,x) pd_symbol( oc->oc_to,v);} -void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv) {each_connect(oc,x) pd_list( oc->oc_to,s,argc,argv);} -void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv){each_connect(oc,x) typedmess( oc->oc_to,s,argc,argv);} - -void outlet_atom(t_outlet *x, t_atom *a) { - if (a->a_type==A_FLOAT ) x->send(a->a_float); - else if (a->a_type==A_SYMBOL ) x->send(a->a_symbol); - else if (a->a_type==A_POINTER) x->send(a->a_gpointer); - else error("can't send atom whose type is %d",a->a_type); -} - -/* get the outlet's declared symbol */ -t_symbol *outlet_getsymbol(t_outlet *x) {return x->sym;} - -void outlet_free(t_outlet *x) { - t_object *y = x->owner; - if (y->outlet == x) y->outlet = x->next; - else for (t_outlet *x2 = y->outlet; x2; x2 = x2->next) if (x2->next == x) { - x2->next = x->next; - break; - } - free(x); -} - -#define each_inlet(i,obj) for ( t_inlet *i=obj->inlet ; i; i=i->next) -#define each_outlet(o,obj) for (t_outlet *o=obj->outlet; o; o=o->next) - -static t_pd *find_inlet(t_object *to, int inlet) { - if (to->_class->firstin) {if (inlet) inlet--; else return (t_pd *)to;} - each_inlet(i,to) if (inlet) inlet--; else return (t_pd *)i; - return 0; -} - -static t_outlet *find_outlet(t_object *from, int outlet) { - each_outlet(o,from) if (outlet) outlet--; else return o; - return 0; -} - -t_outconnect *obj_connect(t_object *from, int outlet, t_object *to, int inlet) { - t_outlet *o = find_outlet(from,outlet); - t_pd *i = find_inlet(to,inlet); - if (!o||!i) return 0; - t_outconnect *oc = wire_new(0,0,0), *oc2; - oc->next = 0; - oc->oc_to = i; - oc->from = from; oc->outlet = outlet; - oc->to = to; oc->inlet = inlet; - /* append it to the end of the list */ - /* LATER we might cache the last "oc" to make this faster. */ - if ((oc2 = o->connections)) { - while (oc2->next) oc2 = oc2->next; - oc2->next = oc; - } else o->connections = oc; - if (o->sym == &s_signal) canvas_update_dsp(); - return oc; -} - -void obj_disconnect(t_object *from, int outlet, t_object *to, int inlet) { - t_outlet *o = find_outlet(from,outlet); if (!o) {post("outlet does not exist"); return;} - t_pd *i = find_inlet(to, inlet); if (!i) {post( "inlet does not exist"); return;} - t_outconnect *oc = o->connections, *oc2; - if (!oc) {post("outlet has no connections"); return;} - if (oc->oc_to == i) { - o->connections = oc->next; - pd_free(oc); - goto done; - } - while ((oc2 = oc->next)) { - if (oc2->oc_to == i) { - oc->next = oc2->next; - pd_free(oc2); - goto done; - } - oc = oc2; - } - post("connection not found"); -done: - if (o->sym == &s_signal) canvas_update_dsp(); -} - -/* ------ traversal routines for code that can't see our structures ------ */ - -int obj_noutlets(t_object *x) { - int n=0; - each_outlet(o,x) n++; - return n; -} - -int obj_ninlets(t_object *x) { - int n=!!x->_class->firstin; - each_inlet(i,x) n++; - return n; -} - -t_outconnect *obj_starttraverseoutlet(t_object *x, t_outlet **op, int nout) { - t_outlet *o = x->outlet; - while (nout-- && o) o = o->next; - *op = o; - return o ? o->connections : 0; -} - -t_outconnect *obj_nexttraverseoutlet(t_outconnect *lastconnect, t_object **destp, t_inlet **inletp, int *whichp) { - t_pd *y = lastconnect->oc_to; - if (ISINLET(y)) { - t_inlet *i = (t_inlet *)y; - t_object *dest = i->owner; - int n = dest->_class->firstin; - each_inlet(i2,dest) if (i2==i) break; else n++; - *whichp = n; - *destp = dest; - *inletp = i; - } else { - *whichp = 0; - *inletp = 0; - *destp = (t_object *)y; - } - return lastconnect->next; -} - -/* this one checks that a pd is indeed a patchable object, and returns it, - correctly typed, or zero if the check failed. */ -t_object *pd_checkobject(t_pd *x) { - return x->_class->patchable ? (t_object *)x : 0; -} - -/* move an inlet or outlet to the head of the list. this code is not safe with the latest additions in t_outconnect ! */ -void obj_moveinletfirst( t_object *x, t_inlet *i) {if (x->inlet == i) return; - each_inlet( i2,x) if (i2->next == i) {i2->next = i->next; i->next = x-> inlet; x-> inlet = i; return;}} -void obj_moveoutletfirst(t_object *x, t_outlet *o) {if (x->outlet == o) return; - each_outlet(o2,x) if (o2->next == o) {o2->next = o->next; o->next = x->outlet; x->outlet = o; return;}} - -/* routines for DSP sorting, which are used in d_ugen.c and g_canvas.c */ -/* LATER try to consolidate all the slightly different routines. */ - -int obj_nsiginlets(t_object *x) { - int n=0; - each_inlet(i,x) if (i->symfrom == &s_signal) n++; - if (x->_class->firstin && x->_class->floatsignalin) n++; - return n; -} -int obj_nsigoutlets(t_object *x) { - int n=0; - each_outlet(o,x) if (o->sym == &s_signal) n++; - return n; -} - -/* get the index, among signal inlets, of the mth inlet overall */ -int obj_siginletindex(t_object *x, int m) { - int n=0; - if (x->_class->firstin && x->_class->floatsignalin) {if (!m--) return 0; else n++;} - each_inlet(i,x) if (i->symfrom == &s_signal) {if (!m) return n; else {n++; m--;}} - return -1; -} -int obj_sigoutletindex(t_object *x, int m) { - int n=0; - each_outlet(o,x) if (o->sym == &s_signal) {if (!m) return n; else {n++; m--;}} - return -1; -} - -int obj_issignalinlet(t_object *x, int m) { - if (x->_class->firstin) {if (!m) return x->_class->floatsignalin; else m--;} - t_inlet *i; - for (i = x->inlet; i && m; i = i->next, m--) {} - return i && i->symfrom==&s_signal; -} -int obj_issignaloutlet(t_object *x, int m) { - t_outlet *o2; - for (o2 = x->outlet; o2 && m--; o2 = o2->next) {} - return o2 && o2->sym==&s_signal; -} - -t_sample *obj_findsignalscalar(t_object *x, int m) { - int n = 0; - t_inlet *i; - if (x->_class->firstin && x->_class->floatsignalin) { - if (!m--) return x->_class->floatsignalin > 0 ? (t_sample *)(((char *)x) + x->_class->floatsignalin) : 0; - n++; - } - for (i = x->inlet; i; i = i->next, m--) if (i->symfrom == &s_signal) { - if (m == 0) return &i->u.floatsignalvalue; - n++; - } - return 0; -} - -/* and those two are only used in desire.c... */ -int inlet_getsignalindex(t_inlet *x) { - int n=0; for ( t_inlet *i = x->owner-> inlet; i; i = i->next) if (i==x) return n; else if (i->symfrom == &s_signal) n++; - return -1;} -int outlet_getsignalindex(t_outlet *x) { - int n=0; for (t_outlet *o = x->owner->outlet; o; o = o->next) if (o==x) return n; else if (o->sym == &s_signal) n++; - return -1;} - -#ifdef QUALIFIED_NAME -static char *pd_library_name = 0; -void pd_set_library_name(char *libname){ - pd_library_name=libname; -} -#endif - -t_hash<t_symbol *, t_class *> *class_table=0; -static t_symbol *class_loadsym; /* name under which an extern is invoked */ -static void pd_defaultfloat(t_pd *x, t_float f); -static void pd_defaultlist(t_pd *x, t_symbol *s, int argc, t_atom *argv); -t_pd pd_objectmaker; /* factory for creating "object" boxes */ -t_pd pd_canvasmaker; /* factory for creating canvases */ - -static t_symbol *class_extern_dir = &s_; - -static void pd_defaultanything(t_pd *x, t_symbol *s, int argc, t_atom *argv) { - error("%s: no method for '%s'", x->_class->name->name, s->name); -} - -static void pd_defaultbang(t_pd *x) { - t_class *c = pd_class(x); - if (c->listmethod != pd_defaultlist) c->listmethod(x,0,0,0); - else c->anymethod(x,&s_bang,0,0); -} - -static void pd_defaultfloat(t_pd *x, t_float f) { - t_class *c = pd_class(x); t_atom at; SETFLOAT(&at, f); - if (c->listmethod != pd_defaultlist) c->listmethod(x,0,1,&at); else c->anymethod(x,&s_float,1,&at); -} -static void pd_defaultsymbol(t_pd *x, t_symbol *s) { - t_class *c = pd_class(x); t_atom at; SETSYMBOL(&at, s); - if (c->listmethod != pd_defaultlist) c->listmethod(x,0,1,&at); else c->anymethod(x,&s_symbol,1,&at); -} -static void pd_defaultpointer(t_pd *x, t_gpointer *gp) { - t_class *c = pd_class(x); t_atom at; SETPOINTER(&at, gp); - if (c->listmethod != pd_defaultlist) c->listmethod(x,0,1,&at); else c->anymethod(x,&s_pointer,1,&at); -} - -void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv); -static void class_nosavefn(t_gobj *z, t_binbuf *b); - -/* handle "list" messages to Pds without explicit list methods defined. */ -static void pd_defaultlist(t_pd *x, t_symbol *s, int argc, t_atom *argv) { - t_class *c = pd_class(x); - /* a list with no elements is handled by the 'bang' method if one exists. */ - if (argc == 0 && c->bangmethod != pd_defaultbang) {c->bangmethod(x); return;} - /* a list with one element which is a number can be handled by a - "float" method if any is defined; same for "symbol", "pointer". */ - if (argc == 1) { -#define HANDLE(A,M,D,F) if (argv->a_type==A && c->M != D) {c->M(x, argv->a_w.F); return;} - HANDLE(A_FLOAT ,floatmethod ,pd_defaultfloat ,w_float) - HANDLE(A_SYMBOL ,symbolmethod ,pd_defaultsymbol ,w_symbol) - HANDLE(A_POINTER,pointermethod,pd_defaultpointer,w_gpointer) - } - /* Next try for an "anything" method; if the object is patchable (i.e., - can have proper inlets) send it on to obj_list which will unpack the - list into the inlets. otherwise gove up and complain. */ - if (c->anymethod != pd_defaultanything) c->anymethod(x,&s_list,argc,argv); - else if (c->patchable) obj_list((t_object *)x, s, argc, argv); - else pd_defaultanything(x, &s_list, argc, argv); -} - -t_symbol *qualified_name(t_symbol *s) { - char *buf; - asprintf(&buf, "%s%s%s", pd_library_name, QUALIFIED_NAME, s->name); - t_symbol *sym = gensym(buf); - free(buf); - return sym; -} - -#undef class_new2 -#undef class_addcreator2 -#undef class_addmethod2 - -/* Note that some classes such as "select", are actually two classes of the same name, - one for the single-argument form, one for the multiple one; see select_setup() to - find out how this is handled. */ -t_class *class_new2(const char *ss, t_newmethod newmethod, t_method freemethod, -size_t size, int flags, const char *sig) { - t_symbol *s = ss?gensym(ss):0; - int typeflag = flags & CLASS_TYPEMASK; - if (!typeflag) typeflag = CLASS_PATCHABLE; -#ifdef QUALIFIED_NAME - if (pd_library_name) s = qualified_name(s); -#endif - if (pd_objectmaker._class && newmethod) { - /* add a "new" method by the name specified by the object */ - class_addmethod2(pd_objectmaker._class, (t_method)newmethod, s->name, sig); - if (class_loadsym) { - /* if we're loading an extern it might have been invoked by a - longer file name; in this case, make this an admissible name too. */ - char *loadstring = class_loadsym->name, l1 = strlen(s->name), l2 = strlen(loadstring); - if (l2 > l1 && !strcmp(s->name, loadstring + (l2 - l1))) - class_addmethod2(pd_objectmaker._class, (t_method)newmethod, class_loadsym->name, sig); - } - } - t_class *c = (t_class *)malloc(sizeof(*c)); - c->name = c->helpname = s; - c->size = size; - c->methods = (t_methodentry *)malloc(1); - c->nmethod = 0; - c->freemethod = (t_method)freemethod; - c->bangmethod = pd_defaultbang; - c->pointermethod = pd_defaultpointer; - c->floatmethod = pd_defaultfloat; - c->symbolmethod = pd_defaultsymbol; - c->listmethod = pd_defaultlist; - c->anymethod = pd_defaultanything; - c->firstin = ((flags & CLASS_NOINLET) == 0); - c->firsttip = gensym("?"); - c->fields = (t_symbol **)malloc(sizeof(t_symbol *)*31); - c->nfields = 0; - c->patchable = (typeflag == CLASS_PATCHABLE); - c->gobj = (typeflag >= CLASS_GOBJ); - c->drawcommand = 0; - c->floatsignalin = 0; - c->externdir = class_extern_dir; - c->savefn = (typeflag == CLASS_PATCHABLE ? text_save : class_nosavefn); -#ifdef QUALIFIED_NAME - // like a class_addcreator - if (pd_library_name && newmethod) class_addmethod2(pd_objectmaker._class, (t_method)newmethod, ss, sig); -#endif - c->onsubscribe = gobj_onsubscribe; - class_table->set(c->name, c); - return c; -} - -/* add a creation method, which is a function that returns a Pd object - suitable for putting in an object box. We presume you've got a class it - can belong to, but this won't be used until the newmethod is actually - called back (and the new method explicitly takes care of this.) */ -void class_addcreator2(const char *ss, t_newmethod newmethod, const char *sig) { - t_symbol *s = gensym(ss); - class_addmethod2(pd_objectmaker._class, (t_method)newmethod, ss, sig); -#ifdef QUALIFIED_NAME - class_addmethod2(pd_objectmaker._class, (t_method)newmethod, pd_library_name ? qualified_name(s)->name : ss, sig); -#endif - class_table->set(s,0); -} - -void class_addmethod2(t_class *c, t_method fn, const char *ss, const char *fmt) { - t_symbol *sel = gensym(ss); - t_methodentry *m; - int argtype = *fmt++; - /* "signal" method specifies that we take audio signals but - that we don't want automatic float to signal conversion. This - is obsolete; you should now use the CLASS_MAINSIGNALIN macro. */ - if (sel == &s_signal) { - if (c->floatsignalin) post("warning: signal method overrides class_mainsignalin"); - c->floatsignalin = -1; - } - /* check for special cases. "Pointer" is missing here so that - pd_objectmaker's pointer method can be typechecked differently. */ - /* is anyone actually using those five cases? */ - if (sel==&s_bang) {if (argtype) goto phooey; class_addbang( c,fn);} - else if (sel==&s_float) {if (argtype!='f'||*fmt) goto phooey; class_doaddfloat( c,fn);} - else if (sel==&s_symbol) {if (argtype!='s'||*fmt) goto phooey; class_addsymbol( c,fn);} - else if (sel==&s_list) {if (argtype!='*') goto phooey; class_addlist( c,fn);} - else if (sel==&s_anything) {if (argtype!='*') goto phooey; class_addanything(c,fn);} - else { - /* SLOW, especially for [objectmaker] */ - c->methods = (t_methodentry *)realloc(c->methods, (c->nmethod+1) * sizeof(*c->methods)); - m = c->methods + c->nmethod; - c->nmethod++; - m->me_name = sel; - m->me_fun = (t_gotfn)fn; - int nargs = 0; - while (argtype && nargs < MAXPDARG) { - t_atomtype t; - switch(argtype) { - case 'f': t=A_FLOAT; break; - case 's': t=A_SYMBOL; break; - case 'p': t=A_POINTER; break; - case ';': t=A_SEMI; break; - case ',': t=A_COMMA; break; - case 'F': t=A_DEFFLOAT; break; - case 'S': t=A_DEFSYMBOL;break; - case '$': t=A_DOLLAR; break; - case '@': t=A_DOLLSYM; break; - case '*': t=A_GIMME; break; - case '!': t=A_CANT; break; - default: goto phooey; - }; - m->me_arg[nargs++] = t; - argtype = *fmt++; - } - if (argtype) error("%s_%s: only 5 arguments are typecheckable; use A_GIMME aka '*'", c->name->name, sel->name); - m->me_arg[nargs] = A_NULL; - } - return; -phooey: - bug("class_addmethod: %s_%s: bad argument types", c->name->name, sel->name); -} - -#define COMMON(R) \ - char fmt[42],*f=fmt; va_list ap; va_start(ap,arg1); int t=arg1; \ - while(t) {if (t>A_CANT) {error("%s: ARRGH! t=%d",__func__,t); return R;} *f++ = " fsp;,FS$@*!"[t]; t=(t_atomtype)va_arg(ap,int);} \ - *f=0; va_end(ap); - -t_class *class_new(t_symbol *s, t_newmethod newmethod, t_method freemethod, size_t size, int flags, t_atomtypearg arg1, ...) { - COMMON(0); return class_new2(s?s->name:0,newmethod,freemethod,size,flags,fmt); -} -void class_addcreator(t_newmethod newmethod, t_symbol *s, t_atomtypearg arg1, ...) { - COMMON(); class_addcreator2(s?s->name:0,newmethod,fmt); -} -void class_addmethod(t_class *c, t_method fn, t_symbol *sel, t_atomtypearg arg1, ...) { - COMMON(); class_addmethod2(c,fn,sel->name,fmt); -} -#undef COMMON - -/* see also the "class_addfloat", etc., macros in m_pd.h */ -#undef class_addbang -#undef class_addpointer -#undef class_addsymbol -#undef class_addlist -#undef class_addanything -void class_addbang( t_class *c, t_method fn) {c-> bangmethod = (t_bangmethod)fn;} -void class_addpointer( t_class *c, t_method fn) {c->pointermethod = (t_pointermethod)fn;} -void class_doaddfloat( t_class *c, t_method fn) {c-> floatmethod = (t_floatmethod)fn;} -void class_addsymbol( t_class *c, t_method fn) {c-> symbolmethod = (t_symbolmethod)fn;} -void class_addlist( t_class *c, t_method fn) {c-> listmethod = (t_listmethod)fn;} -void class_addanything(t_class *c, t_method fn) {c-> anymethod = (t_anymethod)fn;} - -char *class_getname( t_class *c) {return c->name->name;} -char *class_gethelpname( t_class *c) {return c->helpname->name;} -void class_sethelpsymbol( t_class *c, t_symbol *s) {c->helpname = s;} -void class_setdrawcommand(t_class *c) {c->drawcommand = 1;} -int class_isdrawcommand( t_class *c) {return c->drawcommand;} -void class_setnotice( t_class *c, t_notice notice ) {c->notice = notice ;} -void class_setonsubscribe(t_class *c, t_onsubscribe onsubscribe) {c->onsubscribe = onsubscribe;} - -static void pd_floatforsignal(t_pd *x, t_float f) { - int offset = x->_class->floatsignalin; - if (offset>0) *(t_sample *)((char *)x + offset) = f; - else error("%s: float unexpected for signal input", x->_class->name->name); -} - -void class_domainsignalin(t_class *c, int onset) { - if (onset <= 0) onset = -1; - else { - if (c->floatmethod != pd_defaultfloat) post("warning: %s: float method overwritten", c->name->name); - c->floatmethod = (t_floatmethod)pd_floatforsignal; - } - c->floatsignalin = onset; -} - -void class_set_extern_dir(t_symbol *s) {class_extern_dir = s;} -char *class_gethelpdir(t_class *c) {return c->externdir->name;} - -static void class_nosavefn(t_gobj *z, t_binbuf *b) {bug("save function called but not defined");} -void class_setsavefn(t_class *c, t_savefn f) {c->savefn = f;} -t_savefn class_getsavefn(t_class *c) {return c->savefn;} - -/* ---------------- the symbol table ------------------------ */ - -/* tb: new 16 bit hash table: multiplication hash */ -#ifndef NEWHASH -#define HASHSIZE 1024 -#else -#define HASHSIZE 65536 -#define HASHFACTOR 40503 /* donald knuth: (sqrt(5) - 1)/2*pow(2,16) */ -#endif - -#ifdef NEWHASH -static short hash(const char *s, size_t n) { - unsigned short hash1 = 0, hash2 = 0; -#else -static int hash(const char *s, size_t n) { - unsigned int hash1 = 0, hash2 = 0; -#endif - const char *s2 = s; - while (n) { - hash1 += *s2; - hash2 += hash1; - s2++; - n--; - } - return hash2; -} - -/* tb: made dogensym() threadsafe */ -static t_symbol *symhash[HASHSIZE]; -t_symbol *dogensym(const char *s, size_t n, t_symbol *oldsym) { -#ifdef THREADSAFE_GENSYM - static pthread_mutex_t hash_lock = PTHREAD_MUTEX_INITIALIZER; -#endif - t_symbol **sym1, *sym2; -#ifdef NEWHASH - unsigned short hash2 = hash(s,n); -#else - unsigned int hash2 = hash(s,n); -#endif -#ifdef NEWHASH - hash2 = hash2 * HASHFACTOR; - sym1 = symhash + hash2; -#else - sym1 = symhash + (hash2 & (HASHSIZE-1)); -#endif - while ((sym2 = *sym1)) { - if (!strcmp(sym2->name, s)) return sym2; - sym1 = &sym2->next; - } -#ifdef THREADSAFE_GENSYM - pthread_mutex_lock(&hash_lock); - /* tb: maybe another thread added the symbol to the hash table; double check */ - while (sym2 = *sym1) { - if (!strcmp(sym2->name, s)) { - pthread_mutex_unlock(&hash_lock); - return sym2; - } - sym1 = &sym2->next; - } -#endif - - if (oldsym) sym2 = oldsym; - else { - sym2 = (t_symbol *)malloc(sizeof(*sym2)); - sym2->name = (char *)malloc(n+1); - sym2->next = 0; - sym2->thing = 0; - memcpy(sym2->name, s, n); - sym2->name[n]=0; - sym2->n=n; - } - *sym1 = sym2; -#ifdef THREADSAFE_GENSYM - pthread_mutex_unlock(&hash_lock); -#endif - return sym2; -} - -t_symbol *gensym( const char *s) {return dogensym(s,strlen(s),0);} -t_symbol *gensym2(const char *s, size_t n) {return dogensym(s,n,0);} -extern "C" t_symbol *symprintf(const char *s, ...) { - char *buf; - va_list args; - va_start(args,s); - vasprintf(&buf,s,args); - va_end(args); - t_symbol *r = gensym(buf); - free(buf); - return r; -} - -bool symbol_lt (t_symbol *a, t_symbol *b) {return strcmp(a->name,b->name)<0;} - -void glob_symbol_table (t_pd *, float onlybound) { - post("symbol_table = {"); - std::vector<t_symbol *> all; - for (size_t i=0; i<int(sizeof(symhash)/sizeof(*symhash)); i++) for (t_symbol *s=symhash[i]; s; s=s->next) all.push_back(s); - sort(all.begin(),all.end(),symbol_lt); - for (size_t i=0; i<all.size(); i++) { - int j=0; - if (all[i]->thing) { - if (all[i]->thing->_class==bindlist_class) j=2; else j=1; - } - if (j>0 || !onlybound) post(" %0*lx: %s (%d)",2*sizeof(void*),long(all[i]),all[i]->name,j); - } - post("}"); -} - -static int tryingalready; -extern "C" void canvas_popabstraction(t_canvas *x); -extern t_pd *newest; -t_symbol* pathsearch(t_symbol *s,char* ext); -int pd_setloadingabstraction(t_symbol *sym); - -/* this routine is called when a new "object" is requested whose class Pd - doesn't know. Pd tries to load it as an extern, then as an abstraction. */ -void new_anything(void *dummy, t_symbol *s, int argc, t_atom *argv) { - int fd; - char *dirbuf, *nameptr; - if (tryingalready) return; - newest = 0; - class_loadsym = s; - if (sys_load_lib(canvas_getcurrent(), s->name)) { - tryingalready = 1; - typedmess((t_pd *)dummy, s, argc, argv); - tryingalready = 0; - return; - } - class_loadsym = 0; - t_pd *current = s__X.thing; - if ((fd = canvas_open2(canvas_getcurrent(), s->name, ".pd", &dirbuf, &nameptr, 0)) >= 0 || - (fd = canvas_open2(canvas_getcurrent(), s->name, ".pat", &dirbuf, &nameptr, 0)) >= 0) { - close(fd); - if (!pd_setloadingabstraction(s)) { - canvas_setargs(argc, argv); /* bug fix by Krzysztof Czaja */ - binbuf_evalfile(gensym(nameptr), gensym(dirbuf)); - if (s__X.thing != current) canvas_popabstraction((t_canvas *)s__X.thing); - canvas_setargs(0, 0); - } else error("%s: can't load abstraction within itself", s->name); - free(dirbuf); - } else newest = 0; -} - -#define MAKESYM(CSYM,S) t_symbol CSYM = {(char *)(S),0,0,1,0xdeadbeef}; -MAKESYM(s_pointer ,"pointer") -MAKESYM(s_float ,"float") -MAKESYM(s_symbol ,"symbol") -MAKESYM(s_bang ,"bang") -MAKESYM(s_list ,"list") -MAKESYM(s_anything,"anything") -MAKESYM(s_signal ,"signal") -MAKESYM(s__N ,"#N") -MAKESYM(s__X ,"#X") -MAKESYM(s_x ,"x") -MAKESYM(s_y ,"y") -MAKESYM(s_ ,"") - -static t_symbol *symlist[] = { &s_pointer, &s_float, &s_symbol, &s_bang, - &s_list, &s_anything, &s_signal, &s__N, &s__X, &s_x, &s_y, &s_}; - -t_pd *newest; - -/* This is externally available, but note that it might later disappear; the -whole "newest" thing is a hack which needs to be redesigned. */ -t_pd *pd_newest () {return newest;} - - /* horribly, we need prototypes for each of the artificial function - calls in typedmess(), to keep the compiler quiet. */ -typedef t_pd *(*t_newgimme)(t_symbol *s, int argc, t_atom *argv); -typedef void(*t_messgimme)(t_pd *x, t_symbol *s, int argc, t_atom *argv); - -#define REST t_floatarg d1, t_floatarg d2, t_floatarg d3, t_floatarg d4, t_floatarg d5 -typedef t_pd *(*t_fun0)(REST); -typedef t_pd *(*t_fun1)(t_int i1, REST); -typedef t_pd *(*t_fun2)(t_int i1, t_int i2, REST); -typedef t_pd *(*t_fun3)(t_int i1, t_int i2, t_int i3, REST); -typedef t_pd *(*t_fun4)(t_int i1, t_int i2, t_int i3, t_int i4, REST); -typedef t_pd *(*t_fun5)(t_int i1, t_int i2, t_int i3, t_int i4, t_int i5, REST); -typedef t_pd *(*t_fun6)(t_int i1, t_int i2, t_int i3, t_int i4, t_int i5, t_int i6, REST); -#undef REST - -void pd_typedmess_2(t_pd *x, t_symbol *s, int argc, t_atom *argv) { - t_class *c = x->_class; - t_atomtype *wp, wanttype; - t_int ai[MAXPDARG+1], *ap = ai; - t_floatarg ad[MAXPDARG+1], *dp = ad; - int narg = 0; - /* check for messages that are handled by fixed slots in the class structure. We don't catch "pointer" - though so that sending "pointer" to pd_objectmaker doesn't require that we supply a pointer value. */ - if (s == &s_float) { - if (!argc) c->floatmethod(x, 0.); - else if (argv->a_type == A_FLOAT) c->floatmethod(x, argv->a_float); - else error("expected one float, in class [%s]", c->name->name); - return; - } - if (s == &s_bang) {c->bangmethod(x); return;} - if (s == &s_list) {c->listmethod(x,s,argc,argv); return;} - if (s == &s_symbol) {c->symbolmethod(x, argc && argv->a_type==A_SYMBOL ? argv->a_symbol : &s_); return;} - t_methodentry *m = c->methods; - for (int i = c->nmethod; i--; m++) if (m->me_name == s) { - wp = m->me_arg; - if (*wp == A_GIMME) { - if (x == &pd_objectmaker) pd_set_newest(((t_newgimme)(m->me_fun))( s,argc,argv)); - else ((t_messgimme)(m->me_fun))(x,s,argc,argv); - return; - } - if (argc > MAXPDARG) argc = MAXPDARG; - if (x != &pd_objectmaker) *(ap++) = (t_int)x, narg++; - while ((wanttype = *wp++)) { - switch (wanttype) { - case A_POINTER: - if (!argc) goto badarg; - if (argv->a_type!=A_POINTER) goto badarg; - *ap = t_int(argv->a_gpointer); - argc--; argv++; - narg++; - ap++; - break; - case A_FLOAT: if (!argc) goto badarg; - case A_DEFFLOAT: if (!argc) *dp = 0; - else { - if (argv->a_type!=A_FLOAT) goto badarg; - *dp = argv->a_float; - argc--; argv++; - } - dp++; - break; - case A_SYMBOL: if (!argc) goto badarg; - case A_DEFSYM: if (!argc) *ap = t_int(&s_); - else { - if (argv->a_type == A_SYMBOL) *ap = t_int(argv->a_symbol); - /* if it's an unfilled "dollar" argument it appears as zero here; cheat and bash it to the null - symbol. Unfortunately, this lets real zeros pass as symbols too, which seems wrong... */ - else if (x == &pd_objectmaker && argv->a_type == A_FLOAT && argv->a_float == 0) - *ap = t_int(&s_); - else goto badarg; - argc--; argv++; - } - narg++; - ap++; - default: {} - } - } - t_pd *bonzo; - switch (narg) { -#define REST ad[0],ad[1],ad[2],ad[3],ad[4] - case 0 : bonzo = ((t_fun0)(m->me_fun))( REST); break; - case 1 : bonzo = ((t_fun1)(m->me_fun))(ai[0], REST); break; - case 2 : bonzo = ((t_fun2)(m->me_fun))(ai[0],ai[1], REST); break; - case 3 : bonzo = ((t_fun3)(m->me_fun))(ai[0],ai[1],ai[2], REST); break; - case 4 : bonzo = ((t_fun4)(m->me_fun))(ai[0],ai[1],ai[2],ai[3], REST); break; - case 5 : bonzo = ((t_fun5)(m->me_fun))(ai[0],ai[1],ai[2],ai[3],ai[4], REST); break; - case 6 : bonzo = ((t_fun6)(m->me_fun))(ai[0],ai[1],ai[2],ai[3],ai[4],ai[5],REST); break; - default: bonzo = 0; - } - if (x == &pd_objectmaker) pd_set_newest(bonzo); - return; - } - c->anymethod(x, s, argc, argv); - return; -badarg: - error("Bad arguments for message '%s' to object '%s'", s->name, c->name->name); -} - -void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) { - ENTER(s); pd_typedmess_2(x,s,argc,argv); LEAVE; -} - -void pd_vmess(t_pd *x, t_symbol *sel, const char *fmt, ...) { - va_list ap; - t_atom arg[MAXPDARG], *at =arg; - int nargs = 0; - const char *fp = fmt; - va_start(ap, fmt); - while (1) { - if (nargs > MAXPDARG) { - error("pd_vmess: only %d allowed", MAXPDARG); - break; - } - switch(*fp++) { - case 'f': SETFLOAT(at, va_arg(ap, double)); break; - case 's': SETSYMBOL(at, va_arg(ap, t_symbol *)); break; - case 'i': SETFLOAT(at, va_arg(ap, t_int)); break; - case 'p': SETPOINTER(at, va_arg(ap, t_gpointer *)); break; - default: goto done; - } - at++; - nargs++; - } -done: - va_end(ap); - typedmess(x, sel, nargs, arg); -} - -void pd_forwardmess(t_pd *x, int argc, t_atom *argv) { - if (argc) { - t_atomtype t = argv->a_type; - if (t==A_SYMBOL) pd_typedmess(x, argv->a_symbol, argc-1, argv+1); - else if (t==A_POINTER) {if (argc==1) pd_pointer(x, argv->a_gpointer); else pd_list(x, &s_list, argc, argv);} - else if (t==A_FLOAT) {if (argc==1) pd_float( x, argv->a_float); else pd_list(x, &s_list, argc, argv);} - else bug("pd_forwardmess"); - } -} - -void nullfn () {} - -t_gotfn getfn(t_pd *x, t_symbol *s) { - t_class *c = x->_class; t_methodentry *m = c->methods; - for (int i=c->nmethod; i--; m++) if (m->me_name == s) return m->me_fun; - error("%s: no method for message '%s'", c->name->name, s->name); - return (t_gotfn)nullfn; -} -t_gotfn zgetfn(t_pd *x, t_symbol *s) { - t_class *c = x->_class; t_methodentry *m = c->methods; - for (int i=c->nmethod; i--; m++) if (m->me_name == s) return m->me_fun; - return 0; -} - -void class_settip(t_class *x,t_symbol* s) {x->firsttip = s;} - -/* must be called only once */ -void class_setfieldnames(t_class *x, const char *s) { - char foo[64]; - while (*s) { - const char *t = strchr(s,' '); - int i = t-s; - if (!t) return; - memcpy(foo,s,i); - foo[i]=0; - x->fields[x->nfields++] = gensym(foo); - s=s+i+1; - } -} - -int class_getfieldindex(t_class *x, const char *s) { - t_symbol *sy = gensym((char *)s); - for (int i=0; i<x->nfields; i++) if (x->fields[i]==sy) return i; - return -1; -} - -/* only looks for already loaded classes though. */ -t_class *class_find (t_symbol *s) {return (t_class *)class_table->get(s);} - -void glob_update_class_info (t_pd *bogus, t_symbol *s, t_symbol *cb_recv, t_symbol *cb_sel) { - t_class *c = class_find(s); - if (!c) { post("class not found!"); return; } - sys_vgui("global class_info; set class_info(%s) [list " - "helpname \"%s\" externdir \"%s\" size \"%d\" " -/* - t_methodentry *c_methods; int c_nmethod; - t_method c_freemethod; - t_savefn c_savefn; - int c_floatsignalin; -*/ - "gobj \"%d\" patchable \"%d\" firstin \"%d\" " - "firsttip \"%s\" methods {",s->name,c->helpname->name,c->externdir->name, - c->size,c->gobj,c->patchable,c->firstin,c->firsttip->name); - if (c-> bangmethod != pd_defaultbang) sys_vgui("<bang> "); - if (c->pointermethod != pd_defaultpointer) sys_vgui("<pointer> "); - if (c-> floatmethod != pd_defaultfloat) sys_vgui("<float> "); - if (c-> symbolmethod != pd_defaultsymbol) sys_vgui("<symbol> "); - if (c-> listmethod != pd_defaultlist) sys_vgui("<list> "); - if (c-> anymethod != pd_defaultanything) sys_vgui("<any> "); - for (int i=0; i<c->nmethod; i++) sys_vgui("%s ",c->methods[i].me_name->name); - sys_vgui("}]; %s %s %s\n",cb_recv->name, cb_sel->name, s->name); -} - -t_class *binbuf_class; - -t_binbuf *binbuf_new () { - t_binbuf *x = (t_binbuf *)pd_new(binbuf_class); - x->n = 0; - x->capa = 1; - x->v = (t_atom *)malloc(1*sizeof(t_atom)); - return x; -} - -/* caution: capa >= x->n and capa >= 1 too */ -static void binbuf_capa(t_binbuf *x, int capa) { - x->v = (t_atom *)realloc(x->v, capa*sizeof(*x->v)); - x->capa = capa; -} - -void binbuf_free(t_binbuf *x) {pd_free(x);} -void binbuf_free2(t_binbuf *x) {free(x->v);} - -t_binbuf *binbuf_duplicate(t_binbuf *y) { - t_binbuf *x = (t_binbuf *)malloc(sizeof(*x)); - x->capa = x->n = y->n; - x->v = (t_atom *)malloc(x->n * sizeof(*x->v)); - memcpy(x->v,y->v,x->n*sizeof(*x->v)); - return x; -} - -void binbuf_clear(t_binbuf *x) { - x->n = 0; - x->v = (t_atom *)realloc(x->v,4); - x->capa = 4; -} - -/* called just after a doublequote in version 1 parsing */ -const char *binbuf_text_quoted(t_binbuf *x, const char *t, char *end) { - ostringstream buf; - while (t!=end) { - char c = *t++; - if (c=='"') break; - if (c!='\\') {buf << c; continue;} - c = *t++; - if (c=='a') {buf << '\a'; continue;} - if (c=='b') {buf << '\b'; continue;} - if (c=='f') {buf << '\f'; continue;} - if (c=='n') {buf << '\n'; continue;} - if (c=='r') {buf << '\r'; continue;} - if (c=='v') {buf << '\v'; continue;} - if (c=='t') {buf << '\t'; continue;} - if (c=='"') {buf << '\"'; continue;} - if (c=='\\'){buf << '\\'; continue;} - if (c=='\n'){continue;} - /* if (c=='u') ... */ - /* if (c=='x') ... */ - /* if (isdigit(c)) ... */ - buf << c; /* ignore syntax error (should it?) */ - } - binbuf_addv(x,"t",buf.str().data()); - return t; /* ignore syntax error (should it?) */ -} - -/* find the first atom in text, in any, and add it to this binbuf; - returns pointer to end of atom text */ -/* this one is for pd format version 1 */ -/* TODO: double-quotes, braces, test backslashes&dollars */ -const char *binbuf_text_matju(t_binbuf *x, const char *t, const char *end) { - int doll=0; - while (t!=end && isspace(*t)) t++; - if (t==end) return t; - if (*t==';') {binbuf_addv(x,";"); return t+1;} - if (*t==',') {binbuf_addv(x,","); return t+1;} - /* if (*t=='"') return binbuf_text_quoted(x,t,end); */ - if (*t=='+' || *t=='-' || *t=='.' || isdigit(*t)) { - char *token; - double v = strtod(t,&token); - if (t==end || isspace(*token)) {binbuf_addv(x,"f",v); return token;} - } - ostringstream buf; - for (; t!=end && *t!=',' && *t!=';' && !isspace(*t); ) { - doll |= t[0]=='$' && t+1!=end && isdigit(t[1]); - if (*t=='\\') t++; - if (t!=end) buf << *t++; - } - if (doll) { - const char *b = buf.str().data(); - if (b[0]!='$') doll=0; - for (b++; *b; b++) if (!isdigit(*b)) doll=0; - if (doll) binbuf_addv(x,"$",atoi(buf.str().data()+1)); - else binbuf_addv(x,"&",gensym(buf.str().data())); - } else binbuf_addv(x,"t",buf.str().data()); - return t; -} - -/* this one is for pd format version 0 */ -const char *binbuf_text_miller(t_binbuf *x, const char *t, const char *end) { - ostringstream buf; - /* it's an atom other than a comma or semi */ - int q = 0, slash = 0, lastslash = 0, dollar = 0; - /* skip leading space */ - while (t!=end && isspace(*t)) t++; - if (t==end) return t; - if (*t==';') {binbuf_addv(x,";"); return t+1;} - if (*t==',') {binbuf_addv(x,","); return t+1;} - do { - char c = *t++; - lastslash = slash; - slash = c=='\\'; - if (q >= 0) { - int digit = isdigit(c), dot=c=='.', minus=c=='-', plusminus=minus||c=='+', expon=c=='e'||c=='E'; - if (q==0) { /* beginning */ if (minus) q=1; else if (digit) q=2; else if (dot) q=3; else q=-1;} - else if (q==1) { /* got minus */ if (digit) q=2; else if (dot) q=3; else q=-1;} - else if (q==2) { /* got digits */ if (dot) q=4; else if (expon) q=6; else if (!digit) q=-1;} - else if (q==3) { /* got '.' without digits */ if (digit) q=5; else q=-1;} - else if (q==4) { /* got '.' after digits */ if (digit) q=5; else if (expon) q=6; else q=-1;} - else if (q==5) { /* got digits after . */ if (expon) q=6; else if (!digit) q=-1;} - else if (q==6) { /* got 'e' */ if (plusminus) q=7; else if (digit) q=8; else q=-1;} - else if (q==7) { /* got plus or minus */ if (digit) q=8; else q=-1;} - else if (q==8) { /* got digits */ if (!digit) q=-1;} - } - if (!lastslash && c == '$' && t!=end && isdigit(*t)) dollar = 1; -#if 1 - if (slash&&lastslash) slash=0; -#endif - if (!slash) buf << c; - } while (t!=end && (slash || !strchr(" \n\r\t,;",*t))); - if (q == 2 || q == 4 || q == 5 || q == 8) {binbuf_addv(x,"f",atof(buf.str().data())); return t;} - /* LATER try to figure out how to mix "$" and "\$" correctly; here, the backslashes were already - stripped so we assume all "$" chars are real dollars. In fact, we only know at least one was. */ - if (dollar) { - const char *b = buf.str().data(); - //printf("b=%s\n",b); - if (*b != '$') dollar = 0; - for (b++; *b; b++) if (!isdigit(*b)) dollar = 0; - if (dollar) binbuf_addv(x,"$",atoi(buf.str().data()+1)); - else binbuf_addv(x,"&",gensym(buf.str().data())); - } else binbuf_addv(x,"t",buf.str().data()); - return t; -} - -int sys_syntax = 0; - -void binbuf_text(t_binbuf *x, const char *t, size_t size) { - const char *end=t+size; - binbuf_clear(x); - while (t!=end) t = sys_syntax ? binbuf_text_matju(x,t,end) : binbuf_text_miller(x,t,end); - binbuf_capa(x,x->n); -} - -void pd_eval_text(const char *t, size_t size) { - t_binbuf *x = binbuf_new(); - const char *end = t+size; - while (t!=end) { - t = sys_syntax ? binbuf_text_matju(x,t,end) : binbuf_text_miller(x,t,end); - if (x->n && x->v[x->n-1].a_type == A_SEMI) { - binbuf_eval(x,0,0,0); - binbuf_clear(x); - } - } - binbuf_free(x); -} - -namespace desire { -void voprintf(ostream &buf, const char *s, va_list args) { - char *b; - vasprintf(&b,s,args); - buf << b; - free(b); -} -void oprintf(ostream &buf, const char *s, ...) { - va_list args; - va_start(args,s); - voprintf(buf,s,args); - va_end(args); -} -};//end namespace desire - -/* convert a binbuf to text; no null termination. */ -void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp) { - ostringstream buf; - t_atom *ap = x->v; - char nextdelim=0; - for (int i=x->n; i--; ap++) { - if (ap->a_type != A_SEMI && ap->a_type != A_COMMA && nextdelim) buf << (char)nextdelim; - atom_ostream(ap,buf); - nextdelim = ap->a_type == A_SEMI ? '\n' : ' '; - } - //if (nextdelim) buf << (char)nextdelim; - *bufp = strdup(buf.str().data()); - *lengthp = buf.str().size();// - (nextdelim == ' '); -} - -/* convert a binbuf to text with null termination, as return value */ -char *binbuf_gettext2(t_binbuf *x) { - char *buf; int n; - binbuf_gettext(x,&buf,&n); - buf[n] = 0; - return (char *)realloc(buf,n+1); -} - -/* Miller said: fix this so that writing to file doesn't buffer everything together. */ -/* matju said: make this use vector size doubling as it used to be in binbuf_text */ -void binbuf_add(t_binbuf *x, int argc, t_atom *argv) { - int newsize = x->n + argc; - t_atom *ap = (t_atom *)realloc(x->v,newsize*sizeof(*x->v)); - x->v = ap; - ap += x->n; - for (int i = argc; i--; ap++) *ap = *(argv++); - x->capa = x->n = newsize; -} - -#define MAXADDMESSV 100 -void binbuf_addv(t_binbuf *x, const char *fmt, ...) { - va_list ap; - t_atom arg[MAXADDMESSV], *at =arg; - int nargs = 0; - const char *fp = fmt; - va_start(ap, fmt); - while (1) { - if (nargs >= MAXADDMESSV) { - error("binbuf_addmessv: only %d allowed", MAXADDMESSV); - break; - } - switch(*fp++) { - case 'i': SETFLOAT( at, va_arg(ap, int)); break; - case 'f': SETFLOAT( at, va_arg(ap, double)); break; - case 's': SETSYMBOL(at, va_arg(ap, t_symbol *)); break; - case 't': SETSYMBOL(at, gensym(va_arg(ap, char *))); break; - case ';': SETSEMI(at); break; - case ',': SETCOMMA(at); break; - case '$': SETDOLLAR(at, va_arg(ap, int)); break; - case '&': SETDOLLSYM(at, va_arg(ap, t_symbol *)); break; - default: goto done; - } - at++; - nargs++; - } -done: - va_end(ap); - binbuf_add(x, nargs, arg); -} - -/* add a binbuf to another one for saving. Semicolons and commas go to -symbols ";", "'",; the symbol ";" goes to "\;", etc. */ - -void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y) { - t_binbuf *z = binbuf_new(); - binbuf_add(z, y->n, y->v); - t_atom *ap = z->v; - for (size_t i=0; i < z->n; i++, ap++) { - switch (ap->a_type) { - case A_FLOAT: break; - case A_SEMI: SETSYMBOL(ap, gensym(";")); break; - case A_COMMA: SETSYMBOL(ap, gensym(",")); break; - case A_DOLLAR: SETSYMBOL(ap, symprintf("$%ld", ap->a_index)); break; - case A_DOLLSYM: { - ostringstream b; - atom_ostream(ap,b); - SETSYMBOL(ap, gensym(b.str().data()));} break; - case A_SYMBOL: - /* FIXME make this general */ - if (!strcmp(ap->a_symbol->name, ";")) SETSYMBOL(ap, gensym(";")); - else if (!strcmp(ap->a_symbol->name, ",")) SETSYMBOL(ap, gensym(",")); - break; - default: - //bug("binbuf_addbinbuf: stray atom of type %d",ap->a_type); - //abort(); - ; - } - } - binbuf_add(x, z->n, z->v); -} - -void binbuf_addsemi(t_binbuf *x) { - t_atom a; - SETSEMI(&a); - binbuf_add(x, 1, &a); -} - -/* Supply atoms to a binbuf from a message, making the opposite changes -from binbuf_addbinbuf. The symbol ";" goes to a semicolon, etc. */ - -void binbuf_restore(t_binbuf *x, int argc, t_atom *argv) { - int newsize = x->n + argc; - t_atom *ap = (t_atom *)realloc(x->v,(newsize+1)*sizeof(*x->v)); - if (!ap) {error("binbuf_addmessage: out of space"); return;} - x->v = ap; - ap = x->v + x->n; - for (int i = argc; i--; ap++) { - if (argv->a_type == A_SYMBOL) { - char *str = argv->a_symbol->name, *str2; - if (!strcmp(str, ";")) SETSEMI(ap); - else if (!strcmp(str, ",")) SETCOMMA(ap); - else if ((str2 = strchr(str, '$')) && isdigit(str2[1])) { - int dollsym = 0; - if (*str != '$') dollsym = 1; - else for (str2 = str + 1; *str2; str2++) if (!isdigit(*str2)) { - dollsym = 1; - break; - } - if (dollsym) SETDOLLSYM(ap, gensym(str)); - else { - int dollar = 0; - sscanf(argv->a_symbol->name + 1, "%d", &dollar); - SETDOLLAR(ap, dollar); - } - } else *ap = *argv; - argv++; - } else *ap = *(argv++); - } - x->n = newsize; -} - -#define MSTACKSIZE 2048 - -void binbuf_print(t_binbuf *x) { - int startedpost = 0, newline = 1; - for (size_t i=0; i < x->n; i++) { - if (newline) { - if (startedpost) endpost(); - startpost("%s",""); /* dummy string to fool __attribute__ */ - startedpost = 1; - } - postatom(1, x->v + i); - newline = !! x->v[i].a_type == A_SEMI; - } - if (startedpost) endpost(); -} - -int binbuf_getnatom(t_binbuf *x) {return x->n;} -t_atom *binbuf_getvec(t_binbuf *x) {return x->v;} - -int canvas_getdollarzero (); - -/* JMZ: - * s points to the first character after the $ - * (e.g. if the org.symbol is "$1-bla", then s will point to "1-bla") - * (e.g. org.symbol="hu-$1mu", s="1mu") - * LATER: think about more complex $args, like ${$1+3} - * - * the return value holds the length of the $arg (in most cases: 1) - * buf holds the expanded $arg - * - * if some error occurred, "-1" is returned - * - * e.g. "$1-bla" with list "10 20 30" - * s="1-bla" - * buf="10" - * return value = 1; (s+1=="-bla") - */ -static int binbuf_expanddollsym(char *s, std::ostream &buf, t_atom dollar0, int ac, t_atom *av, int tonew) { - int argno=atol(s); - int arglen=0; - char*cs=s; - char c=*cs; - while (c && isdigit(c)) { - c=*cs++; - arglen++; - } - /* invalid $-expansion (like "$bla") */ - if (cs==s) {buf << "$"; return 0;} - if (argno < 0 || argno > ac) { /* undefined argument */ - if(!tonew) return 0; - buf << "$" << argno; - } else if (argno == 0) { /* $0 */ - atom_ostream(&dollar0, buf); - } else { /* fine! */ - atom_ostream(av+(argno-1), buf); - } - return arglen-1; -} - -/* LATER remove the dependence on the current canvas for $0; should be another argument. */ -t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew) { - ostringstream buf2; - char *str=s->name; - t_atom dollarnull; - SETFLOAT(&dollarnull, canvas_getdollarzero()); - /* JMZ: currently, a symbol is detected to be A_DOLLSYM if it starts with '$' - * the leading $ is stripped and the rest stored in "s". i would suggest to NOT strip the leading $ - * and make everything a A_DOLLSYM that contains(!) a $ whenever this happened, enable this code */ - char *substr=strchr(str, '$'); - if(!substr) return s; - oprintf(buf2,"%.*s",substr-str,str); - str=substr+1; - for (;;) { - std::ostringstream buf; - int next = binbuf_expanddollsym(str, buf, dollarnull, ac, av, tonew); - if (next<0) break; - /* JMZ: i am not sure what this means, so i might have broken it. it seems like that if "tonew" is - set and the $arg cannot be expanded (or the dollarsym is in reality a A_DOLLAR). - 0 is returned from binbuf_realizedollsym; this happens when expanding in a message-box, - but does not happen when the A_DOLLSYM is the name of a subpatch */ - /* JMZ: this should mimick the original behaviour */ - if(!tonew && !next && buf.str().size()==0) return 0; - buf2 << buf.str(); - str+=next; - substr=strchr(str, '$'); - if(substr) { - oprintf(buf2,"%.*s",substr-str,str); - str=substr+1; - } else { - buf2 << str; - return gensym(buf2.str().data()); - } - } - return gensym(buf2.str().data()); -} - -void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv) { - static t_atom mstack[MSTACKSIZE], *msp = mstack, *ems = mstack+MSTACKSIZE; - t_atom *stackwas = msp; - t_atom *at = x->v; - int ac = x->n; - int nargs; - while (1) { - t_pd *nexttarget; - while (!target) { - t_symbol *s; - while (ac && (at->a_type == A_SEMI || at->a_type == A_COMMA)) {ac--; at++;} - if (!ac) break; - if (at->a_type == A_DOLLAR) { - if (at->a_index<=0 || at->a_index>argc) {error("$%ld: not enough arguments supplied",long(at->a_index)); goto cleanup;} - else if (argv[at->a_index-1].a_type!=A_SYMBOL) {error("$%ld: symbol needed as receiver",long(at->a_index)); goto cleanup;} - else s = argv[at->a_index-1].a_symbol; - } else if (at->a_type == A_DOLLSYM) { - s = binbuf_realizedollsym(at->a_symbol, argc, argv, 0); - if (!s) {error("$%s: not enough arguments supplied", at->a_symbol->name); goto cleanup;} - } else s = atom_getsymbol(at); - target = s->thing; - /* IMPD: allows messages to unbound objects, via pointers */ - if (!target) { - if (!sscanf(s->name,".x%lx",(long*)&target)) target=0; - if (target) { - if (!object_table->exists(target) || !object_table->get(target)) { - error("%s target is not a currently valid pointer",s->name); - return; - } - } - } - if (!target) {error("%s: no such object", s->name); goto cleanup;} - at++; - ac--; - break; - cleanup: - do {at++; ac--;} while (ac && at->a_type != A_SEMI); /* is this the correct thing to do? */ - continue; - } - if (!ac) break; - nargs = 0; - nexttarget = target; - while (1) { - if (!ac) goto gotmess; - if (msp >= ems) {error("message too long"); goto broken;} - switch (at->a_type) { - /* semis and commas in new message just get bashed to a symbol. This is needed so you can pass them to "expr." */ - case A_SEMI: if (target == &pd_objectmaker) {SETSYMBOL(msp, gensym(";")); break;} else {nexttarget = 0; goto gotmess;} - case A_COMMA: if (target == &pd_objectmaker) {SETSYMBOL(msp, gensym(",")); break;} else goto gotmess; - case A_FLOAT: - case A_SYMBOL: - *msp = *at; - break; - case A_DOLLAR: - if (at->a_index > 0 && at->a_index <= argc) *msp = argv[at->a_index-1]; - else if (at->a_index == 0) SETFLOAT(msp, canvas_getdollarzero()); - else { - SETFLOAT(msp, 0); - if (target != &pd_objectmaker) error("$%ld: argument number out of range",long(at->a_index)); - } - break; - case A_DOLLSYM: { - t_symbol *s9 = binbuf_realizedollsym(at->a_symbol, argc, argv, target == &pd_objectmaker); - if (!s9) { - error("%s: argument number out of range", at->a_symbol->name); - SETSYMBOL(msp, at->a_symbol); - } else SETSYMBOL(msp, s9); - break;} - default: - bug("bad item in binbuf"); - goto broken; - } - msp++; - ac--; - at++; - nargs++; - } - gotmess: - if (nargs) { - switch (stackwas->a_type) { - case A_SYMBOL: typedmess(target, stackwas->a_symbol, nargs-1, stackwas+1); break; - case A_FLOAT: if (nargs == 1) pd_float(target, stackwas->a_float); else pd_list(target, 0, nargs, stackwas); break; - default: {} - } - } - msp = stackwas; - if (!ac) break; - target = nexttarget; - at++; - ac--; - } - return; -broken: - msp = stackwas; -} - -static int binbuf_doopen(char *s, int mode) { - char namebuf[strlen(s)+1]; -#ifdef MSW - mode |= O_BINARY; -#endif - sys_bashfilename(s, namebuf); - return open(namebuf, mode); -} - -static FILE *binbuf_dofopen(const char *s, const char *mode) { - char namebuf[strlen(s)+1]; - sys_bashfilename(s, namebuf); - return fopen(namebuf, mode); -} - -int binbuf_read(t_binbuf *b, const char *filename, const char *dirname, int flags) { - long length; - char *buf; - char *namebuf=0; - if (*dirname) asprintf(&namebuf,"%s/%s",dirname,filename); - else asprintf(&namebuf, "%s", filename); - int fd = binbuf_doopen(namebuf, 0); - if (fd < 0) {error("open: %s: %s",namebuf,strerror(errno)); return 1;} - if ((length = lseek(fd, 0, SEEK_END)) < 0 || lseek(fd, 0, SEEK_SET) < 0 || !(buf = (char *)malloc(length))) { - error("lseek: %s: %s",namebuf,strerror(errno)); - close(fd); free(namebuf); - return 1; - } - int readret = read(fd, buf, length); - if (readret < length) { - error("read (%d %ld) -> %d; %s: %s", fd, length, readret, namebuf, strerror(errno)); - close(fd); free(namebuf); free(buf); - return 1; - } - if (flags&1) for (int i=0; i<length; i++) if (buf[i]=='\n') buf[i] = ';'; - if (flags&2) pd_eval_text(buf,length); else binbuf_text(b, buf, length); - close(fd); free(namebuf); free(buf); - return 0; -} - -/* read a binbuf from a file, via the search patch of a canvas */ -int binbuf_read_via_canvas(t_binbuf *b, const char *filename, t_canvas *canvas, int flags) { - char *buf, *bufptr; int fd = canvas_open2(canvas, filename, "", &buf, &bufptr, 0); - if (fd<0) {error("%s: can't open", filename); return 1;} - close(fd); free(buf); - return !!binbuf_read(b, bufptr, buf, flags); -} -/* old version */ -int binbuf_read_via_path(t_binbuf *b, char const *filename, const char *dirname, int flags) { - char *buf, *bufptr; int fd = open_via_path2(dirname, filename, "", &buf, &bufptr, 0); - if (fd<0) {error("%s: can't open", filename); return 1;} - close(fd); - bool r = binbuf_read(b, bufptr, buf, flags); - free(buf); - return r; -} - -#define WBUFSIZE 4096 -static t_binbuf *binbuf_convert(t_binbuf *oldb, int maxtopd); - -/* write a binbuf to a text file. If "crflag" is set we suppress semicolons. */ -int binbuf_write(t_binbuf *x, const char *filename, const char *dir, int crflag) { - char sbuf[WBUFSIZE]; - ostringstream fbuf; - char *bp = sbuf, *ep = sbuf + WBUFSIZE; - int indx; bool deleteit = 0; - int ncolumn = 0; - if (*dir) fbuf << dir << "/"; - fbuf << filename; - if (!strcmp(filename + strlen(filename) - 4, ".pat")) { - x = binbuf_convert(x, 0); - deleteit = 1; - } - FILE *f = binbuf_dofopen(fbuf.str().data(), "w"); - if (!f) {error("open: %s: %s",fbuf.str().data(),strerror(errno)); goto fail;} - indx = x->n; - for (t_atom *ap = x->v; indx--; ap++) { - /* estimate how many characters will be needed. Printing out symbols may need extra characters for inserting backslashes. */ - int length = (ap->a_type == A_SYMBOL || ap->a_type == A_DOLLSYM) ? 80 + strlen(ap->a_symbol->name) : 40; - if (ep - bp < length) { - if (fwrite(sbuf, bp-sbuf, 1, f) < 1) {error("write: %s: %s",fbuf.str().data(),strerror(errno)); goto fail;} - bp = sbuf; - } - if ((ap->a_type == A_SEMI || ap->a_type == A_COMMA) && bp > sbuf && bp[-1] == ' ') bp--; - if (!crflag || ap->a_type != A_SEMI) { - atom_string(ap, bp, (ep-bp)-2); - length = strlen(bp); - bp += length; - ncolumn += length; - } - if (ap->a_type == A_SEMI || (!crflag && ncolumn > 65)) { - *bp++ = '\n'; - ncolumn = 0; - } else { - *bp++ = ' '; - ncolumn++; - } - } - if (fwrite(sbuf, bp-sbuf, 1, f) < 1) {error("write: %s: %s",fbuf.str().data(),strerror(errno)); goto fail;} - if (deleteit) binbuf_free(x); - fclose(f); - return 0; -fail: - if (deleteit) binbuf_free(x); - if (f) fclose(f); - return 1; -} - -/* The following routine attempts to convert from max to pd or back. The max to pd direction is working OK - but you will need to make lots of abstractions for objects like "gate" which don't exist in Pd. Conversion - from Pd to Max hasn't been tested for patches with subpatches yet! */ -#define MAXSTACK 1000 -#define ISSYMBOL(a, b) ((a)->a_type == A_SYMBOL && !strcmp((a)->a_symbol->name, (b))) -#define GETF(i) atom_getfloatarg(i,natom,nextmess) -static t_binbuf *binbuf_convert(t_binbuf *oldb, int maxtopd) { - t_binbuf *newb = binbuf_new(); - t_atom *vec = oldb->v; - t_int n = oldb->n, nextindex, stackdepth = 0, stack[MAXSTACK], nobj = 0; - t_atom outmess[MAXSTACK], *nextmess; - if (!maxtopd) binbuf_addv(newb,"tt;","max","v2"); - for (nextindex = 0; nextindex < n; ) { - int endmess, natom; - for (endmess = nextindex; endmess < n && vec[endmess].a_type != A_SEMI; endmess++) {} - if (endmess == n) break; - if (endmess == nextindex || endmess == nextindex + 1 - || vec[nextindex].a_type != A_SYMBOL || vec[nextindex+1].a_type != A_SYMBOL) { - nextindex = endmess + 1; - continue; - } - natom = endmess - nextindex; - if (natom > MAXSTACK-10) natom = MAXSTACK-10; - nextmess = vec + nextindex; - char *first = nextmess ->a_symbol->name; - char *second = (nextmess+1)->a_symbol->name; - if (maxtopd) { /* case 1: importing a ".pat" file into Pd. */ - /* dollar signs in file translate to symbols */ - for (int i=0; i<natom; i++) { - if (nextmess[i].a_type == A_DOLLAR) { - SETSYMBOL(nextmess+i, symprintf("$%ld",nextmess[i].a_index)); - } else if (nextmess[i].a_type == A_DOLLSYM) { - SETSYMBOL(nextmess+i, gensym(nextmess[i].a_symbol->name)); - } - } - if (!strcmp(first, "#N")) { - if (!strcmp(second, "vpatcher")) { - if (stackdepth >= MAXSTACK) {post("too many embedded patches"); return newb;} - stack[stackdepth] = nobj; - stackdepth++; - nobj = 0; - binbuf_addv(newb,"ttfffff;","#N","canvas", GETF(2), GETF(3), GETF(4)-GETF(2), GETF(5)-GETF(3), 10.); - } - } - if (!strcmp(first, "#P")) { - /* drop initial "hidden" flag */ - if (!strcmp(second, "hidden")) { - nextmess++; - natom--; - second = (nextmess+1)->a_symbol->name; - } - if (natom >= 7 && !strcmp(second, "newobj") - && (ISSYMBOL(&nextmess[6], "patcher") || ISSYMBOL(&nextmess[6], "p"))) { - binbuf_addv(newb,"ttffts;","#X","restore", GETF(2), GETF(3), - "pd", atom_getsymbolarg(7, natom, nextmess)); - if (stackdepth) stackdepth--; - nobj = stack[stackdepth]; - nobj++; - } else if (!strcmp(second, "newex") || !strcmp(second, "newobj")) { - t_symbol *classname = atom_getsymbolarg(6, natom, nextmess); - if (classname == gensym("trigger") || classname == gensym("t")) { - for (int i=7; i<natom; i++) - if (nextmess[i].a_type == A_SYMBOL && nextmess[i].a_symbol == gensym("i")) - nextmess[i].a_symbol = gensym("f"); - } - if (classname == gensym("table")) classname = gensym("TABLE"); - SETSYMBOL(outmess, gensym("#X")); - SETSYMBOL(outmess + 1, gensym("obj")); - outmess[2] = nextmess[2]; - outmess[3] = nextmess[3]; - SETSYMBOL(outmess+4, classname); - for (int i=7; i<natom; i++) outmess[i-2] = nextmess[i]; - SETSEMI(outmess + natom - 2); - binbuf_add(newb, natom - 1, outmess); - nobj++; - } else if (!strcmp(second, "message") || !strcmp(second, "comment")) { - SETSYMBOL(outmess, gensym("#X")); - SETSYMBOL(outmess + 1, gensym((char *)(strcmp(second, "message") ? "text" : "msg"))); - outmess[2] = nextmess[2]; - outmess[3] = nextmess[3]; - for (int i=6; i<natom; i++) outmess[i-2] = nextmess[i]; - SETSEMI(outmess + natom - 2); - binbuf_add(newb, natom - 1, outmess); - nobj++; - } else if (!strcmp(second, "button")) { - binbuf_addv(newb,"ttfft;","#X","obj",GETF(2),GETF(3),"bng"); - nobj++; - } else if (!strcmp(second, "number") || !strcmp(second, "flonum")) { - binbuf_addv(newb,"ttff;","#X","floatatom",GETF(2),GETF(3)); - nobj++; - } else if (!strcmp(second, "slider")) { - float inc = GETF(7); - if (inc <= 0) inc = 1; - binbuf_addv(newb, "ttfftfffffftttfffffffff;","#X","obj", - GETF(2), GETF(3), "vsl", GETF(4), GETF(5), GETF(6), GETF(6)+(GETF(5)-1)*inc, - 0., 0., "empty", "empty", "empty", 0., -8., 0., 8., -262144., -1., -1., 0., 1.); - nobj++; - } else if (!strcmp(second, "toggle")) { - binbuf_addv(newb,"ttfft;","#X","obj",GETF(2),GETF(3),"tgl"); - nobj++; - } else if (!strcmp(second, "inlet")) { - binbuf_addv(newb,"ttfft;","#X","obj",GETF(2),GETF(3), natom > 5 ? "inlet~" : "inlet"); - nobj++; - } else if (!strcmp(second, "outlet")) { - binbuf_addv(newb,"ttfft;","#X","obj",GETF(2),GETF(3), natom > 5 ? "outlet~" : "outlet"); - nobj++; - } else if (!strcmp(second, "user")) { - binbuf_addv(newb,"ttffs;","#X","obj", GETF(3), GETF(4), atom_getsymbolarg(2, natom, nextmess)); - nobj++; - } else if (!strcmp(second, "connect") || !strcmp(second, "fasten")) { - binbuf_addv(newb,"ttffff;","#X","connect", nobj-GETF(2)-1, GETF(3), nobj-GETF(4)-1, GETF(5)); - } - } - } else { /* Pd to Max */ - if (!strcmp(first, "#N")) { - if (!strcmp(second, "canvas")) { - if (stackdepth >= MAXSTACK) { - post("too many embedded patches"); - return newb; - } - stack[stackdepth] = nobj; - stackdepth++; - nobj = 0; - binbuf_addv(newb,"ttffff;","#N","vpatcher", GETF(2), GETF(3), GETF(4), GETF(5)); - } - } - if (!strcmp(first, "#X")) { - if (natom >= 5 && !strcmp(second, "restore") && (ISSYMBOL (&nextmess[4], "pd"))) { - binbuf_addv(newb,"tt;","#P","pop"); - binbuf_addv(newb,"ttffffts;","#P","newobj", GETF(2), GETF(3), 50., 1., - "patcher", atom_getsymbolarg(5, natom, nextmess)); - if (stackdepth) stackdepth--; - nobj = stack[stackdepth]; - nobj++; - } else if (!strcmp(second, "obj")) { - t_symbol *classname = atom_getsymbolarg(4, natom, nextmess); - if (classname == gensym("inlet")) binbuf_addv(newb,"ttfff;","#P","inlet", GETF(2), GETF(3), 15.); - else if (classname == gensym("inlet~")) binbuf_addv(newb,"ttffff;","#P","inlet", GETF(2), GETF(3), 15., 1.); - else if (classname == gensym("outlet")) binbuf_addv(newb,"ttfff;","#P","outlet", GETF(2), GETF(3), 15.); - else if (classname == gensym("outlet~")) binbuf_addv(newb,"ttffff;","#P","outlet", GETF(2), GETF(3), 15., 1.); - else if (classname == gensym("bng")) binbuf_addv(newb,"ttffff;","#P","button", GETF(2), GETF(3), GETF(5), 0.); - else if (classname == gensym("tgl")) binbuf_addv(newb,"ttffff;","#P","toggle", GETF(2), GETF(3), GETF(5), 0.); - else if (classname == gensym("vsl")) binbuf_addv(newb,"ttffffff;","#P","slider", - GETF(2), GETF(3), GETF(5), GETF(6), (GETF(8)-GETF(7)) / (GETF(6)==1?1:GETF(6)-1), GETF(7)); - else { - binbuf_addv(newb,"ttffff","#P","newex", GETF(2), GETF(3), 50., 1.); - for (int i=4; i<natom; i++) outmess[i-4] = nextmess[i]; - binbuf_add(newb, natom-4, outmess); - binbuf_addv(newb,";"); - } - nobj++; - } else if (!strcmp(second, "msg") || !strcmp(second, "text")) { - binbuf_addv(newb,"ttffff","#P",strcmp(second, "msg") ? "comment" : "message",GETF(2),GETF(3),50.,1.); - for (int i=4; i<natom; i++) outmess[i-4] = nextmess[i]; - binbuf_add(newb, natom-4, outmess); - binbuf_addv(newb,";"); - nobj++; - } else if (!strcmp(second, "floatatom")) { - binbuf_addv(newb, "ttfff;", "#P", "flonum", GETF(2), GETF(3), 35); - nobj++; - } else if (!strcmp(second, "connect")) { - binbuf_addv(newb, "ttffff;", "#P", "connect", nobj-GETF(2)-1, GETF(3), nobj-GETF(4)-1, GETF(5)); - } - } - } - nextindex = endmess + 1; - } - if (!maxtopd) binbuf_addv(newb, "tt;", "#P", "pop"); -#if 0 - binbuf_write(newb, "import-result.pd", "/tmp", 0); -#endif - return newb; -} - -/* function to support searching */ -int binbuf_match(t_binbuf *inbuf, t_binbuf *searchbuf) { - for (size_t indexin = 0; indexin <= inbuf->n - searchbuf->n; indexin++) { - for (size_t nmatched = 0; nmatched < searchbuf->n; nmatched++) { - t_atom *a1 = &inbuf->v[indexin + nmatched], *a2 = &searchbuf->v[nmatched]; - if (a1->a_type != a2->a_type || - (a1->a_type == A_SYMBOL && a1->a_symbol != a2->a_symbol) || - (a1->a_type == A_FLOAT && a1->a_float != a2->a_float ) || - (a1->a_type == A_DOLLAR && a1->a_index != a2->a_index ) || - (a1->a_type == A_DOLLSYM && a1->a_symbol != a2->a_symbol)) goto nomatch; - } - return 1; - nomatch: ; - } - return 0; -} - -/* LATER figure out how to log errors */ -void binbuf_evalfile(t_symbol *name, t_symbol *dir) { - t_binbuf *b = binbuf_new(); - int import = !strcmp(name->name + strlen(name->name) - 4, ".pat"); - /* set filename so that new canvases can pick them up */ - int dspstate = canvas_suspend_dsp(); - glob_setfilename(0, name, dir); - if (import) { - if (binbuf_read(b, name->name, dir->name, 0)) {perror(name->name); goto bye;} - t_binbuf *newb = binbuf_convert(b, 1); - binbuf_free(b); - b = newb; - } else { - if (binbuf_read(b, name->name, dir->name, 2)) perror(name->name); - } -bye: - glob_setfilename(0, &s_, &s_); /* bug fix by Krzysztof Czaja */ - binbuf_free(b); - canvas_resume_dsp(dspstate); -} - -void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir) { - /* even though binbuf_evalfile appears to take care of dspstate, we have to do it again here, because - canvas_startdsp() assumes that all toplevel canvases are visible. LATER: check if this is still necessary (probably not) */ - int dspstate = canvas_suspend_dsp(); - binbuf_evalfile(name, dir); - t_pd *x = 0; - while ((x != s__X.thing) && (x = s__X.thing)) vmess(x, gensym("pop"), "i", 1); - if (lastpopped) pd_vmess(lastpopped, gensym("loadbang"), ""); - lastpopped = 0; - canvas_resume_dsp(dspstate); -} - -//copied from m_pd.h -#define class_new2(NAME,NU,FREE,SIZE,FLAGS,SIG) class_new2(NAME,(t_newmethod)NU,(t_method)FREE,SIZE,FLAGS,SIG) - -extern "C" { -void conf_init(); -void glob_init(); -void boxes_init(); -void garray_init(); -void pd_init() { - object_table = new t_hash<t_pd *,long>(127); - bindlist_class = class_new(gensym("bindlist"), 0, 0, sizeof(t_bindlist), CLASS_PD, 0); - class_addbang(bindlist_class, (t_method)bindlist_bang); - class_addfloat(bindlist_class, (t_method)bindlist_float); - class_addsymbol(bindlist_class, (t_method)bindlist_symbol); - class_addpointer(bindlist_class, (t_method)bindlist_pointer); - class_addlist(bindlist_class, (t_method)bindlist_list); - class_addanything(bindlist_class, (t_method)bindlist_anything); - binbuf_class = class_new2("__list", binbuf_new, binbuf_free2, sizeof(t_binbuf), CLASS_PD, "*"); - wire_class = class_new2("__wire", wire_new, wire_free, sizeof(t_wire), CLASS_GOBJ, "*"); - class_setsavefn(wire_class,(t_savefn)wire_save); - if (pd_objectmaker._class) bug("ARGH"); - for (size_t i=0; i<sizeof(symlist)/sizeof(*symlist); i++) { - symlist[i]->n = strlen(symlist[i]->name); - dogensym(symlist[i]->name, symlist[i]->n, symlist[i]); /* why does this take three args? */ - } - pd_objectmaker._class = class_new2("objectmaker", 0, 0, sizeof(t_pd), CLASS_DEFAULT, ""); - pd_canvasmaker._class = class_new2("canvasmaker", 0, 0, sizeof(t_pd), CLASS_DEFAULT, ""); - pd_bind(&pd_canvasmaker, &s__N); - class_addanything(pd_objectmaker._class, (t_method)new_anything); - obj_init(); - conf_init(); - glob_init(); - boxes_init(); - garray_init(); -} -}; - -#ifndef HAVE_ASPRINTF -#define HAVE_ASPRINTF -#undef asprintf -#undef vasprintf -int asprintf(char **str, const char *fmt, ...) throw () { - va_list ap; - int ret; - *str = NULL; - va_start(ap, fmt); - ret = vasprintf(str, fmt, ap); - va_end(ap); - return ret; -} -#endif /* HAVE_ASPRINTF */ -#ifndef HAVE_VASPRINTF -#define HAVE_VASPRINTF -#include <stdio.h> -#include <errno.h> -#include <limits.h> -#include <stdarg.h> -#include <stdlib.h> - -#ifndef VA_COPY -# ifdef HAVE_VA_COPY -# define VA_COPY(dest, src) va_copy(dest, src) -# else -# ifdef HAVE___VA_COPY -# define VA_COPY(dest, src) __va_copy(dest, src) -# else -# define VA_COPY(dest, src) (dest) = (src) -# endif -# endif -#endif - -#define INIT_SZ 128 - -int vasprintf(char **str, const char *fmt, va_list ap) throw () { - int ret = -1; - va_list ap2; - char *string, *newstr; - size_t len; - VA_COPY(ap2, ap); - if ((string = (char *)malloc(INIT_SZ)) == NULL) - goto fail; - ret = vsnprintf(string, INIT_SZ, fmt, ap2); - if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ - *str = string; - } else if (ret == INT_MAX || ret < 0) { /* Bad length */ - goto fail; - } else { /* bigger than initial, realloc allowing for nul */ - len = (size_t)ret + 1; - if ((newstr = (char *)realloc(string, len)) == NULL) { - free(string); - goto fail; - } else { - va_end(ap2); - VA_COPY(ap2, ap); - ret = vsnprintf(newstr, len, fmt, ap2); - if (ret >= 0 && (size_t)ret < len) { - *str = newstr; - } else { /* failed with realloc'ed string, give up */ - free(newstr); - goto fail; - } - } - } - va_end(ap2); - return ret; -fail: - *str = NULL; - errno = ENOMEM; - va_end(ap2); - return -1; -} -#endif /* HAVE_VASPRINTF */ diff --git a/desiredata/src/locale/bokmal.tcl b/desiredata/src/locale/bokmal.tcl deleted file mode 100644 index 8db87129..00000000 --- a/desiredata/src/locale/bokmal.tcl +++ /dev/null @@ -1,453 +0,0 @@ -#!/usr/bin/env tclsh -# Norwegian (Norsk Bokml) translations for PureData -# $Id: bokmal.tcl,v 1.1.2.5.2.2 2007-08-06 15:39:57 matju Exp $ -# by Gisle Frysland - -### Menus - -say file "Fil" - say new_file "Ny Fil" - say open_file "pne Fil..." - # say pdrc_editor ".pdrc Redigerer" - say server_prefs "Tjener Egenskaper..." - say client_prefs "Klient Egenskaper..." - say send_message "Send Melding..." - say paths "Stier..." - say close "Lukk" - say save "Lagre" - say save_as "Lagre Som..." - say print "Skriv Ut..." - say abort_server "Avbryt Tjener" - say quit "Avslutt" - - say canvasnew_file "Ny Fil" - say canvasopen_file "pne Fil..." - say canvassave "Lagre" - say canvassave_as "Lagre Som..." - say clientpdrc_editor ".pdrc Redigering" - say clientddrc_editor ".ddrc Redigering" - say canvasclose "Lukk" - say canvasquit "Avslutt" - -say edit "Rediger" - say undo "Angre" - say redo "Gjr Om" - say cut "Klipp Ut" - say copy "Kopier" - say paste "Lim Inn" - say duplicate "Dupliser" - say select_all "Merk Alt" - say clear_selection "Fjern merking" - say text_editor "Tekst Redigerer..." - say font "Skrift" - say tidy_up "Rydd Opp" - say edit_mode "Redigeringsmodus" - say editmodeswitch "Rediger/Kjr modus" - say subpatcherize "Subpatcherize" - - say canvascut "Klipp Ut" - say canvascopy "Kopier" - say canvasundo "Angre" - say canvasredo "Gjr Om" - say canvaspaste "Lim Inn" - say canvasduplicate "Dupliser" - say canvasselect_all "Merk Alt" - say canvaseditmodeswitch "Rediger/Kjr modus" - -say view "Vis" - say reload "Oppdater" - say redraw "Tegn P Nytt" - - say canvasreload "Oppdater" - say canvasredraw "Tegn P Nytt" - -say find "Finn" - say find_again "Finn P Nytt" - say find_last_error "Finn Siste Feil" - say string "Finn Tekst" -say canvasfind "Finn" - say canvasfind_again "Finn P Nytt" - -# contents of Put menu is Phase 5C -say put "Sett Inn" - say Object "Objekt" - say Message "Melding" - say Number "Nummer" - say Symbol "Symbol" - say Comment "Kommentar" - say Graph "Graf" - say Array "Tabell" - -say media "Media" - say audio_on "Audio P" - say audio_off "Audio AV" - say test_audio_and_midi "Test Audio og MIDI" - say load_meter "Belastningsmler" - - say canvasaudio_on "Audio P" - say canvasaudio_off "Audio AV" - say clienttest_audio_and_midi "Test Audio og MIDI" - say canvasload_meter "Belastningsmler" - -say window "Vindu" - -say help "Hjelp" - say about "Om..." - say documentation "Dokumentasjon..." - say class_browser "Klasseleser..." - - say canvasabout "Om..." - -say properties "Egenskaper" -say open "pne" - -### for key binding editor -say general "Generelt" -say audio_settings "Audio Innstillinger" -say midi_settings "Midi Innstillinger" -say latency_meter "Forsinkelsesmler" -say Pdwindow "Pd vindu" - -say canvaspdwindow "Pd vindu" -say canvaslatency_meter "Forsinkelsesmler" -say clientaudio_settings "Audio Innstillinger" -say clientmidi_settings "Midi Innstillinger" - - -say_namespace summary { - say_category IEMGUI - say bng "Bang Boks" - say tgl "Av/P Boks" - say nbx "Nummer Boks (IEM)" - say hsl "Glidebryter (Horisontal" - say vsl "Glidebryter (Vertikal)" - say hradio "Velger Boks (Horisontal)" - say vradio "Velger Boks (Vertikal)" - say cnv "Bakgrunn (IEM)" - say vu "Vumler" - say dropper "Dra-og-Slipp Boks" - - say_category LIM - say bang "send ut en bang melding" - say float "lagre og hente frem et tall" - say symbol "lagre og hente frem et symbol" - say int "lagre og hente frem et heltall" - say send "send en melding til et navngitt objekt" - say receive "ta i mot sendte meldinger" - say select "sjekk etter passende tall eller symboler" - say route "videresend meldinger i henhold til frste element" - say pack "lag sammensatte meldinger" - say unpack "hent elementer fra sammensatte meldinger" - say trigger "sekvenser og konverter meldinger" - say spigot "avbrytbar meldingsforbindelse" - say moses "bryt opp en numerisk strm" - say until "mekanisme for repetisjon" - say print "skriv ut meldinger" - say makefilename "formater et symbol med et variabelt felt" - say change "fjern repeterte tall fra en strm" - say swap "bytt om to tall" - say value "delt numerisk verdi" - - say_category TID - say delay "send en melding etter en tidsforsinkelse" - say metro "send en melding periodisk" - say line "send en serie av linert stegvise tall" - say timer "ml tidsintervaller" - say cputime "ml CPU tid" - say realtime "ml sann tid" - say pipe "dynamisk skalerbar forsinkelsesk for tall" - - say_category MATTEMATIKK - say + "legg til" - say - "trekk fra" - say * "multipliser" - say {/ div} "divider" - say {% mod} "delingsrestere" - say pow "eksponensiere" - say == "er lik?" - say != "er ikke lik?" - - - say > "strre enn?" - say < "mindre enn?" - say >= "ikke mindre enn?" - say <= "ikke strre enn?" - say & "bitvis konjunksjon (og)" - say | "bitvis atskillelse (eller)" - say && "logisk konjunksjon (og)" - say || "logisk atskillelse (eller)" - say mtof "MIDI til Hertz" - say ftom "Hertz til MIDI" - say powtodb "Watt til dB" - say dbtopow "dB til Watt" - say rmstodb "Volt til dB" - say dbtorms "dB til Volt" - say {sin cos tan atan atan2 sqrt} "trigonometri" - say log "Euler logaritme" - say exp "Euler eksponential" - say abs "absolutt verdi" - say random "tilfeldig" - say max "strste av to tall" - say min "minste av to tall" - say clip "tvinge et tall inn i et omrde" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} \ - "MIDI inndata" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} \ - "MIDI utdata" - say makenote \ - "sett inn en forsinket \"note off\" melding som korresponderer med en note-on" - say stripnote "fjern \"note off\" meldinger" - - say_category TABELLER - say tabread "les et tall fra en tabell" - say tabread4 "les et tall fra en tabell, med 4 punkts interpolasjon" - say tabwrite "skriv et tall til en tabell" - say soundfiler "les og skriv tabeller til lydfiler" - - say_category DIVERSE - say loadbang "bang ved lasting" - say serial "seriell enhetskontroll kun for NT" - say netsend "send meldinger over internettet" - say netreceive "motta dem" - say qlist "\"sequencer\" for meldinger" - say textfile "fil til melding konverterer" - say openpanel "\"pne\" dialog" - say savepanel "\"Lagre som\" dialog" - say bag "tallsett" - say poly "polyfonisk stemmeallokering" - say {key keyup} "numeriske noteverdier fra keyboard" - say keyname "symbolsk notenavn" - say_category "AUDIO MATTEMATIKK" - foreach word {+ - * /} {say $word~ "[say $word] (for signaler)"} - say max~ "supremum for signaler" - say min~ "infimum for signaler" - say clip~ "innskrenk signal til ligge mellom to grenseverdier" - say q8_rsqrt~ "billig resiprokal kvadratrot (obs -- 8 bits!)" - say q8_sqrt~ "billig kvadratrot (obs-- 8 bits!)" - say wrap~ "brett rundt (fractional part, sort of)" - say fft~ "kompleks forlengs diskr Fourier transform" - say ifft~ "kompleks invers diskr Fourier transform" - say rfft~ "sann forlengs diskr Fourier transform" - say rifft~ "sann invers diskr Fourier transform" - say framp~ "send ut en rampe for hver blokk" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signaler)" - } -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "sample rate" - say -audioindev "audio inn enheter" - say -audiooutdev "audio ut enheter" - say -inchannels "audio inndata kanaler (pr. enhet, som \"2\" el. \"16,8\")" - say -outchannels "antall audio ut kanaler (samme)" - say -audiobuf "spesifiser strrelse p audio buffer i ms" - say -blocksize "spesifiser audio I/U blokk strrelse i sample rammer" - say -sleepgrain "spesifiser antall millisekunder g i dvale nr inaktiv" - say -nodac "hindre audio utdata" - say -noadc "hindre audio inndata" - say audio_api_choice "Audio API" - say default "standard" - say -alsa "bruk ALSA audio API" - say -jack "bruk JACK audio API" - say -mmio "bruk MMIO audio API (standard for Windows)" - say -portaudio "bruk ASIO audio driver (via Portaudio)" - say -oss "bruk OSS audio API" - say -32bit "tillat 32 bit OSS audio (for RME Hammerfall)" - say {} "standard" - -say section_midi "MIDI" - say -nomidiin "hindre MIDI inndata" - say -nomidiout "hindre MIDI utdata" - say -midiindev "midi inn enhetsiste; d.v.s., \"1,3\" for frste og tredje" - say -midioutdev "midi ut enhetsliste, samme format" - -say section_externals "Eksterne" - say -path "fil skesti" - say -helppath "helpefil skesti" - say -lib "last objektbiblioteker" - -say section_gui "Gooey" - say -nogui "hindre oppstart av GUI (forsiktig)" - say -guicmd "bytt med annet GUI program (d.v.s., rsh)" - say -look "knappelinje ikoner" - say -font "spesifiser standard skriftstrrelse i punkter" - -say section_other "Annet" - say -open "pne fil(er) ved oppstart" - say -verbose "ekstra utprint ved oppstart og ved sking etter filer" - say -d "feilskingsniv" - say -noloadbang "sl av effekten av \[loadbang\]" - say -send "send en melding ved oppstart (etter patcher er lastet)" - say -listdev "vis audio og MIDI enheter ved oppstart" - say -realtime "bruk sanntids prioritet (trenger superbruker rettigheter)" - -say section_paths "Stier" - -# phase 4B: ddrc (keyword names not finalized!) -say console "konsoll rullefelt linjer (0 = sl av konsoll)" -say lang "Sprkvalg" -say pointer_sense "Musepeker sensitivitet" -say section_color "farger" - say canvas_color "lerret" - say canvasbgedit "lerretsbakgrunn (redigeringsmodus)" - say canvasbgrun "lerretsbakgrunn (kjremodus)" - say object_color "objekt" - say viewframe1 "objektboks farge" - say viewframe2 "objektboks farge" - say viewframe3 "objektboks farge" - say viewframe4 "objektboks framhevingsfarge" - say viewbg "objekt bakgrunn" - say viewfg "objekt forgrunn" - say commentbg "kommentar bakgrunn" - say commentfg "kommentar forgrunn" - say commentframe1 "kommentar ramme" - say commentframe2 "kommentar ramme" - say commentframe3 "kommentar ramme" - say viewselectframe "framhevingsboks" - say wire_color "trd" - say wirefg "trdfarge" - say wirefg2 "trd framhevingstone" - say wiredspfg "dsp trdfarge" - say futurewiredash "ny (streket) trd" - say others_color "andre" - say boxinletfg "inngangsfarge" - say boxoutletfg "utgangsfarge" - say selrectrect "markeringsboks" -say keys "taster" -say others "andre" -say hairstate "Sl p siktekryss" -say hairsnap "Siktekryss fest til objekt" -say statusbar "Sl p statuslinje" -say buttonbar "Sl p knappelinje" -say menubar "Sl p menulinje" -say scrollbar "Sl p auto rullefelt" -say wirearrow "Trd Pil" -say tooltip "VerktysTips" -say insert_object "Sett Inn objekt" -say chain_object "Kjedeobjekt" -say clear_wires "Fjern trder" -say auto_wire "Fjern objekt" -say subpatcherize "Subpatcherize" -say keynav "tastatur navigering" -say key_nav_up "flytt opp" -say key_nav_up_shift "pluss valg" -say key_nav_down "flytt ned" -say key_nav_down_shift "pluss valg" -say key_nav_right "flytt hyre" -say key_nav_right_shift "pluss valg" -say key_nav_left "flytt venstre" -say key_nav_left_shift "pluss valg" -say key_nav_ioselect "velg inn/utganger" - -#phaze 5A -say cannot "kan ikke" -say cancel "Avbryt" -say apply "Bruk" -say ok "OK" -say popup_open "pne" -say popup_properties "Egenskaper" -say popup_help "Hjelp" -say filter "Filter: " -say how_many_object_classes "%d av %d objektklasser" -say do_what_i_mean "Gjr Det Jeg Mener" -say save_changes? "Lagre endringer?" -say reset "Nullstille" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Legg til" -say up "Opp" -say down "Ned" -say remove "Fjern" -say lib_add "legg navnet du skrev til listen" -say lib_up "bytt rekkeflge med forrige bibliotek" -say lib_down "bytt rekkeflge med neste bibliotek" -say lib_remove "fjern det valgte biblioteket" -say dir_add "legg til en mappe ved bruke en filvelger" -say dir_up "bytt rekkeflge med forrige mappe" -say dir_down "bytt rekkeflge med neste mappe" -say dir_remove "fjern den valgte mappen" -say client_class_tree "Klient KlasseTre" -say clipboard_view "Utklippstavlevisning" -say history_view "Historievisning" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "bredde(px)" -say h "hyde(px)" -say hold "ventetid(ms)" -say break "pausetid(ms)" -say min "minimumsverdi" -say max "maksimumsverdi" -say is_log "modus" -say linear "liner" -say logarithmic "logaritmisk" -say isa "initiering" -say n "antall valg" -say steady "stdighet" -say steady_no "hopp ved klikk" -say steady_yes "stdig ved klikk" -say snd "send-symbol" -say rcv "motta-symbol" -say lab "merkelapp" -say ldx "merkelapp x forskyvning" -say ldy "merkelapp y forskyvning" -say fstyle "Skrift" -say fs "skriftstrrelse" -say bcol "bakgrunnsfarge" -say fcol "forgrunnsfarge" -say lcol "merkelappfarge" -say yes "ja" -say no "nei" -say courier "courier (skrivemaskin)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "graph on parent" - -say_category GAtomProperties -say width "bredde" -say lo "nedre grense" -say hi "vre grense" -say label "merkelapp" -say wherelabel "vis merkelapp p" -say symto "send symbol" -say symfrom "motta symbol" - -say_category GraphProperties -say x1 "x fra" -say x2 "x til" -say xpix "skjermbredde" -say y2 "y fra" -say y1 "y til" -say ypix "skjermhyde" - -say_category CanvasProperties -#say xscale "X enheter/px" -#say yscale "Y enheter/px" -say gop "Graph on Parent" -say xmargin "X margin" -say ymargin "Y margin" -say height "hyde" - -say_category ArrayProperties -say name "navn" -say n "strrelse" -say xfrom "x omrde fra" -say xto "x omrde til" -say yfrom "y omrde fra" -say yto "y omrde til" - -say_category MainWindow -say in "inn" -say out "ut" -say audio "Audio" -say meters "Mlere" -say io_errors "IU Feil" -say tcl_console "Tcl Klient" -say pd_console "Pd Tjener" - diff --git a/desiredata/src/locale/brasileiro.tcl b/desiredata/src/locale/brasileiro.tcl deleted file mode 100644 index cef5db8d..00000000 --- a/desiredata/src/locale/brasileiro.tcl +++ /dev/null @@ -1,577 +0,0 @@ -#!/usr/bin/env tclsh -# Portuguese translations for DesireData -# $Id: brasiliano.tcl,v 1.1.2.1 2007/10/05 23:15:45 matju Exp $ -# Author: Carlos Paulino <chgp@riseup.net> revision 0.4 - -### Menus - -say file "Arquivo" - say new_file "Novo" - say open_file "Abrir..." - say server_prefs "Config. servidor..." - say client_prefs "Config. cliente..." - say send_message "Enviar mensagem..." - say paths "Caminhos..." - say close "Fechar Janela" - say save "Salvar" - say save_as "Salvar como..." - say print "Imprimir..." - say abort_server "Terminar o servidor" - say quit "Sair" - - say canvasnew_file "Novo Arquivo" - say canvasopen_file "Abrir Arquivo..." - say canvassave "Salvar" - say canvassave_as "Salvar como..." - say clientpdrc_editor "Editor .pdrc" - say clientddrc_editor "Editor .ddrc" - say canvasclose "Fechar" - say canvasquit "Sair" - -say edit "Edição" - say undo "Desfazer" - say redo "Refazer" - say cut "Cortar" - say copy "Copiar" - say paste "Colar" - say duplicate "Duplicar" - say select_all "Selecionar tudo" - say clear_selection "Limpar seleção" - say text_editor "Editor de Texto..." - say font "Fonte" - say tidy_up "Tidy Up" - say edit_mode "Modo de edição" - say editmodeswitch "Modo de edição/execução" - say subpatcherize "Subpatcherizar :)" - - say canvascut "Cortar" - say canvascopy "Copiar" - say canvasundo "Colar" - say canvasredo "Refazer" - say canvaspaste "Colar" - say canvasduplicate "Duplicar" - say canvasselect_all "Selecionar tudo" - say canvaseditmodeswitch "Modo de edição/execução" - -say view "Visualizar" - say reload "Recarregar" - say redraw "Redesenhar" - - say canvasreload "Recarregar" - say canvasredraw "Redesenhar" -say visual_diff "visual diff??" -say get_elapsed "get elapsed??" - -say find "Procurar" - say find_again "Procura novamente" - say find_last_error "Encontrar o último erro" - say string "Procurar por sequência de caracteres" -say canvasfind "Buscar" - say canvasfind_again "Busca novamente" - -# contents of Put menu is Phase 5C -say put "Inserir" - say Object "Objeto" - say Message "Mensagem" - say Number "Número" - say Symbol "Símbolo" - say Comment "Comentário" - say Graph "Gráfico" - say Array "Tabela" - -say media "Mídia" - say audio_on "Ligar Áudio" - say audio_off "Desligar Áudio" - say test_audio_and_midi "Testar áudio e MIDI" - say load_meter "Carregar Meter" - - say canvasaudio_on "Áudio Ligado" - say canvasaudio_off "Áudio Desligado" - say clienttest_audio_and_midi "Testar áudio e MIDI" - say canvasload_meter "Carregar Meter" - -say window "Janelas" - -say help "Ajuda" - say about "Sobre..." - say documentation "Documentação..." - say class_browser "Navegador..." - - say canvasabout "Sobre..." - -say properties "Propriedades" -say open "Abrir" - -### for key binding editor -say general "Geral" -say audio_settings "Configurações de Áudio" -say midi_settings "Configurações Midi" -say latency_meter "Medidor de latência" -say Pdwindow "Janela do Pd" - -say canvaspdwindow "Janela do Pd" -say canvaslatency_meter "Medidor de latência" -say clientaudio_settings "Configurações de áudio" -say clientmidi_settings "Configurações Midi" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "largura(px)" -say h "altura(px)" -say hold "tempo de espera(ms)" -say break "tempo de quebra(ms)" -say min "valor mínimo" -say max "valor máximo" -say is_log "mode? (is_log)" -say linear "linear" -say logarithmic "logarítimico" -say isa "início" -say n "número de alternativas" -say steady "steadiness?" -say steady_no "pula no clique" -say steady_yes "steady? no clique" -say snd "envia-símbolo" -say rcv "recebe-símbolo" -say lab "etiqueta" -say ldx "offset etiqueta x" -say ldy "offset etiqueta y" -say fstyle "Fonte tipo" -say fs "tamanho da fonte" -say bcol "cor de fundo" -say fcol "cor da frente" -say lcol "cor da etiqueta" -say yes "sim" -say no "não" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "gráfico no pai" - -say_category GAtomProperties -say width "largura" -say lo "limite inferior" -say hi "limite superior" -say label "etiqueta" -say wherelabel "exibe etiqueta" -say symto "envia símbolo" -say symfrom "recebe símbolo" - -say_category GraphProperties -say x1 "de x" -say x2 "para x" -say xpix "largura da tela" -say y2 "de y" -say y1 "para y" -say ypix "altura da tela" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "gráfico no pai" -say xmargin "margem x" -say ymargin "margem y" -say height "altura" -say_category ArrayProperties -say name "nome" -say n "tamanho" -say xfrom "escala x de?" -say xto "escala x até" -say yfrom "escala y de" -say yto "escala y até" - - -say_category MainWindow -say in "entrada" -say out "saída" -say audio "Áudio" -say meters "Medidores" -say io_errors "Erros E/S" -say tcl_console "Cliente Tcl" -say pd_console "Servidor Pd" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang" - say tgl "Interruptor (Toggle)" - say nbx "Caixa numérica (IEM)" - say hsl "Slider (Horizontal)" - say vsl "Slider (Vertical)" - say hradio "Caixa de seleção (horizontal)" - say vradio "Caixa de seleção (Vertical)" - say cnv "Canvas (IEM)" - say dropper "Caixa arrasta-e-solta" - say vu "Medidor VU" - - say_category GLUE - say bang "envia uma mensagem bang" - say float "armazena e acessa um número" - say symbol "armazena e acessa um símbolo" - say int "armazena e acessa um inteiro" - say send "armazena uma mensagem para um objeto rotulado" - say receive "rebe mensagens enviadas" - say select "testar por números ou símbolos coincidentes" - say route "refaz a rota das mensagens de acordo com o primeiro elemento" - say pack "\"empacotador\" de mensagens" - say unpack "\"desempacota\" mensagens compostas" - say trigger "sequencia e converte mensagens" - say spigot "interruptor de fluxo de mensagens" - say moses "part a numeric stream" - say until "mecanismo de loop" - say print "exibe mensagens" - say makefilename "formata um símbolo com um campo variável??" - say change "remover números repetidos de uma sequência" - say swap "troca dois números" - say value "compartilha valor numérico" - - say_category TIME - say delay "envia uma mensagem após um intervalo de tempo" - say metro "Metrônomo - envia mensagens periodicamente" - say line "envia mensagem com números lineares" - say timer "mede intervalos de tempo" - say cputime "mede tempo de processamento" - say realtime "mede tempo real" - say pipe "linha de intervalo de tempo númerico que cresce dinamicamente" - - say_category MATH - say + "adiciona" - say - "subtrai" - say * "multiplica" - say {/ div} "divisão" - say {% mod} "resto da divisão" - say pow "potência" - say == "igua a?" - say != "diferente de?" - say > "maior que?" - say < "menor que?" - say >= "menor ou igual a?" - say <= "maior ou igual a?" - say & "conjunção bitwise (e)" - say | "disjunção bitwise (ou)" - say && "conjunção lógica (e)" - say || "disjunção lógica (ou)" - say mtof "MIDI para Hertz" - say ftom "Hertz para MIDI" - say powtodb "Watts para dB" - say dbtopow "dB para Watts" - say rmstodb "Volts para dB" - say dbtorms "dB para Volts" - say {sin cos tan atan atan2 sqrt} "trigonometria" - say log "Logarítimo Euler" - say exp "Exponenciação Euler" - say abs "valor absoluto" - say random "randômico" - say max "máximo de dois números" - say min "mínimo de dois números" - say clip "forçar um número numa faixa" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "entrada MIDI" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "saída MIDI" - say makenote "agenda uma mensagem \"note off\" correspondente a uma note-on" - say stripnote "separa mensagens \"note off\" " - - say_category TABLES - say tabread "le um número de uma tabela" - say tabread4 "lê um número de uma tabela com 4 pontos de interpolação" - say tabwrite "escreve um número numa tabela" - say soundfiler "lê e escreve tabelas em arquivos de som" - - say_category MISC - say loadbang "bang quando carregar patch" - say serial "controle de dispositivo para MS NT" - say netsend "envia mensagens através da internet" - say netreceive "recebe as mensagens através da internet" - say qlist "sequenciador de mensagens" - say textfile "conversor de arquivo para mensagens" - say openpanel "Diálogo \"Abrir\"" - say savepanel "Diálogo \"Salvar como\" " - say bag "conjunto de números" - say poly "alocação de voz polifônica" - say {key keyup} "valor numéricos de teclas de teclado alfanumérico" - say keyname "nome simbólico da chave?" - - say_category "Matemática com Áudio" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "supremacia dos sinais" - say min~ "infinidade dos sinais" - say clip~ "constrict signal to lie between two bounds" - say q8_rsqrt~ "raiz quadrada reciproca barata (cuidado -- 8 bits!)" - say q8_sqrt~ "raiz quadrada barata (cuidado -- 8 bits!)" - say wrap~ "wraparound (tipo de parte fracionária)" - say fft~ "transformação discreta Fourier complex forward" - say ifft~ "transformação discreta Fourier complex inverse" - say rfft~ "transformação discreta Fourier real forward " - say rifft~ "transformação discreta Fourier real inverse " - say framp~ "dá saída numa rampa para cada bloco" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (para sinais)" - } -} - -### phase 3 - -say_namespace summary { - say_category "Cola de Áudio" - say dac~ "saída de áudio" - say adc~ "entrada de áudio" - say sig~ "converte números para sinais de áudio" - say line~ "gera rampas de áudio" - say vline~ "line~ de luxo" - say threshold~ "detecta sinal thresholds" - say snapshot~ "sample a signal (convert it back to a number)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "send a bang message after each DSP block" - say samplerate~ "get the sample rate" - say send~ "nonlocal signal connection with fanout" - say receive~ "obtêm sinal do send~" - say throw~ "adiciona a um summing bus" - say catch~ "definir e ler um summing bus??" - say block~ "especificar tamanho do bloco e overlap" - say switch~ "liga e desliga computação DSP" - say readsf~ "le de arquivos de som no disco" - say writesf~ "grava arquivos de som no disco" - - say_category "Osciladores de áudio e tabelas" - say phasor~ "oscilador dente de serra (sawtooth)" - say {cos~ osc~} "oscilador coseno" - say tabwrite~ "escrever em tabela" - say tabplay~ "tocar de uma tabela (sem transpor)" - say tabread~ "leitura de tabela não interpolada" - say tabread4~ "leitura de tabela com 4 ponto de interpolação" - say tabosc4~ "oscilador com tabela de ondas (wavetable)" - say tabsend~ "escreve um bloco continuamente em uma tabela" - say tabreceive~ "le um bloco continuamente de uma tabela" - - say_category "Filtros de áudio" - say vcf~ "filtro controlador de voltagem" - say noise~ "gerador de ruido branco" - say env~ "envelope follower" - say hip~ "filtro passo alto" - say lop~ "filtro passo baixo" - say bp~ "filtro passo banda" - say biquad~ "filtro raw" - say samphold~ "unidade sample and hold" - say print~ "exibe um ou mais \"blocose \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (tempo-revertido)" - say cpole~ "[say rpole~] (valor complexo)" - say czero~ "[say rzero~] (valor complexo)" - say czero_rev~ "[say rzero_rev~] (valor complexo)" - - say_category "AUDIO DELAY" - say delwrite~ "escreve para uma linha de atraso(delay)" - say delread~ "ler de uma linha de atraso(delay)" - say vd~ "ler de uma linha de atraso num read from a delay line at a variable delay time" - - say_category "Subjanelas" - say pd "define uma subjanela" - say table "array de números em uma subjanela" - say inlet "add an inlet to a pd" - say outlet "add an outlet to a pd" - say inlet~ "[say inlet] (for signal)" - say outlet~ "[say outlet] (for signal)" - - say_category "Modelos de DADOS (templates)" - say struct "define uma estrutura de dados" - say {drawcurve filledcurve} "desenha uma curva" - say {drawpolygon filledpolygon} "desenha um polígono" - say plot "plotar um campo array" - say drawnumber "imprime um valor numérico" - - say_category "Acessando DADOS" - say pointer "aponta para um objeto pertencente a um modelo" - say get "obtêm campos numéricos" - say set "altera campos numéricos" - say element "obtêm um elemento array" - say getsize "obtêm o tamanho do array" - say setsize "altera o tamanho de um array" - say append "adiciona um elemento a uma lista" - say sublist "obtêm um ponteiro em uma lista que é um elemento para uma outra escalar??" - say scalar "desenha uma escalar no pai" - - say_category "OBSOLETE" - say scope~ "(usar tabwrite~ agora)" - say namecanvas "" ;# what was this anyway? - say template "(usar struct agora)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Áudio" - say -r "Frequência da amostra" - say -audioindev "dispositivos de entrada" - say -audiooutdev "dispositivos de saída" - say -inchannels "número de canais de entrada (por dispositivo, tipo \"2\" ou \"16,8\")" - say -outchannels "número de canais de saída (o mesmo)" - say -audiobuf "especificar tamanho do buffer de áudio em mseg." - say -blocksize "espcificar tamanho do bloco de E/S em quadros de amostras" - say -sleepgrain "especificar número para dormir quando inativa em milisegundos" - say -nodac "não processa áudio" - say -noadc "não processa(supress?) áudio" - say audio_api_choice "API de áudio" - say default "padrão" - say -alsa "usar API ALSA de áudio" - say -jack "usar API JACK de áudio" - say -mmio "usar API MMIO de áudio (padrão para windows)" - say -portaudio "usar driver de áudio ASIO (via Portaudio)" - say -oss "usar API OSS de áudio" - say -32bit "permitir acesso 32 bits a áudio OSS (para RME Hammerfall)" - say {} "padrão" - -say section_midi "MIDI" - say -nomidiin "não processa entrada MIDI" - say -nomidiout "não processa saída MIDI" - say -midiindev "dispositivos de entrada MIDI; ex, \"1,3\" para primeiro e terceiro" -say -midioutdev "dispositivos de saída MIDI; lista de dispositivos de saída midi, mesmo formato" - -say section_externals "Externos" - say -path "caminho de procura por arquivos" - say -helppath "caminho de procura por arquivos de ajuda" - say -lib "carrega bibliotecas de objetos" - -say section_gui "Interface" - say -nogui "desabilita o início da interface gráfica (cuidado)" - say -guicmd "substitui outro programa de interface (ex., rsh)" - say -look "ícones da barra de butões" - say -font "especificar o padrão do tamanho da fonte em pontos" - -say section_other "Outros" - say -open "abrir arquivo(s) no início" - say -verbose "exibir mais detalhes no início e quando pesquisar por arquivos" - say -d "grau de depuração" - say -noloadbang "desabilita o efeito de \[loadbang\]" - say -send "envia uma mensagem no início (depois dos patches carregados)" - say -listdev "listar dispositivos de áudio e MIDI carga do logicial" - say -realtime "usar prioridade de tempo-real (necessita conta com privilégio especial ou root)" - -say section_paths "Caminhos" - -# phase 4B: ddrc (keyword names not finalized!) -say console "linhas de rolamento da console (1 = desabilita console)" -say lang "Linguagem" -say pointer_sense "Sensibilidade do ponteiro do mouse" -say section_color "Aparencia" - say canvas_color "canvas" - say canvasbgedit "fundo do canvas (modo edição)" - say canvasbgrun "canvas background (modo execução)" - say object_color "objeto" - say viewframe1 "cor da caixa de objeto" - say viewframe2 "cor da caixa de objeto" - say viewframe3 "cor da caixa de objeto" - say viewframe4 "cor de destaque da caixa de objeto" - say viewbg "fundo do objeto" - say viewfg "frente do objeto" - say commentbg "fundo do comentário" - say commentfg "frente do comentário" - say commentframe1 "quadro de comentário" - say commentframe2 "quadro de comentário" - say commentframe3 "quadro de comentário" - say viewselectframe "hilight box" - say wire_color "fio" - say wirefg "cor do fio" - say wirefg2 "destaque do fio" - say wiredspfg "cor do fio de áudio" - say futurewiredash "novo fio (esmagado?)" - say others_color "outras" - say boxinletfg "cor das entradas" - say boxoutletfg "cor das saídas" - say selrectrect "caixa de seleção" -say keys "chaves" -say others "outras" -say hairstate "Ativa crosshair" -say hairsnap "Crosshair gruda no objeto" -say statusbar "Ativa barra de estado" -say buttonbar "Ativa barra de butões" -say menubar "Ativa barra de menus" -say scrollbar "Ativa barra de rolagem automática" -say wirearrow "Cabo com seta" -say tooltip "Dica" -say insert_object "Inserir objeto" -say chain_object "Objeto corrente (Chain)" -say clear_wires "Limpar cabos" -say auto_wire "Remove objeto" -say subpatcherize "Subpatcherizar :)" -say keynav "navegação do teclado" -say key_nav_up "move para cima" -say key_nav_up_shift "selecione mais" -say key_nav_down "mover para baixo" -say key_nav_down_shift "selecione mais" -say key_nav_right "move right" -say key_nav_right_shift "selecione mais" -say key_nav_left "mover para esquerda" -say key_nav_left_shift "selecione mais" -say key_nav_ioselect "seleciona entradas/saídas" -# phase 5A - -say cannot "não consigo" -say cancel "Cancelar" -say apply "Aplicar" -say ok "OK" -say popup_open "Abrir" -say popup_insert "Inserir" -say popup_properties "Propriedades" -say popup_clear_wires "Limpar conexões" -say popup_remove_from_path "Remove objeto do caminho" -say popup_delete_from_path "Apaga objeto do caminho" -say popup_copy_id "copia identificação" -say popup_help "Ajuda" -say filter "Filtro: " -say how_many_object_classes "%d de %d classes de objeto" -say do_what_i_mean "Realize o que eu imagino!" -say ask_cool "Este recurso quando estiver implementado vai ficar muito, foda." -say save_changes? "Salvar as bobagens que você fez?" -say reset "Reiniciar" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Adiciona" -say up "Acima" -say down "Abaixo" -say remove "Remove" -say lib_add "adiciona o nome que você digitou na lista" -say lib_up "altera ordem com biblioteca anterior" -say lib_down "altera ordem com próxima biblioteca" -say lib_remove "remove biblioteca selecionada na lista" -say dir_add "adiciona um campo usando um diálogo de arquivo" -say dir_up "troca ordem com campo anterior" -say dir_down "troca ordem com próximo campo" -say dir_remove "remove pasta selecionada na lista" -say client_class_tree "Árvore de Classes pro freguês" -say clipboard_view "Visão Clipboard" -say command_history_view "Visão do histórico de comandos" -say event_history_view "Ver histórico de eventos" - -# during/after piksel: - -say auto_apply "Auto-Aplicar" -say font_preview "Prévia:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Estilo:" -say font_bold "Negrito" -say font_italic "Itálico" -say font_family "Nome:" -say font_size "Tamanho:" -say damn "Maldito!" -say console_clear "Limpar Console" -say horizontal "Horizontal" -say vertical "Vertical" -say language "Língua" - -# 2007: - -say no_matches "o padrão especificado não foi encontrado" -say preset "modelo??" -say canvasgrid "Cor da Grade" -say grid_size "Tamanho da grade" -say gridstate "Ativar grade de fundo" -say snap_grid "Grudar na grade" -say viewfont "fonte do objeto" -say consolefont "fonte do console" -say keyboarddialogfont "fonte do teclado virtual" -say keyboard_view "Teclado Virtual" -say log_height "Tamanho do Histórico" - diff --git a/desiredata/src/locale/catala.tcl b/desiredata/src/locale/catala.tcl deleted file mode 100644 index 8f244256..00000000 --- a/desiredata/src/locale/catala.tcl +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env tclsh -# Catalan (catal) translations for PureData -# $Id: catala.tcl,v 1.1.2.5 2006-10-13 16:00:56 matju Exp $ -# by Nria Verges - -say file "Fitxer" - say new_file "Nou Fitxer" - say open_file "Obrir Fitxer..." - say pdrc_editor "Editor de .pdrc" - say send_message "Enviar Missatge..." - say paths "Camins..." - say close "Tancar" - say save "Desar" - say save_as "Guardar com a..." - say print "Imprimir..." - say quit "Sortir" - -say edit "Editar" - say undo "Desfer" - say redo "Refer" - say cut "Tallar" - say copy "Copiar" - say paste "Enganxar" - say duplicate "Duplicar" - say select_all "Seleccionar-ho tot" - say text_editor "Editor de text..." - say tidy_up "Netejar" - say edit_mode "Mode d'edici" - -say view "Veure" - say reload "Recarregar" - say redraw "Redissenyar" - -say find "Trobar" - say find_again "Trobar novament" - say find_last_error "Trobar l'ltima errada" - -say put "Posar" - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - -say window "Finestra" - -say help "Ajuda" - say about "Sobre..." - say pure_documentation "Pure Documentaci..." - say class_browser "Cercador de Classes..." - -### Main Window - -say in "in" -say out "out" -say audio "Audio" -say meters "Meters" -say io_errors "Errades d'E/S" - diff --git a/desiredata/src/locale/chinese.tcl b/desiredata/src/locale/chinese.tcl deleted file mode 100644 index bdbd0a37..00000000 --- a/desiredata/src/locale/chinese.tcl +++ /dev/null @@ -1,560 +0,0 @@ -#!/usr/bin/env tclsh -# English translations for PureData -# $Id: chinese.tcl,v 1.1.2.3 2007-08-09 02:09:07 chunlee Exp $ - -### Menus - -say file "案檔" - say new_file "新案檔" - say open_file "開啟舊檔..." - say server_prefs "伺服器設定..." - say client_prefs "客戶端設定..." - say send_message "傳送旨令..." - say paths "Paths..." - say close "關閉" - say save "存檔" - say save_as "另存新檔..." - say print "印出..." - say quit "結束" - - say canvasnew_file "開啟新檔" - say canvasopen_file "開啟舊檔..." - say canvassave "存檔" - say canvassave_as "另存新檔..." - say clientpdrc_editor "遠端設定" - say clientddrc_editor "終端設定" - say canvasclose "關閉" - say canvasquit "結束" - -say edit "編輯" - say undo "回上一步" - say redo "回下一步" - say cut "剪下" - say copy "拷貝" - say paste "後貼" - say duplicate "復製" - say select_all "全選" - say text_editor "Text Editor..." - say font "字體" - say tidy_up "自動排列" - say edit_mode "編輯模式" - say editmodeswitch "編輯/執行 模式" - - say canvascut "剪下" - say canvascopy "拷貝" - say canvasundo "回上一步" - say canvasredo "回下一步" - say canvaspaste "後貼" - say canvasduplicate "復製" - say canvasselect_all "全選" - say canvaseditmodeswitch "編輯/執行 模式" - -say view "顯示" - say reload "重新下載" - say redraw "重新畫製" - - say canvasreload "重新下載" - say canvasredraw "重新畫製" - -say find "尋找" - say find_again "再次尋找" - say find_last_error "尋找上一錯誤" - say string "Find string" -say canvasfind "尋找" - say canvasfind_again "再次尋找" - -# contents of Put menu is Phase 5C -say put "放置" - say Object "物件" - say Message "信息" - say Number "數字" - say Symbol "符號" - say Comment "註譯" - say Graph "圖" - say Array "陣列" - -say media "Media" - say audio_on "聲頻開啟" - say audio_off "聲頻關閉" - say test_audio_and_midi "測試聲頻及MIDI" - say load_meter "負載錶" - - say canvasaudio_on "聲頻開啟" - say canvasaudio_off "聲頻關閉" - say clienttest_audio_and_midi "測試聲頻及MIDI" - say canvasload_meter "負載錶" - -say window "視窗" - -say help "幫助" - say about "相關..." - say documentation "使用說明..." - say class_browser "物件瀏覽器..." - - say canvasabout "相關..." - -say properties "內容" -say open "開啟" - -### for key binding editor -say general "一般" -say audio_settings "聲頻設定" -say midi_settings "Midi設定" -say latency_meter "時延錶" -say Pdwindow "Pd主視窗" - -say canvaspdwindow "Pd主視窗" -say canvaslatency_meter "時延錶" -say clientaudio_settings "聲頻設定" -say clientmidi_settings "Midi設定" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "寬(像素)" -say h "高(像素)" -say hold "有效顯示時限(毫秒)" -say break "有效空閒時限(毫秒)" -say min "最低數限" -say max "最高數限" -say is_log "模式" -say linear "線性" -say logarithmic "對數" -say isa "起始" -say n "選擇數量" -say steady "穩定性" -say steady_no "點選跳躍式" -say steady_yes "點選持續式" -say snd "傳送符號" -say rcv "接收符號" -say lab "標簽" -say ldx "標簽橫落差" -say ldy "標簽縱落差" -say fstyle "字形" -say fs "字體大小" -say bcol "背景研色" -say fcol "前景研色" -say lcol "標簽研色" -say yes "是" -say no "否" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "頂端顯示" - -say_category GAtomProperties -say width "寬" -say lo "最低數限" -say hi "最高數限" -say label "標簽" -say wherelabel "標簽位置" -say symto "傳送符號" -say symfrom "接收符號" -say pos "標簽位置" -say_category GraphProperties -say x1 "x from" -say x2 "x to" -say xpix "screen width" -say y2 "y from" -say y1 "y to" -say ypix "screen height" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "頂端顯示" -say xmargin "橫軸邊緣限度" -say ymargin "縱軸邊緣限度" -say height "高" -say_category ArrayProperties -say name "名子" -say n "大小" -say xfrom "橫軸範圍啟" -say xto "橫軸範圍使" -say yfrom "縱軸範圍啟" -say yto "縱軸範圍使" - - -say_category MainWindow -say in "進" -say out "出" -say audio "聲音" -say meters "聲頻錶" -say io_errors "聲頻錯誤" -say console_clear "清空顯示" -say tcl_console "TCL 旨令" -say pd_console "Pd 旨令" -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box" - say tgl "Toggle Box" - say nbx "Number Box (IEM)" - say hsl "Slider (Horizontal)" - say vsl "Slider (Vertical)" - say hradio "Choice Box (Horizontal)" - say vradio "Choice Box (Vertical)" - say cnv "Canvas (IEM)" - say dropper "Drag-and-Drop Box" - say vu "Vumeter" - - say_category GLUE - say bang "output a bang message" - say float "store and recall a number" - say symbol "store and recall a symbol" - say int "store and recall an integer" - say send "send a message to a named object" - say receive "catch sent messages" - say select "test for matching numbers or symbols" - say route "route messages according to first element" - say pack "make compound messages" - say unpack "get elements of compound messages" - say trigger "sequence and convert messagess" - say spigot "interruptible message connection" - say moses "part a numeric stream" - say until "looping mechanism" - say print "print out messages" - say makefilename "format a symbol with a variable field" - say change "remove repeated numbers from a stream" - say swap "swap two numbers" - say value "shared numeric value" - - say_category TIME - say delay "send a message after a time delay" - say metro "send a message periodically" - say line "send a series of linearly stepped numbers" - say timer "measure time intervals" - say cputime "measure CPU time" - say realtime "measure real time" - say pipe "dynamically growable delay line for numbers" - - say_category MATH - say + "add" - say - "substract" - say * "multiply" - say {/ div} "divide" - say {% mod} "division remainder" - say pow "exponentiate" - say == "equal?" - say != "not equal?" - say > "more than?" - say < "less than?" - say >= "not less than?" - say <= "not more than?" - say & "bitwise conjunction (and)" - say | "bitwise disjunction (or)" - say && "logical conjunction (and)" - say || "logical disjunction (or)" - say mtof "MIDI to Hertz" - say ftom "Hertz to MIDI" - say powtodb "Watts to dB" - say dbtopow "dB to Watts" - say rmstodb "Volts to dB" - say dbtorms "dB to Volts" - say {sin cos tan atan atan2 sqrt} "trigonometry" - say log "Euler logarithm" - say exp "Euler exponential" - say abs "absolute value" - say random "random" - say max "greater of two numbers" - say min "lesser of two numbers" - say clip "force a number into a range" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI input" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI output" - say makenote "schedule a delayed \"note off\" message corresponding to a note-on" - say stripnote "strip \"note off\" messages" - - say_category TABLES - say tabread "read a number from a table" - say tabread4 "read a number from a table, with 4 point interpolation" - say tabwrite "write a number to a table" - say soundfiler "read and write tables to soundfiles" - - say_category MISC - say loadbang "bang on load" - say serial "serial device control for NT only" - say netsend "send messages over the internet" - say netreceive "receive them" - say qlist "message sequencer" - say textfile "file to message converter" - say openpanel "\"Open\" dialog" - say savepanel "\"Save as\" dialog" - say bag "set of numbers" - say poly "polyphonic voice allocation" - say {key keyup} "numeric key values from keyboard" - say keyname "symbolic key name" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "supremum of signals" - say min~ "infimum of signals" - say clip~ "constrict signal to lie between two bounds" - say q8_rsqrt~ "cheap reciprocal square root (beware -- 8 bits!)" - say q8_sqrt~ "cheap square root (beware -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "real inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio output" - say adc~ "audio input" - say sig~ "convert numbers to audio signals" - say line~ "generate audio ramps" - say vline~ "deluxe line~" - say threshold~ "detect signal thresholds" - say snapshot~ "sample a signal (convert it back to a number)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "send a bang message after each DSP block" - say samplerate~ "get the sample rate" - say send~ "nonlocal signal connection with fanout" - say receive~ "get signal from send~" - say throw~ "add to a summing bus" - say catch~ "define and read a summing bus" - say block~ "specify block size and overlap" - say switch~ "switch DSP computation on and off" - say readsf~ "soundfile playback from disk" - say writesf~ "record sound to disk" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "sawtooth oscillator" - say {cos~ osc~} "cosine oscillator" - say tabwrite~ "write to a table" - say tabplay~ "play back from a table (non-transposing)" - say tabread~ "non-interpolating table read" - say tabread4~ "four-point interpolating table read" - say tabosc4~ "wavetable oscillator" - say tabsend~ "write one block continuously to a table" - say tabreceive~ "read one block continuously from a table" - - say_category "AUDIO FILTERS" - say vcf~ "voltage controlled filter" - say noise~ "white noise generator" - say env~ "envelope follower" - say hip~ "high pass filter" - say lop~ "low pass filter" - say bp~ "band pass filter" - say biquad~ "raw filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO DELAY" - say delwrite~ "write to a delay line" - say delread~ "read from a delay line" - say vd~ "read from a delay line at a variable delay time" - - say_category "SUBWINDOWS" - say pd "define a subwindow" - say table "array of numbers in a subwindow" - say inlet "add an inlet to a pd" - say outlet "add an outlet to a pd" - say inlet~ "[say inlet] (for signal)" - say outlet~ "[say outlet] (for signal)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "draw a curve" - say {drawpolygon filledpolygon} "draw a polygon" - say plot "plot an array field" - say drawnumber "print a numeric value" - - say_category "ACCESSING DATA" - say pointer "point to an object belonging to a template" - say get "get numeric fields" - say set "change numeric fields" - say element "get an array element" - say getsize "get the size of an array" - say setsize "change the size of an array" - say append "add an element to a list" - say sublist "get a pointer into a list which is an element of another scalar" - say scalar "draw a scalar on parent" - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ now)" - say namecanvas "" ;# what was this anyway? - say template "(use struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "聲頻" - say -r "取樣率" - say -audioindev "輸入裝置" - say -audiooutdev "輸出裝置" - say -inchannels "輸入音軌" - say -outchannels "輸出音軌" - say -audiobuf "聲頻緩衝器大小(毫秒)" - say -blocksize "聲頻輸出/入區塊大小(樣框數目)" - say -sleepgrain "空閒至睡眠時間(毫秒)" - say -nodac "停用聲頻輸出" - say -noadc "停用聲頻輸入" - say audio_api_choice "聲頻介面" - say default "內定值" - say -alsa "使用ALSA" - say -jack "使用JACK" - say -mmio "使用MMIO(Windows內定值)" - say -portaudio "使用ASIO(透過Portaudio)" - say -oss "使用OSS" - say -32bit "允許32位元OSS(for RME Hammerfall)" - say {} "內定值" - -say section_midi "MIDI" - say -nomidiin "停用MIDI輸入" - say -nomidiout "停用MIDI輸出" - say -midiindev "Midi輸入裝置名單" - say -midioutdev "Midi輸出裝置名單" - -say section_externals "外加功能" - say -path "尋找路徑" - say -helppath "說明文件路徑" - say -lib "加載功能組" - -say section_gui "使用者介面" - say -nogui "suppress starting the GUI (caution)" - say -guicmd "substitute another GUI program (e.g., rsh)" - say -console "console scrollback lines (0 = disable console)" - say -look "buttonbar icons" - say -statusbar "enable statusbar" - say -font "specify default font size in points" - -say section_other "其它" - say -open "自動開啟檔案" - say -verbose "詳係回報" - say -d "除錯階級" - say -noloadbang "停用 \[loadbang\]" - say -send "啟動後傳送旨令" - say -listdev "程式開啟時列出聲頻及MIDI裝置名單" - say -realtime "使用即時配給 (須要根權)" - -say section_paths "路徑" - -# phase 4B: ddrc (keyword names not finalized!) - -say section_color "色彩" - say canvas_color "畫布" - say canvasbgedit "畫布背景 (編輯模式)" - say canvasbgrun "畫布背景 (執行模式)" - say object_color "物件" - say viewframe1 "物件外框" - say viewframe2 "物件外框" - say viewframe3 "物件外框" - say viewframe4 "物件反白" - say viewbg "物件背景" - say viewfg "物件前景" - say commentbg "註譯背景" - say commentfg "註譯前景" - say commentframe1 "註譯外框" - say commentframe2 "註譯背景" - say commentframe3 "註譯背景" - say viewselectframe "物件反白外框" - say wire_color "通路" - say wirefg "通路研色" - say wirefg2 "通路反白" - say wiredspfg "聲頻通路" - say futurewiredash "未接通路" - say others_color "其它" - say boxinletfg "輸入點研色" - say boxoutletfg "輸出點研色" - say selrectrect "多選框" -say keys "快速鍵" -say others "其它" -say hairstate "顯示十字器" -say hairsnap "十字器停留物件左上角" -say statusbar "顯示目前狀態" -say buttonbar "顯示按鈕排" -say menubar "顯示清單" -say scrollbar "自動拉霸顯示" -say wirearrow "通路箭頭" -say tooltip "提示" -say insert_object "嵌入物件" -say chain_object "自動連結新物件" -say clear_wires "清除通路" -say auto_wire "移除物件" -say subpatcherize "自動封裝" -say keynav "鍵盤導覽" -say key_nav_up "上移" -say key_nav_up_shift "加入選區" -say key_nav_down "下移" -say key_nav_down_shift "加入選區" -say key_nav_right "右移" -say key_nav_right_shift "加入選區" -say key_nav_left "左移" -say key_nav_left_shift "加入選區" -say key_nav_ioselect "選擇輸出/入點" - -# phase 5A - -say cannot "不能" -say cancel "取消" -say apply "使用" -say ok "好" -say popup_open "打開" -say popup_insert "嵌入物件" -say popup_properties "內容" -say popup_clear_wires "清除通路" -say popup_auto_wire "移除物件" -say popup_help "輔助" -say filter "過濾: " -say how_many_object_classes "%d of %d object classes" -say do_what_i_mean "照我意思做" -say save_changes? "確定存檔?" -say reset "重新設定" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "加入" -say up "上移" -say down "下移" -say remove "移除" -say lib_add "add the name you typed to the list" -say lib_up "swap order with previous library" -say lib_down "swap order with next library" -say lib_remove "remove library selected in the list" -say dir_add "add a folder using a file dialog" -say dir_up "swap order with previous folder" -say dir_down "swap order with next folder" -say dir_remove "remove folder selected in the list" -say client_class_tree "客戶端類別樹" -say clipboard_view "閱覽筆記板" -say command_history_view "閱覽旨令歷史記錄" -say event_history_view "閱覽事件歷史記錄" -say keyboard_view "顯示鍵盤" -say abort_server "強迫中止伺服器" -# during/after piksel: - -say auto_apply "自動更新" -say font_preview "預覽:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "形態:" -say font_bold "粗體" -say font_italic "斜體" -say font_family "字體名:" -say font_size "大小:" -say damn "可惡!" -say preset "預設" -say console "儲存旨令行數" -say language "語言" -say pointer_sense "滑鼠游標敏感度" -say clear_selection "全部反選" -say popup_remove_from_path "移除通路中物件" -say popup_delete_from_path "刪除通路中物件" -say popup_copy_id "考背愛低" - diff --git a/desiredata/src/locale/dansk.tcl b/desiredata/src/locale/dansk.tcl deleted file mode 100644 index 4c789f15..00000000 --- a/desiredata/src/locale/dansk.tcl +++ /dev/null @@ -1,564 +0,0 @@ -#!/usr/bin/env tclsh -# $Id: dansk.tcl,v 1.1.2.2 2007-08-18 18:01:10 matju Exp $ -# Danish translations for PureData -# by Steffen Leve Poulsen - -### Menus - -say file "Fil" - say new_file "Ny fil" - say open_file "bn fil..." - say server_prefs "Server Preferenser..." - say client_prefs "Klient Preferenser..." - say send_message "Send besked..." - say paths "Stier..." - say close "Luk" - say save "Gem" - say save_as "Gem som..." - say print "Udskriv..." - say abort_server "Stop server" - say quit "Afslut" - - say canvasnew_file "Ny Fil" - say canvasopen_file "bn Fil..." - say canvassave "Gem" - say canvassave_as "Gem som..." - say clientpdrc_editor ".pdrc reidgering" - say clientddrc_editor ".ddrc redigering" - say canvasclose "Luk" - say canvasquit "Afslut" - -say edit "Rediger" - say undo "Fortryd" - say redo "Genskab" - say cut "Klip" - say copy "Kopier" - say paste "St ind" - say duplicate "Dubler" - say select_all "Vlg alt" - say clear_selection "Afvlg" - say text_editor "Tekstredigering..." - say font "Font" - say tidy_up "Ordn" - say edit_mode "Rediger" - say editmodeswitch "Rediger/Kr tilstand" - say subpatcherize "Gr til underlap" - - say canvascut "Klip" - say canvascopy "Kopier" - say canvasundo "Fortryd" - say canvasredo "Genskab" - say canvaspaste "St ind" - say canvasduplicate "Dubler" - say canvasselect_all "Vlg alt" - say canvaseditmodeswitch "Rediger/Kr tilstand" - -say view "Se" - say reload "bn igen" - say redraw "Gentegn" - - say canvasreload "bn igen" - say canvasredraw "Gentegn" - -say find "Sg" - say find_again "Sg igen" - say find_last_error "Find sidste fejl" - say string "Find streng" -say canvasfind "Sg" - say canvasfind_again "Sg igen" - -# contents of Put menu is Phase 5C -say put "Indst" - say Object "Objekt" - say Message "Besked" - say Number "Tal" - say Symbol "Symbol" - say Comment "Kommentar" - say Graph "Graf" - say Array "Tabel" - -say media "Medier" - say audio_on "Start lyd" - say audio_off "Stop lyd" - say test_audio_and_midi "Test lyd og MIDI" - say load_meter "Belastning" - - say canvasaudio_on "Start lyd" - say canvasaudio_off "Stop lyd" - say clienttest_audio_and_midi "Test lyd og MIDI" - say canvasload_meter "Belastning" - -say window "Vindue" - -say help "Hjlp" - say about "Om..." - say documentation "Dokumentation..." - say class_browser "Se klasser..." - - say canvasabout "Om..." - -say properties "Egenskaber" -say open "bn" - -### for key binding editor -say general "Generelt" -say audio_settings "Lyd indstillinger" -say midi_settings "MIDI indstillinger" -say latency_meter "Forsinkelse" -say Pdwindow "Pd vindue" - -say canvaspdwindow "Pd vindue" -say canvaslatency_meter "Forsinkelse" -say clientaudio_settings "Lyd indstillinger" -say clientmidi_settings "MIDI indstillinger" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "bredde(px)" -say h "hjde(px)" -say hold "vis (ms)" -say break "afbryd (ms)" -say min "minimum vrdi" -say max "maximum vrdi" -say is_log "modus" -say linear "liner" -say logarithmic "logaritmisk" -say isa "startvrdi" -say n "antal valg" -say steady "reaktion" -say steady_no "Hop ved klik" -say steady_yes "Bliv ved klik" -say snd "sende-navn" -say rcv "modtage-navn" -say lab "etiket" -say ldx "etiket x afst" -say ldy "etiket y afst" -say fstyle "Udseende" -say fs "font strrelse" -say bcol "baggrundsfarve" -say fcol "forgrundsfarve" -say lcol "farve etiket" -say yes "ja" -say no "nej" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "vis p forldre" - -say_category GAtomProperties -say width "bredde" -say lo "nedre grnse" -say hi "vre grnse" -say label "etiket" -say wherelabel "vis label" -say symto "sende-navn" -say symfrom "modtage-navn" - -say_category GraphProperties -say x1 "x fra" -say x2 "x til" -say xpix "bredde" -say y2 "y fra" -say y1 "y til" -say ypix "hjde" - -say_category CanvasProperties -#say xscale "X enheder/px" -#say yscale "Y enheder/px" -say gop "vis p forlder" -say xmargin "x margen" -say ymargin "y margen" -say height "hjde" -say_category ArrayProperties -say name "navn" -say n "strrelse" -say xfrom "x fra" -say xto "x til" -say yfrom "y fra" -say yto "y til" - - -say_category MainWindow -say in "ind" -say out "ud" -say audio "Lyd" -say meters "Meter" -say io_errors "IO fejl" -say tcl_console "Tcl Klient" -say pd_console "Pd Server" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Boks" - say tgl "Toggle Boks" - say nbx "Tal Boks (IEM)" - say hsl "Fader (vandret)" - say vsl "Fader (lodret)" - say hradio "Valgboks (vandret)" - say vradio "Valgbox (lodret)" - say cnv "Lrred (IEM)" - say dropper "Trk og slip box" - say vu "Vumeter" - - say_category GLUE - say bang "send et bang" - say float "gem og genkald decimaltal" - say symbol "gem og genkald symbol" - say int "gem og genkald heltal" - say send "send besked til objekt med navn" - say receive "modtag sendte beskeder" - say select "vlg symbol eller tal" - say route "rute efter frste element" - say pack "pak elementer" - say unpack "pak elementer ud" - say trigger "rkkeflge og omdannelse" - say spigot "afbryder" - say moses "del talstrm" - say until "gentagne bangs" - say print "skriv til promt" - say makefilename "formater navn med variabel" - say change "fjern gentagelser" - say swap "ombyt to tal" - say value "global variabel" - - say_category TIME - say delay "forsink bang" - say metro "metronom" - say line "skridtvis liner interpolation" - say timer "ml tid mellem beskeder" - say cputime "ml CPU tid" - say realtime "ml reel tid" - say pipe "dynamisk voksende forsinkelse af tal" - - say_category MATH - say + "adder" - say - "subtraher" - say * "multiplicer" - say {/ div} "divider" - say {% mod} "heltal modulus" - say pow "eksponent" - say == "ens?" - say != "forskellig?" - say > "strrer end?" - say < "mindre end?" - say >= "strrer eller lig med?" - say <= "mindre eller lig med?" - say & "bitmssig (og)" - say | "bitmssig (eller)" - say && "boelsk (og)" - say || "boelsk (eller)" - say mtof "MIDI til Hertz" - say ftom "Hertz til MIDI" - say powtodb "W til dB" - say dbtopow "dB til W" - say rmstodb "Volt til dB" - say dbtorms "dB til Volt" - say {sin cos tan atan atan2 sqrt} "trigonometri" - say log "Euler logaritme" - say exp "Euler exponentiale" - say abs "absolutte vrdi" - say random "tilfldigt heltal" - say max "strst af to tal" - say min "mindst af to tal" - say clip "klip tal hvis udenfor grnser" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI ind" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI ud" - say makenote "formater miditone" - say stripnote "fjern \"note off\" beskeder" - - say_category TABLES - say tabread "ls tal fra tabel" - say tabread4 "ls tal fra tabel, med kubisk interpolation" - say tabwrite "skriv tal ind i tabel" - say soundfiler "ls og skriv tabeller" - - say_category MISC - say loadbang "bang ved start" - say serial "serielport (kun NT)" - say netsend "send bekeder via netvrk" - say netreceive "modtag beskeder fra netvrk" - say qlist "besked sequencer" - say textfile "fil til besked konverter" - say openpanel "\"bn\" dialog" - say savepanel "\"Gem som\" dialog" - say bag "talst" - say poly "polyfonisk stemmekontrol" - say {key keyup} "tastaturvrdier" - say keyname "tastnavn" - - say_category "Signal matematik" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "strst af to signaler" - say min~ "mindst af to signaler" - say clip~ "begrns signal" - say q8_rsqrt~ "billig omvendt kvadratrod (8 bit!)" - say q8_sqrt~ "billig kvadratrod (8 bit!)" - say wrap~ "decimaldel af signal" - say fft~ "compleks diskret Fourier transformation" - say ifft~ "omvendt compleks diskret Fourier transformation" - say rfft~ "reel diskret Fourier transformation" - say rifft~ "omvendt reel diskret Fourier transformation" - say framp~ "rampe per blok" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "LYD LIM" - say dac~ "lyd ud" - say adc~ "lyd ind" - say sig~ "konverter tal til signal" - say line~ "signal rampe" - say vline~ "deluxe line~" - say threshold~ "find signalgrnse" - say snapshot~ "konverter signal til tal" - say vsnapshot~ "deluxe snapshot~" - say bang~ "bang efter hver blok" - say samplerate~ "hent samplefrekvens" - say send~ "send et signal til mange modtagere" - say receive~ "modtag fra send~" - say throw~ "mange signalafsendere til en modtager" - say catch~ "modtag fra throw~" - say block~ "st blokstrrelse og overlap" - say switch~ "tnd/sluk DSP lokalt" - say readsf~ "afspil lydfil fra hrdskive" - say writesf~ "optag lyd p hrdskive" - - say_category "signal oscillatorer og tabeller" - say phasor~ "savtak-generator" - say {cos~ osc~} "cubisk interpoleret cosinus tabelopslag" - say tabwrite~ "skriv signal til tabel" - say tabplay~ "afspil tabel (uden transponering)" - say tabread~ "ikke interpoleret tabelafspilning" - say tabread4~ "kubisk interpoleret tabelafspilning" - say tabosc4~ "tabel oscillator" - say tabsend~ "skriv en blok kontinuerligt til tabel" - say tabreceive~ "ls en blok kontinuerligt fra tabel" - - say_category "Signal filtre" - say vcf~ "volt controlleret filter" - say noise~ "hvid stj" - say env~ "flg signal" - say hip~ "hjpas filter" - say lop~ "lavpas filter" - say bp~ "bndpas filter" - say biquad~ "2-pol-2-nul-filter" - say samphold~ "sample og frys dims" - say print~ "skriv en eller flere \"blocks\" ud" - say rpole~ "en pol reel filter" - say rzero~ "et nul reel filter" - say rzero_rev~ "[say rzero~] (baglns)" - say cpole~ "[say rpole~] (kompleks)" - say czero~ "[say rzero~] (kompleks)" - say czero_rev~ "[say rzero_rev~] (kompleks)" - - say_category "AUDIO DELAY" - say delwrite~ "forsink" - say delread~ "ls efter forsinkelse" - say vd~ "ls efter varieret forsinkelse" - - say_category "SUBWINDOWS" - say pd "definer undervindue" - say table "tabel i undervindue" - say inlet "tilfj indgang til et vindue" - say outlet "tilfj udgang fra et vindue" - say inlet~ "[say inlet] (signal)" - say outlet~ "[say outlet] (signal)" - - say_category "DATA skabeloner" - say struct "definer en data struktur" - say {drawcurve filledcurve} "tegn en kurve" - say {drawpolygon filledpolygon} "tegn en polygon" - say plot "tegn en tabel" - say drawnumber "skriv et tal" - - say_category "ACCESSING DATA" - say pointer "peg p et objekt der hrer til en skabelon" - say get "hent numeriske felt" - say set "skift numerisk felt" - say element "hent element fra tabel" - say getsize "hent strrelse p tabel" - say setsize "st lngde p tabel" - say append "tilfj element til liste" - say sublist "peger p start af undertabel" - say scalar "tegn skalar p forlder" - - say_category "FOORLDET" - say scope~ "(brug tabwrite~ nu)" - say namecanvas "" ;# what was this anyway? - say template "(brug struct)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Lyd" - say -r "sample rate" - say -audioindev "LYD-ind enheder" - say -audiooutdev "LYD-ud enheder" - say -inchannels "antal lydkanaler ind (per enhed, som \"2\" or \"16,8\")" - say -outchannels "antal lydkanaler ud (samme)" - say -audiobuf "Lydbuffer i millisekunder" - say -blocksize "specificer lyd I/O blok i samples" - say -sleepgrain "specificer pause i millisekunder ved ledighed" - say -nodac "ingen lyd ud" - say -noadc "ingen lyd ind" - say audio_api_choice "Audio API" - say default "forudindstillet" - say -alsa "brug ALSA lyd API" - say -jack "brug JACK lyd API" - say -mmio "brug MMIO lyd API (forudindstillet til Windows)" - say -portaudio "brug ASIO lyd (via Portaudio)" - say -oss "brug OSS lyd API" - say -32bit "tillad 32 bit OSS lyd (til RME Hammerfall)" - say {} "forudindstillet" - -say section_midi "MIDI" - say -nomidiin "ingen MIDI ind" - say -nomidiout "ingen MIDI ud" - say -midiindev "midi ind enhedsliste; e.g., \"1,3\" frste og tredje" - say -midioutdev "midi ud enhedsliste (samme format)" - -say section_externals "Eksterne biblioteker" - say -path "fil sgesti" - say -helppath "hjlpefil sgesti" - say -lib "bn biblioteker" - -say section_gui "Gooey" - say -nogui "ingen grafisk brugerflade (pas p)" - say -guicmd "brug anden grafisk brugerflade (e.g., rsh)" - say -look "knap ikoner" - say -font "st forudindstillet fontstrrelse i points" - -say section_other "Andet" - say -open "bn fil(er) ved start" - say -verbose "ekstra beskeder ved opstart og filsgning" - say -d "fejlsgning" - say -noloadbang "ingen \[loadbang\]" - say -send "send besked ved start (efter alt er bent)" - say -listdev "list lyd og MIDI enheder ved start" - say -realtime "brug real-time priority (behver root privilege)" - -say section_paths "Stier" - -# phase 4B: ddrc (keyword names not finalized!) -say console "spol antal linier tilbage i konsollen (0 = skriv ikke til konsol)" -say lang "Sprog" -say pointer_sense "Musens flsomhed" -say section_color "farver" - say canvas_color "lrred" - say canvasbgedit "farve p lrred ved redigering" - say canvasbgrun "farve p lrred ved Kr" - say object_color "objekt" - say viewframe1 "farve p objektboks" - say viewframe2 "farve p objektboks" - say viewframe3 "farve p objektboks" - say viewframe4 "farve p valgt objektboks" - say viewbg "baggrundsfarve p objektboks" - say viewfg "forgrundsfarve p objektboks" - say commentbg "baggrundsfarve p kommentar" - say commentfg "forgrundsfarve p kommentar" - say commentframe1 "ramme p kommentar" - say commentframe2 "ramme p kommentar" - say commentframe3 "ramme p kommentar" - say viewselectframe "valgt boks" - say wire_color "trd" - say wirefg "trd farve" - say wirefg2 "valgt trd" - say wiredspfg "signaltrd" - say futurewiredash "ny (stiplet) trd" - say others_color "andet" - say boxinletfg "farve p indgang" - say boxoutletfg "farve p udgang" - say selrectrect "valgt omrde" -say keys "taster" -say others "andet" -say hairstate "aktiver kors" -say hairsnap "snap kors til objekt" -say statusbar "Aktiver statusvisning" -say buttonbar "Aktiver objekt knapper" -say menubar "Aktiver menubar" -say scrollbar "Aktiver autospoleknap" -say wirearrow "trd pil" -say tooltip "Vrktjstip" -say insert_object "Indst objekt" -say chain_object "Forbind objekt(er)" -say clear_wires "Fjern trde" -say auto_wire "Fjern objekt" -say subpatcherize "Subpatcherize" -say keynav "tastatur navigation" -say key_nav_up "flyt op" -say key_nav_up_shift "plus select" -say key_nav_down "flyt ned" -say key_nav_down_shift "plus select" -say key_nav_right "flyt til hjre" -say key_nav_right_shift "plus select" -say key_nav_left "flyt til venstre" -say key_nav_left_shift "plus select" -say key_nav_ioselect "vlg ind/udgang" -# phase 5A - -say cannot "Kan ikke" -say cancel "fortryd" -say apply "Gr det" -say ok "OK" -say popup_open "bn" -say popup_insert "St ind" -say popup_properties "Egenskaber" -say popup_clear_wires "Slet trde" -say popup_remove_from_path "Fjern objekt fra sti" -say popup_delete_from_path "Slet objekt fra sti" -say popup_help "Hjlp" -say filter "Filter: " -say how_many_object_classes "%d af %d objektklasser" -say do_what_i_mean "Gr hvad jeg mener" -say ask_cool "Det ville have vret fedt at kunne gre, ikk?" -say save_changes? "Gem ndringer?" -say reset "Nulstil" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Tilfj" -say up "Op" -say down "Ned" -say remove "Fjern" -say lib_add "tilfj bibliotek til listen" -say lib_up "byt med forrige bibliotek" -say lib_down "byt med nste bibliotek" -say lib_remove "fjern valgte fra listen" -say dir_add "tilfj mappe vha. dialog" -say dir_up "byt med forrige mappe" -say dir_down "byt med nste mappe" -say dir_remove "fjern valgt mappe fra listen" -say client_class_tree "Klient klasse tr" -say clipboard_view "Se klipbord" -say command_history_view "se kommando historie" -say event_history_view "se handlings historie" - -# during/after piksel: - -say auto_apply "Automatisk" -say font_preview "Se:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Stil:" -say font_bold "Fremhvet" -say font_italic "Skr" -say font_family "Navn:" -say font_size "Strrelse:" -say damn "Pokkers!" -say console_clear "Slet indholdet i konsollen" -say horizontal "Vandret" -say vertical "Lodret" -say language "Sprog" - -# 2007: - -say no_matches "(ingen svarer til)" -say preset "forudsat" diff --git a/desiredata/src/locale/deutsch.tcl b/desiredata/src/locale/deutsch.tcl deleted file mode 100644 index 439e672b..00000000 --- a/desiredata/src/locale/deutsch.tcl +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env tclsh -# German translations for PureData -# $Id: deutsch.tcl,v 1.1.2.13 2006-11-25 01:45:05 matju Exp $ -# by Max Neupert, Georg Holzmann, Thomas Grill - -say file "Datei" - say new_file "Neu" - say open_file "ffnen..." - say pdrc_editor ".pdrc Editor" - say send_message "Sende Nachricht..." ;# georg&foo say "Message" - say paths "Pfade..." - say close "Schlieen" - say save "Speichern" - say save_as "Speichern Unter..." - say print "Drucken..." - say quit "Beenden" - -say edit "Bearbeiten" - say undo "Rckgngig" - say redo "Wiederherstellen" - say cut "Ausschneiden" - say copy "Kopieren" - say paste "Einfgen" - say duplicate "Duplizieren" - say select_all "Alles auswhlen" - say text_editor "Texteditor..." - say tidy_up "Aufrumen" - say edit_mode "Editiermodus" ;# georg says "Edit Modus" - -say view "Ansicht" - say reload "Neu Laden" - say redraw "Neu Zeichnen" - -say find "Suchen" - say find_again "Weitersuchen" ;# georg: "Suche Nochmal" - say find_last_error "Finde letzten Fehler" ;# georg: "Finde Letzten Error" - -say put "Erstelle" - -say media "Media" - say audio_on "Audio AN" - say audio_off "Audio AUS" - -say window "Fenster" - -say help "Hilfe" - say about "ber..." - say pure_documentation "Pure Documentation..." - say class_browser "Class Browser..." - - - -### Main Window - -say in "Eingang" -say out "Ausgang" -say audio "Audio" -say meters "Pegel" -say io_errors "IO Fehler" - - -say_namespace summary { - say_category "IEMGUI" - say bng "Bang-Feld" - say tgl "Schalter" - say nbx "Zahlenfeld (IEM)" - say hsl "Schieberegler (Horizontal)" - say vsl "Schieberegler (Vertical)" - say hradio "Radioknopf (Horizontal)" - say vradio "Radioknopf (Vertical)" - say cnv "Hintergrund (IEM)" - say vu "VU-Pegel" - say dropper "\"Drag-and-Drop\" Box" - - say_category "GLUE" - say bang "Bang-Nachricht ausgeben" - say float "Zahl speichern und abrufen" - say symbol "Symbol speichern und abrufen" - say int "Ganzzahl speichern und abrufen" - say send "Nachricht an benanntes Objekt schicken" - say receive "Nachrichten empfangen" - say select "auf bereinstimmende Symbole oder Zahlen prfen" - say route "Nachrichten gem ihrem ersten Element umleiten" - say pack "Nachrichten packen" - say unpack "gepackte Nachrichten auflsen" - say trigger "Nachrichten auslsen und umwandeln" - say spigot "eine steuerbare Nachrichtenverbindung" - say moses "einen Zahlenstrom aufteilen" - say until "Schleife" - say print "Ausgabe in Konsole umleiten" - say makefilename "Symbol mit Variable formatieren" - say change "entfernt wiederholte Nachrichten" - say swap "zwei Zahlen austauschen" - say value "gemeinsamer Zahlenspeicher" - - say_category "TIME" - say delay "verzgert Nachrichten" - say metro "sendet Nachrichten im Takt" - say line "interpoliert zwischen zwei Zahlen" - say timer "misst Zeitabstnde" - say cputime "Prozessorzeit-Messung" - say realtime "Echtzeit-Messung" - say pipe "dynamisch verlngerbare Verzgerungsstrecke" - - say_category "MATH" - say + "addieren" - say - "subtrahieren" - say * "multiplizieren" - say {/ div} "dividieren" - say {% mod} "Divisionsrest" - say pow "potenzieren" - say == "gleich?" - say != "ungleich?" - say > "grer als?" - say < "kleiner als?" - say >= "grer gleich?" - say <= "kleiner gleich?" - say & "bitweise UND-Funktion" - say | "bitweise ODER-Funktion" - say && "logische UND-Funktion " - say || "logische ODER-Funktion" - say mtof "MIDI zu Hertz Umrechnung" - say ftom "Hertz zu MIDI Umrechnung" - say powtodb "Watt zu dB Umrechnung" - say dbtopow "dB zu Watt Umrechnung" - say rmstodb "Volt zu dB Umrechnung" - say dbtorms "dB zu Volt Umrechnung" - say {sin cos tan atan atan2 sqrt} "Trigonometrie" - say log "natrlicher Logarithmus" - say exp "Exponentialfunktion" - say abs "absoluter Wert" - say random "Zufallszahl" - say max "grere zweier Zahlen" - say min "kleinere zweier Zahlen" - say clip "Begrenzung einer Zahlenreihe" - - say_category "MIDI" - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} \ -"MIDI Eingang" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} \ -"MIDI Ausgang" - say makenote \ - "eine verzgerte \"note off\" Nachricht nach einer \"noteon\"-Nachricht einplanen" - say stripnote "entferne \"note off\" Nachrichten" - - say_category "TABLES" - say tabread "liest Zahl aus einer Tabelle" - say tabread4 "liest Zahl aus einer Tabelle, mit 4-Punkt-Interpolation" - say tabwrite "schreibt Zahl in eine Tabelle" - say soundfiler "schreibt und liest Samples in/aus einer Tabelle" - - say_category "MISC" - say loadbang "Bang beim ffnen der Datei" - say serial "Serielle Schnittstelle, nur NT" - say netsend "sendet Nachrichten ber das Netzwerk" - say netreceive "empfngt Nachrichten ber das Netzwerk" - say qlist "Nachrichten-Sequenzer" - say textfile "Datei zu Nachricht bersetzung" - say openpanel "\"ffnen...\" Dialog" - say savepanel "\"Speichern unter...\" Dialog" - say bag "Zahlenpaar" - say poly "Polyphone Stimmenbelegung" - say {key keyup} "Numerische Tastenwerte der Tastatur" - say keyname "Symbolischer Tastenname" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (fr Audiosignale)"} - say max~ "Maximum eines Audiosignals" - say min~ "Minimum eines Audiosignals" - say clip~ "begrenzt ein Audiosignal von unten und oben" - say q8_rsqrt~ "schnelle reziproke Quadratwurzel (Achtung! - 8 Bit)" - say q8_sqrt~ "schnelle Quadratwurzel (Achtung! - 8 Bit)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "komplexe Fouriertransformation vorwrts" - say ifft~ "komplexe inverse Fast-Fouriertransformation" - say rfft~ "reelle Fouriertransformation vorwrts" - say rifft~ "reelle inverse Fast-Fouriertransformation" - say framp~ "erzeugt eine Rampe fr jeden Block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (fr Audiosignale)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "Audio Ausgabe" - say adc~ "Audio Eingabe" - say sig~ "wandelt Zahlen in Audiosignal um" - say line~ "generiert Audio Rampen" - say vline~ "deluxe line~" - say threshold~ "erkennt Schwellenwerte des Audiosignals" - say snapshot~ "tastet ein Audiosignal ab (konvertiert es zu Zahlen)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "sendet Bang nach jedem DSP-Block" - say samplerate~ "gibt die Abtastrate aus" - say send~ "nonlocal signal connection with fanout" - say receive~ "empfngt Audiosignal von send~" - say throw~ "fgt Audiosignal zu einem sich summierenden Bus zu" - say catch~ "definiert und liest einen Bus" - say block~ "legt Block-Gre und berlappung fest" - say switch~ "schaltet DSP-Berechnung an/aus" - say readsf~ "spielt Audiodateien von Festplatte ab" - say writesf~ "nimmt Audio auf Festplatte auf" - - say_category "AUDIO-OSZILLATOREN AND TABELLEN" - say phasor~ "Sgezahn-Oszillator" - say {cos~ osc~} "Cosinus-Oszillator" - say tabwrite~ "in eine Tabelle schreiben" - say tabplay~ "aus einer Tabelle abspielen (nicht-transponierend)" - say tabread~ "Tabelle auslesen (ohne Interpolation)" - say tabread4~ "Tabelle auslesen (mit Vier-Punkt Interpolation)" - say tabosc4~ "wavetable Oszillator" - say tabsend~ "einen Block kontinuierlich in eine Tabelle schreiben" - say tabreceive~ "einen Block kontinuierlich aus einer Tabelle lesen" - - say_category "AUDIO FILTER" - say vcf~ "Spannungsgesteuerter Filter" - say noise~ "generiert weies Rauschen" - say env~ "Hllkurven-Abtaster" - say hip~ "Hochpassfilter" - say lop~ "Tiefpassfilter" - say bp~ "Bandpassfilter" - say biquad~ "grober Filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO VERZGERUNG" - say delwrite~ "in eine Verzgerungsstrecke schreiben" - say delread~ "von einer Verzgerungsstrecke lesen" - say vd~ "von einer Verzgerungsstrecke in variabler Verzgerungszeit lesen" - - say_category "UNTERFENSTER" - say pd "definiere ein Unterfenster" - say table "Zahlentabelle in einem Unterfenster" - say inlet "Eingang hinzufgen" - say outlet "Ausgang hinzufgen" - say inlet~ "[say inlet] (fr Audiosignale)" - say outlet~ "[say outlet] (fr Audiosignale)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "zeichnet eine Kurve" - say {drawpolygon filledpolygon} "zeichnet ein Polygon" - say plot "plot an array field" - say drawnumber "einen Zahlenwert ausgeben" - - say_category "DATENZUGRIFF" - say pointer "point to an object belonging to a template" - say get "get numeric fields" - say set "legt Wert in Zahlenfeldern fest" - say element "get an array element" - say getsize "Gre eines Arrays feststellen" - say setsize "Gre eines Arrays bestimmen" - say append "Element an eine Liste anfgen" - say sublist "get a pointer into a list which is an element of another \ -scalar" - say scalar "draw a scalar on parent" - - say_category "BERHOLT" - say scope~ "(benutze tabwrite~ anstatt)" - say namecanvas "" ;# what was this anyway? - say template "(benutze struct anstatt)" -} - -say cannot "kann nicht" - -say filter "Filter" ;# sorry -say how_many_object_classes "%d/%d" - -say save_changes? "nderungen speichern?" - - diff --git a/desiredata/src/locale/english.tcl b/desiredata/src/locale/english.tcl deleted file mode 100644 index 13545a1a..00000000 --- a/desiredata/src/locale/english.tcl +++ /dev/null @@ -1,575 +0,0 @@ -#!/usr/bin/env tclsh -# English translations for PureData -# $Id: english.tcl,v 1.1.2.34.2.22 2007/09/04 11:24:02 chunlee Exp $ - -### Menus - -say file "File" - say new_file "New File" - say open_file "Open File..." - say server_prefs "Server Preferences..." - say client_prefs "Client Preferences..." - say send_message "Send Message..." - say paths "Paths..." - say close "Close" - say save "Save" - say save_as "Save As..." - say print "Print..." - say abort_server "Abort Server" - say quit "Quit" - - say canvasnew_file "New File" - say canvasopen_file "Open File..." - say canvassave "Save" - say canvassave_as "Save As..." - say clientpdrc_editor ".pdrc Editor" - say clientddrc_editor ".ddrc Editor" - say canvasclose "Close" - say canvasquit "Quit" - -say edit "Edit" - say undo "Undo" - say redo "Redo" - say cut "Cut" - say copy "Copy" - say paste "Paste" - say duplicate "Duplicate" - say select_all "Select All" - say clear_selection "Deselect selection" - say text_editor "Text Editor..." - say font "Font" - say tidy_up "Tidy Up" - say edit_mode "Edit Mode" - say editmodeswitch "Edit/Run mode" - say subpatcherize "Subpatcherize" - - say canvascut "Cut" - say canvascopy "Copy" - say canvasundo "Undo" - say canvasredo "Redo" - say canvaspaste "Paste" - say canvasduplicate "Duplicate" - say canvasselect_all "Select All" - say canvaseditmodeswitch "Edit/Run mode" - -say view "View" - say reload "Reload" - say redraw "Redraw" - - say canvasreload "Reload" - say canvasredraw "Redraw" - -say find "Find" - say find_again "Find Again" - say find_last_error "Find Last Error" - say string "Find string" -say canvasfind "Find" - say canvasfind_again "Find Again" - -# contents of Put menu is Phase 5C -say put "Put" - say Object "Object" - say Message "Message" - say Number "Number" - say Symbol "Symbol" - say Comment "Comment" - say Graph "Graph" - say Array "Array" - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Test Audio and MIDI" - say load_meter "Load Meter" - - say canvasaudio_on "Audio ON" - say canvasaudio_off "Audio OFF" - say clienttest_audio_and_midi "Test Audio and MIDI" - say canvasload_meter "Load Meter" - -say window "Window" - -say help "Help" - say about "About..." - say documentation "Documentation..." - say class_browser "Class Browser..." - - say canvasabout "About..." - -say properties "Properties" -say open "Open" - -### for key binding editor -say general "General" -say audio_settings "Audio Settings" -say midi_settings "Midi Settings" -say latency_meter "Latency Meter" -say Pdwindow "Pd window" - -say canvaspdwindow "Pd window" -say canvaslatency_meter "Latency Meter" -say clientaudio_settings "Audio Settings" -say clientmidi_settings "Midi Settings" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "width(px)" -say h "height(px)" -say hold "hold time(ms)" -say break "break time(ms)" -say min "minimum value" -say max "maximum value" -say is_log "mode" -say linear "linear" -say logarithmic "logarithmic" -say isa "init" -say n "number of choices" -say steady "steadiness" -say steady_no "jump on click" -say steady_yes "steady on click" -say snd "send-symbol" -say rcv "receive-symbol" -say lab "label" -say ldx "label x offset" -say ldy "label y offset" -say fstyle "Typeface" -say fs "font size" -say bcol "background color" -say fcol "forground color" -say lcol "label color" -say yes "yes" -say no "no" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "graph on parent" - -say_category GAtomProperties -say width "width" -say lo "lower limit" -say hi "upper limit" -say label "label" -say wherelabel "show label on" -say symto "send symbol" -say symfrom "receive symbol" - -say_category GraphProperties -say x1 "x from" -say x2 "x to" -say xpix "screen width" -say y2 "y from" -say y1 "y to" -say ypix "screen height" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "graph on parent" -say xmargin "xmargin" -say ymargin "ymargin" -say height "height" -say_category ArrayProperties -say name "name" -say n "size" -say xfrom "x range from" -say xto "x range to" -say yfrom "y range from" -say yto "y range to" - - -say_category MainWindow -say in "in" -say out "out" -say audio "Audio" -say meters "Meters" -say io_errors "IO Errors" -say tcl_console "Tcl Client" -say pd_console "Pd Server" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box" - say tgl "Toggle Box" - say nbx "Number Box (IEM)" - say hsl "Slider (Horizontal)" - say vsl "Slider (Vertical)" - say hradio "Choice Box (Horizontal)" - say vradio "Choice Box (Vertical)" - say cnv "Canvas (IEM)" - say dropper "Drag-and-Drop Box" - say vu "Vumeter" - - say_category GLUE - say bang "output a bang message" - say float "store and recall a number" - say symbol "store and recall a symbol" - say int "store and recall an integer" - say send "send a message to a named object" - say receive "catch sent messages" - say select "test for matching numbers or symbols" - say route "route messages according to first element" - say pack "make compound messages" - say unpack "get elements of compound messages" - say trigger "sequence and convert messagess" - say spigot "interruptible message connection" - say moses "part a numeric stream" - say until "looping mechanism" - say print "print out messages" - say makefilename "format a symbol with a variable field" - say change "remove repeated numbers from a stream" - say swap "swap two numbers" - say value "shared numeric value" - - say_category TIME - say delay "send a message after a time delay" - say metro "send a message periodically" - say line "send a series of linearly stepped numbers" - say timer "measure time intervals" - say cputime "measure CPU time" - say realtime "measure real time" - say pipe "dynamically growable delay line for numbers" - - say_category MATH - say + "add" - say - "substract" - say * "multiply" - say {/ div} "divide" - say {% mod} "division remainder" - say pow "exponentiate" - say == "equal?" - say != "not equal?" - say > "more than?" - say < "less than?" - say >= "not less than?" - say <= "not more than?" - say & "bitwise conjunction (and)" - say | "bitwise disjunction (or)" - say && "logical conjunction (and)" - say || "logical disjunction (or)" - say mtof "MIDI to Hertz" - say ftom "Hertz to MIDI" - say powtodb "Watts to dB" - say dbtopow "dB to Watts" - say rmstodb "Volts to dB" - say dbtorms "dB to Volts" - say {sin cos tan atan atan2 sqrt} "trigonometry" - say log "Euler logarithm" - say exp "Euler exponential" - say abs "absolute value" - say random "random" - say max "greater of two numbers" - say min "lesser of two numbers" - say clip "force a number into a range" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI input" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI output" - say makenote "schedule a delayed \"note off\" message corresponding to a note-on" - say stripnote "strip \"note off\" messages" - - say_category TABLES - say tabread "read a number from a table" - say tabread4 "read a number from a table, with 4 point interpolation" - say tabwrite "write a number to a table" - say soundfiler "read and write tables to soundfiles" - - say_category MISC - say loadbang "bang on load" - say serial "serial device control for NT only" - say netsend "send messages over the internet" - say netreceive "receive them" - say qlist "message sequencer" - say textfile "file to message converter" - say openpanel "\"Open\" dialogue" - say savepanel "\"Save as\" dialogue" - say bag "set of numbers" - say poly "polyphonic voice allocation" - say {key keyup} "numeric key values from keyboard" - say keyname "symbolic key name" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "supremum of signals" - say min~ "infimum of signals" - say clip~ "constrict signal to lie between two bounds" - say q8_rsqrt~ "cheap reciprocal square root (beware -- 8 bits!)" - say q8_sqrt~ "cheap square root (beware -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "real inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio output" - say adc~ "audio input" - say sig~ "convert numbers to audio signals" - say line~ "generate audio ramps" - say vline~ "deluxe line~" - say threshold~ "detect signal thresholds" - say snapshot~ "sample a signal (convert it back to a number)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "send a bang message after each DSP block" - say samplerate~ "get the sample rate" - say send~ "nonlocal signal connection with fanout" - say receive~ "get signal from send~" - say throw~ "add to a summing bus" - say catch~ "define and read a summing bus" - say block~ "specify block size and overlap" - say switch~ "switch DSP computation on and off" - say readsf~ "soundfile playback from disk" - say writesf~ "record sound to disk" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "sawtooth oscillator" - say {cos~ osc~} "cosine oscillator" - say tabwrite~ "write to a table" - say tabplay~ "play back from a table (non-transposing)" - say tabread~ "non-interpolating table read" - say tabread4~ "four-point interpolating table read" - say tabosc4~ "wavetable oscillator" - say tabsend~ "write one block continuously to a table" - say tabreceive~ "read one block continuously from a table" - - say_category "AUDIO FILTERS" - say vcf~ "voltage controlled filter" - say noise~ "white noise generator" - say env~ "envelope follower" - say hip~ "high pass filter" - say lop~ "low pass filter" - say bp~ "band pass filter" - say biquad~ "raw filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO DELAY" - say delwrite~ "write to a delay line" - say delread~ "read from a delay line" - say vd~ "read from a delay line at a variable delay time" - - say_category "SUBWINDOWS" - say pd "define a subwindow" - say table "array of numbers in a subwindow" - say inlet "add an inlet to a pd" - say outlet "add an outlet to a pd" - say inlet~ "[say inlet] (for signal)" - say outlet~ "[say outlet] (for signal)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "draw a curve" - say {drawpolygon filledpolygon} "draw a polygon" - say plot "plot an array field" - say drawnumber "print a numeric value" - - say_category "ACCESSING DATA" - say pointer "point to an object belonging to a template" - say get "get numeric fields" - say set "change numeric fields" - say element "get an array element" - say getsize "get the size of an array" - say setsize "change the size of an array" - say append "add an element to a list" - say sublist "get a pointer into a list which is an element of another scalar" - say scalar "draw a scalar on parent" - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ now)" - say namecanvas "" ;# what was this anyway? - say template "(use struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "sample rate" - say -audioindev "audio in devices" - say -audiooutdev "audio out devices" - say -inchannels "audio input channels (by device, like \"2\" or \"16,8\")" - say -outchannels "number of audio out channels (same)" - say -audiobuf "specify size of audio buffer in msec" - say -blocksize "specify audio I/O block size in sample frames" - say -sleepgrain "specify number of milliseconds to sleep when idle" - say -nodac "suppress audio output" - say -noadc "suppress audio input" - say audio_api_choice "Audio API" - say default "default" - say -alsa "use ALSA audio API" - say -jack "use JACK audio API" - say -mmio "use MMIO audio API (default for Windows)" - say -portaudio "use ASIO audio driver (via Portaudio)" - say -oss "use OSS audio API" - say -32bit "allow 32 bit OSS audio (for RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "suppress MIDI input" - say -nomidiout "suppress MIDI output" - say -midiindev "midi in device list; e.g., \"1,3\" for first and third" - say -midioutdev "midi out device list, same format" - -say section_externals "Externals" - say -path "file search path" - say -helppath "help file search path" - say -lib "load object libraries" - -say section_gui "Gooey" - say -nogui "suppress starting the GUI (caution)" - say -guicmd "substitute another GUI program (e.g., rsh)" - say -look "buttonbar icons" - say -font "specify default font size in points" - -say section_other "Other" - say -open "open file(s) on startup" - say -verbose "extra printout on startup and when searching for files" - say -d "debug level" - say -noloadbang "disable the effect of \[loadbang\]" - say -send "send a message at startup (after patches are loaded)" - say -listdev "list audio and MIDI devices upon startup" - say -realtime "use real-time priority (needs root privilege)" - -say section_paths "Paths" - -# phase 4B: ddrc (keyword names not finalized!) -say console "console scrollback lines (0 = disable console)" -say lang "Language to use" -say pointer_sense "Mouse pointer sensitivity" -say section_color "Appearance" - say canvas_color "canvas" - say canvasbgedit "canvas background (edit mode)" - say canvasbgrun "canvas background (run mode)" - say object_color "object" - say viewframe1 "objectbox color" - say viewframe2 "objectbox color" - say viewframe3 "objectbox color" - say viewframe4 "objectbox highlight color" - say viewbg "object background" - say viewfg "object foreground" - say commentbg "comment background" - say commentfg "comment forground" - say commentframe1 "comment frame" - say commentframe2 "comment frame" - say commentframe3 "comment frame" - say viewselectframe "hilight box" - say wire_color "wire" - say wirefg "wire color" - say wirefg2 "wire highlight" - say wiredspfg "dsp wire color" - say futurewiredash "new (dashed) wire" - say others_color "others" - say boxinletfg "inlet color" - say boxoutletfg "outlet color" - say selrectrect "selection box" -say keys "keys" -say others "others" -say hairstate "Activate crosshair" -say hairsnap "Crosshair snap to object" -say statusbar "Activate statusbar" -say buttonbar "Activate buttonbar" -say menubar "Activate menubar" -say scrollbar "Active auto scrollbar" -say wirearrow "Wire Arrow" -say tooltip "ToolTip" -say insert_object "Insert object" -say chain_object "Chain object" -say clear_wires "Clear wires" -say auto_wire "Remove object" -say subpatcherize "Subpatcherize" -say keynav "keyboard navigation" -say key_nav_up "move up" -say key_nav_up_shift "plus select" -say key_nav_down "move down" -say key_nav_down_shift "plus select" -say key_nav_right "move right" -say key_nav_right_shift "plus select" -say key_nav_left "move left" -say key_nav_left_shift "plus select" -say key_nav_ioselect "select in/outlets" -# phase 5A - -say cannot "can't" -say cancel "Cancel" -say apply "Apply" -say ok "OK" -say popup_open "Open" -say popup_insert "Insert" -say popup_properties "Properties" -say popup_clear_wires "Clear wires" -say popup_remove_from_path "Remove object from path" -say popup_delete_from_path "Delete object from path" -say popup_help "Help" -say filter "Filter: " -say how_many_object_classes "%d of %d object classes" -say do_what_i_mean "Do What I Mean" -say ask_cool "This would be a cool feature, eh?" -say save_changes? "Save changes?" -say reset "Reset" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Add" -say up "Up" -say down "Down" -say remove "Remove" -say lib_add "add the name you typed to the list" -say lib_up "swap order with previous library" -say lib_down "swap order with next library" -say lib_remove "remove library selected in the list" -say dir_add "add a folder using a file dialogue" -say dir_up "swap order with previous folder" -say dir_down "swap order with next folder" -say dir_remove "remove folder selected in the list" -say client_class_tree "Client Class Tree" -say clipboard_view "Clipboard View" -say command_history_view "Command History View" -say event_history_view "Event History View" - -# during/after piksel: - -say auto_apply "Auto-Apply" -say font_preview "Preview:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Style:" -say font_bold "Bold" -say font_italic "Italic" -say font_family "Name:" -say font_size "Size:" -say damn "Damn!" -say console_clear "Clear Console" -say horizontal "Horizontal" -say vertical "Vertical" -say language "Language" - -# 2007: - -say no_matches "(no matches)" -say preset "preset" -say canvasgrid "Grid color" -say grid_size "Grid size" -say gridstate "Activate background grid" -say snap_grid "Snap to grid" -say viewfont "object font" -say consolefont "console font" -say keyboarddialoguefont "virtual keyboard font" -say keyboard_view "Virtual keyboard" -say log_height "Log Height" -say visual_diff "Visual diff" -say oops "Oops..." -say oops_text "This program has performed a silly operation and has been shut down." diff --git a/desiredata/src/locale/espanol.tcl b/desiredata/src/locale/espanol.tcl deleted file mode 100644 index 32a46202..00000000 --- a/desiredata/src/locale/espanol.tcl +++ /dev/null @@ -1,526 +0,0 @@ -#!/usr/bin/env tclsh -# Español translations for PureData -# $Id: espanol.tcl,v 1.1.2.3.2.1 2006-12-05 04:51:47 matju Exp $ -# translated by Mario Mora (makro) & Ramiro Cosentino (rama) - -### Menus - -say file "Archivo" - say new_file "Nuevo Archivo" - say open_file "Abrir Archivo..." - say pdrc_editor "Editor .pdrc" - say send_message "Enviar Mensaje..." - say paths "Rutas..." - say close "Cerrar" - say save "Guardar" - say save_as "Guardar Como..." - say print "Imprimir..." - say quit "Salir" - - say canvasnew_file "Archivo Nuevo" - say canvasopen_file "Abrir Archivo..." - say canvassave "Guardar" - say canvassave_as "Guardar como..." - say clientpdrc_editor "Editor .pdrc " - say clientddrc_editor "Editor .ddrc " - say canvasclose "Cerrar" - say canvasquit "Salir" - -say edit "Edición" - say undo "Deshacer" - say redo "Rehacer" - say cut "Cortar" - say copy "Copiar" - say paste "Pegar" - say duplicate "Duplicar" - say select_all "Seleccionar Todo" - say text_editor "Editor de Texto..." - say tidy_up "Ordenar" - say edit_mode "Modo Edición" - say editmodeswitch "Modo edicion/ejecucion" - - say canvascut "Cortar" - say canvascopy "Copiar" - say canvasundo "Deshacer" - say canvasredo "Rehacer" - say canvaspaste "Pegar" - say canvasselect_all "Seleccionar todo" - say canvaseditmodeswitch "Modo edicion/ejecucion" - -say view "Ver" - say reload "Recargar" - say redraw "Refrescar" - - say canvasreload "Recargar" - say canvasredraw "Refrescar" - -say find "Buscar" - say find_again "Buscar Nuevamente" - say find_last_error "Buscar Ultimo Error" - -say canvasfind "Buscar" - say canvasfind_again "Buscar Nuevamente" - -# contents of Put menu is Phase 5C -say put "Poner" - say Object "Objeto" - say Message "Mensaje" - say Number "Numero" - say Symbol "Simbolo" - say Comment "Comentario" - say Canvas "Canvas";# - say Array "Deposito";#array as "desposito"? - - say canvasobject "Objeto" - say canvasmessage "Mensaje" - say canvasnumber "Numero" - say canvassymbol "Simbolo" - say canvascomment "Comentario" - say canvasbang "Bang";# - say canvastoggle "Interruptor";# toggle as "interruptor"? - say canvasnumber2 "Numero2" - say canvasvslider "Deslizador Vertical";#slider as "deslizador"?? - say canvashslider "Deslizador Horizontal" - say canvasvradio "Rango Vertical";#radio as "Rango"?? - say canvashradio "Rango Horizontal";# - say canvascanvas "Canvas";# - say canvasarray "Array";# - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Probar Audio y MIDI" - say load_meter "Medidor de Carga" - - say canvasaudio_on "Audio ON" - say canvasaudio_off "Audio OFF" - say clienttest_audio_and_midi "Probar Audio y MIDI" - say canvasload_meter "Medidor de Carga" - -say window "Ventana" - -say help "Ayuda" - say about "Acerca de..." - say pure_documentation "Pura Documentacion..." - say class_browser "Navegador de Clases..." - say canvasabout "Acerca de..." - -say properties "Propiedades" -say open "Abrir" - -### for key binding editor -say general "General" -say audio_settings "Configuracion Audio " -say midi_settings "Configuracion Midi " -say latency_meter "Medidor de Latencia" -say Pdwindow "Ventana Pd " - -say canvaspdwindow "Ventana Pd" -say canvaslatency_meter "Medidor de Latencia" -say clientaudio_settings "Configuracion Audio" -say clientmidi_settings "Configuracion Midi" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "ancho(px)" -say h "alto(px)" -say hold "tiempo de mantencion(ms)" -say break "tiempo de quiebre(ms)" -say min "valor minimo" -say max "valor maximo" -say is_log "modo" -say linear "linear" -say logarithmic "logaritmico" -say isa "inicio" -say n "numero de posibilidades" -say steady "regularidad" -say steady_no "saltar en click";# -say steady_yes "estabilizar en click";# -say snd "enviar-simbolo" -say rcv "recibir-simbolo" -say lab "etiqueta" -say ldx "etiqueta compensacion x";# -say ldy "etiqueta compensacion y";# -say fstyle "Tipografia" -say fs "Tamaño de fuente" -say bcol "Color Fondo" -say fcol "color primer plano" -say lcol "color etiqueta" -say yes "si" -say no "no" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "grafico en pariente" ;# parent?? as "pariente"?? - -say_category GAtomProperties -say width "ancho" -say lo "limite bajo" -say hi "limite alto" -say label "etiquetal" -say wherelabel "mostrar etiqueta on" -say symto "enviar simbolo" -say symfrom "recibir simbolo" - -say_category GraphProperties -say x1 "desde x" -say x2 "hacia x" -say xpix "ancho pantalla" -say y2 "desde y" -say y1 "hacia y" -say ypix "altura pantalla" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" - -say_category ArrayProperties -say name "nombre" -say n "Tamaño" - -### Main Window -say_category MainWindow -say in "in" -say out "out" -say audio "Audio" -say meters "Medidores" -say io_errors "Errores de E/S" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box";# Caja de bang? -# say Bang "Bang" -# say Toggle "Interruptor";# toggle as "interruptor"? - say tgl "Toggle Box";#Caja palanca? caja interruptora? - say nbx "Number Box (IEM)";#Caja de numeros? -# say Number2 "Numero2" - say hsl "deslizador (Horizontal)";# - say vsl "Deslizador (Vertical)";# - say hradio "Choice Box (Horizontal)";# Caja seleccionadora? - say vradio "Choice Box (Vertical)";# -# say Vradio "Rango Vertical";#radio as "rango"? -# say Hradio "Rango Horizontal";# - say cnv "Canvas (IEM)" - say dropper "Drag-and-Drop Box";#Caja agarrar y soltar? - say vu "Vumeter";# medidor VU? - - say_category GLUE - say bang "envia un mensaje de bang" - say float "guarda y recuerda un numero" - say symbol "guarda y recuerda un simbolo" - say int "guarda y recuerda un entero" - say send "envia un mensaje a un objeto nombrado" - say receive "catch sent messages" - say select "test para numeros o simbolos coincidentes" - say route "rutea mensajes de acuerdo al primer elemento" - say pack "genera mensajes compuestos" - say unpack "obtiene elementos de mensajes compuestos" - say trigger "ordena y convierte mensajes" - say spigot "conexion mensajes interrumpible" - say moses "divide un flujo de numeros" - say until "mecanismo de loop" - say print "imprime mensajes" - say makefilename "formatea un simbolo con un campo variable";# - say change "remover numeros repetidos de un flujo de datos";# - say swap "intercambiar dos numeros";# - say value "compartir valor numerico" - - say_category TIME - say delay "envia un mensaje despues de un retraso de tiempo" - say metro "envia un mensaje periodicamente" - say line "envia una serie de numeros encaminados linearmente" - say timer "medicion de intervalos de tiempo" - say cputime "medicion tiempo CPU" - say realtime "medicion tiempo real" - say pipe "linea de retraso dinamicamente creciente para numeros" - - say_category MATH - say + "sumar" - say - "sustraer" - say * "multiplicar" - say {/ div} "dividir" - say {% mod} "resto de la division" - say pow "exponencial" - say == "igual?" - say != "no igual?" - say > "mas que?" - say < "menos que?" - say >= "no menos que?" - say <= "no mas que?" - say & "bitwise conjunction (and)";#bitwise? conjuncion (y) - say | "bitwise disjunction (or)";#bitwise? conjuncion (o) - say && "conjuncion logica (y)" - say || "separacion logica (o)" - say mtof "MIDI a Hertz" - say ftom "Hertz a MIDI" - say powtodb "Watts a dB" - say dbtopow "dB a Watts" - say rmstodb "Volts a dB" - say dbtorms "dB a Volts" - say {sin cos tan atan atan2 sqrt} "trigonometria" - say log "logaritmo Euler" - say exp "exponencial Euler" - say abs "valor absoluto" - say random "aleatorio" - say max "mayor de dos numeros" - say min "menor de dos numeros" - say clip "fuerza un numero en un rango" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "entrada MIDI" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "salida MIDI" - say makenote "programa un retrasado \"note off\" mensaje correspondiente a un note-on";# - say stripnote "tira \"note off\" mensajes";# - - say_category TABLES - say tabread "lee un numero desde una tabla" - say tabread4 "lee un numero desde una tabla, con 4 puntos de interpolacion" - say tabwrite "escribe un numero a una tabla" - say soundfiler "lee y escribe tablas a archivos de audio" - - say_category MISC - say loadbang "bang en carga" - say serial "control recurso serial for NT only" - say netsend "envia mensajes sobre internet" - say netreceive "recibirlos" - say qlist "secuencia mensajes" - say textfile "convertidor de archivo a mensaje" - say openpanel "\"Abrir\" dialogo" - say savepanel "\"Guardar como\" dialogo" - say bag "sistema de numeros" - say poly "asignacion de voz polifonica" - say {key keyup} "valores numericos de teclas del teclado" - say keyname "simbolo de la tecla";# - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"};#this has to be translated too? - say max~ "supremo de señales" - say min~ "infimo de señales" - say clip~ "fuerza la señal a permanecer entre dos limites" - say q8_rsqrt~ "raiz cuadrada reciproca economica (cuidado -- 8 bits!)";# - say q8_sqrt~ "raiz cuadrada economica (cuidado -- 8 bits!)";# - say wrap~ "abrigo alrededor (parte fraccional, tipo de)";#wrap? as abrigo?? around as "alrededor"?? - say fft~ "transformada fourier discreta compleja delantero";# - say ifft~ "transformada fourier discreta compleja inversa";# - say rfft~ "transformada fourier discreta real delantero";# - say rifft~ "transformada fourier discreta real delantero";# - say framp~ "arroja una rampa para cada bloque" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (para señales)";# - } -} - -### phase 3 - -say_namespace summary { - say_category "UTILIDADES AUDIO" - say dac~ "salida audio" - say adc~ "entrada audio" - say sig~ "convierte numeros a señales de audio" - say line~ "genera rampas de audio" - say vline~ "line~ delujo" - say threshold~ "detectar umbrales de la señal" - say snapshot~ "toma muestras de una señal (reconvierte a numeros)" - say vsnapshot~ "snapshot~ delujo";# - say bang~ "envia un mensaje bang despues de cada block DSP" - say samplerate~ "obtener rango de muestreo" - say send~ "conexion señal no local con fanout";# fanout?? - say receive~ "obtener señal desde send~" - say throw~ "agrega a un bus sumador";# - say catch~ "define y lee bus sumador";# - say block~ "especifica tamaño del bloque y overlap" - say switch~ "selecciona computacion DSP on y off";# - say readsf~ "reproduce archivo de audio desde disco" - say writesf~ "graba sonido a disco" - - say_category "OSCILADORES DE AUDIO Y TABLAS" - say phasor~ "oscilador diente de sierra" - say {cos~ osc~} "oscilador coseno" - say tabwrite~ "escribe a una tabla" - say tabplay~ "reproduce desde una tabla (sin transponer)" - say tabread~ "lee tabla sin interpolacion" - say tabread4~ "lee tabla con 4 puntos de interpolacion" - say tabosc4~ "oscilador de tabla de ondas" - say tabsend~ "escribe un bloque continuamente a una tabla" - say tabreceive~ "lee un bloque continuamente desde una tabla" - - say_category "FILTROS AUDIO" - say vcf~ "filtro controlado por voltaje" - say noise~ "generador ruido blanco" - say env~ "lector envolvente" - say hip~ "filtro pasa agudos" - say lop~ "filtro pasa bajos" - say bp~ "filtro pasa banda" - say biquad~ "filtro crudo" - say samphold~ "unidad muestra y mantener";# sample as "muestra" - say print~ "imprimir uno o mas \"bloques\"" - say rpole~ "filtro crudo valor real de un polo" - say rzero~ "fitro crudo valor real de un cero" - say rzero_rev~ "[say rzero~] (tiempo-invertido)" - say cpole~ "[say rpole~] (complejo-valorado)" - say czero~ "[say rzero~] (complejo-valorado)" - say czero_rev~ "[say rzero_rev~] (complejo-valorado)" - - say_category "AUDIO DELAY" - say delwrite~ "escribir a una linea de retraso" - say delread~ "leer desde una linea de retraso" - say vd~ "leer desde una linea de retraso a un tiempo de retraso variable" - - say_category "SUBVENTANAS" - say pd "define una subventana" - say table "arsenal de numeros en una subventana" - say inlet "agrega una entrada a pd" - say outlet "agrega una salida a pd" - say inlet~ "[say entrada] (para señal)";# - say outlet~ "[say salida] (para señal)";# - - say_category "PLANTILLAS DE DATOS" - say struct "define una estructura de datos" - say {drawcurve filledcurve} "dibuja una curva" - say {drawpolygon filledpolygon} "dibuja un poligono" - say plot "trace un campo del arsenal";# - say drawnumber "imprime un valor numerico" - - say_category "ACCEDIENDO A DATOS" - say pointer "señale a un objeto que pertenece a una plantilla" - say get "obtener campos numericos" - say set "cambiar campos numericos" - say element "obtener un elemento del deposito";#array as "deposito" - say getsize "obtener el tamaño del deposito" - say setsize "cambiar el tamaño del deposito" - say append "agregar un elemento a una lista" - say sublist "obtenga un indicador en una lista que sea un elemento de otro escalar";# scalar as escalar?? some maths expert should give his opinion - say scalar "dibuje un escalar en pariente";#same - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ ahora)" - say namecanvas "" ;# what was this anyway? - say template "(use struct ahora)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "rango de muestreo" - say -audioindev "dispositivos entrada de audio" - say -audiooutdev "dispositivos salida de audio" - say -inchannels "canales entrada audio (por dispositivo, como \"2\" or \"16,8\")" - say -outchannels "numero de canales salida audio (igual)" - say -audiobuf "especificar tamaño de almacenador de audio en mseg" - say -blocksize "especificar tamaño block E/S audio en muestras por cuadro" - say -sleepgrain "especificar numero de milisegundos para suspension cuando este inactivo";# - say -nodac "suprimir salida de audio" - say -noadc "suprimir entrada de audio" - say audio_api_choice "Audio API" - say default "defecto" - say -alsa "usar ALSA audio API" - say -jack "usar JACK audio API" - say -mmio "usar MMIO audio API (por defecto para Windows)" - say -portaudio "usar ASIO audio driver (via Portaudio)" - say -oss "usar OSS audio API" - say -32bit "permitir 32 bit OSS audio (para RME Hammerfall)" - say {} "defecto" - -say section_midi "MIDI" - say -nomidiin "suprime entrada MIDI" - say -nomidiout "suprime salida MIDI" - say -midiindev "lista dispositivos midi in; e.g., \"1,3\" para primero y tercero" - say -midioutdev "lista dispositivos midi out, mismo formato" - -say section_externals "Externals" - say -path "ruta busqueda de archivo" - say -helppath "ruta busqueda archivo de ayuda" - say -lib "cargar librerias de objeto" - -say section_gui "Gooey";# what?? - say -nogui "suprime inicio de gui (precaucion)" - say -guicmd "substituye por otro programa GUI (e.g., rsh)" - say -console "lineas retroceso consola (0 = desactivar consola)" - say -look "iconos barra de botones" - say -statusbar "activar barra de status" - say -font "especificar tamaño de fuente por defecto en puntos" - -say section_other "Otro" - say -open "abrir archivo(s) en inicio" - say -verbose "impresion extra en inicio y al buscar archivos";# - say -d "nivel chequeo errores";# - say -noloadbang "desactivar el efecto de \[loadbang\]" - say -send "enviar un mensaje al inicio (despues patches estan cargados)" - say -listdev "lista dispositivos audio y MIDI al inicio" - say -realtime "usar prioridad tiempo-real (necesita privilegios de administrador)" - -say section_paths "Rutas" - -# ddrc - -say section_color "colores" - say canvas_color "canvas";# - say canvasbgedit "canvas fondo (modo edicion)" - say canvasbgrun "canvas fondo (modo ejecucion)" - say object_color "objeto" - say viewframe1 "color objeto";# objetbox as "objeto" - say viewframe2 "color objeto";# - say viewframe3 "color objeto";# - say viewframe4 "color resaltado objeto";# - say viewbg "objeto fondo" - say viewfg "objeto primer plano" - say commentbg "comentario fondo" - say commentfg "comentario primer plano" - say commentframe1 "comentario cuadro";#frame as "cuadro" - say commentframe2 "comentario cuadro" - say commentframe3 "comentario cuadro" - say viewselectframe "caja resaltada";# - say wire_color "cable";# wire as "cable" - say wirefg "color cable" - say wirefg2 "cable resaltado" - say wiredash "cable rociado" - say others_color "otros" - say inletfg "color entrada" - say outletfg "color salida" - say selrect "caja de seleccion";# selection box -say keys "teclas" -say others "otros" -say canvashairstate "Activar malla";# crosshair como "malla" -say canvashairsnap "Malla ajustada a objeto" -say canvasstatusbar "Activar barra de estatus" -say canvasbuttonbar "Activar barra de botones" - - -# phase 5A - -say cannot "no puedo" -say cancel "Cancelar" -say apply "Aplicar" -say ok "OK" -say popup_open "Abrir" -say popup_properties "Propiedades" -say popup_help "Ayuda" -say filter "Filtro: " -say how_many_object_classes "%d of %d object classes";# this has to be translated? -say do_what_i_mean "haga lo que quiero decir" -say save_changes? "Guardar cambios?" -say reset "Reiniciar" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Agregar" -say up "Arriba" -say down "Abajo" -say remove "Remover" -say lib_add "agrega el nombre tipeado en la lista" -say lib_up "intercambiar orden con libreria previa" -say lib_down "intercambiar orden con libreria proxima" -say lib_remove "remover libreria seleccionada en la lista" -say dir_add "agregar una carpeta usando un cuadro de dialogo" -say dir_up "intercambiar orden con carpeta previa" -say dir_down "intercambiar orden con carpeta proxima" -say dir_remove "remover carpeta seleccionada en la lista" - - -### Other - - - diff --git a/desiredata/src/locale/euskara.tcl b/desiredata/src/locale/euskara.tcl deleted file mode 100644 index 9a27d1f5..00000000 --- a/desiredata/src/locale/euskara.tcl +++ /dev/null @@ -1,554 +0,0 @@ -#!/usr/bin/env tclsh -# Basque translations for PureData -# translated by Ibon Rodriguez Garcia -### Menus - -say file "Fitxategia" - say new_file "Berria" - say open_file "Ireki..." - say server_prefs "Zerbitzari Hobespenak..." - say client_prefs "Bezero Hobespenak..." - say send_message "Mezua Bidali..." - say paths "Bide Izena..." - say close "Itxi" - say save "Gorde" - say save_as "Gorde Honela..." - say print "Inprimatu..." - say quit "Irten" - - say canvasnew_file "Berria" - say canvasopen_file "Ireki..." - say canvassave "Gorde" - say canvassave_as "Gorde Honela..." - say clientpdrc_editor ".pdrc Editorea" - say clientddrc_editor ".ddrc Editorea" - say canvasclose "Itxi" - say canvasquit "Irten" - -say edit "Editatu" - say undo "Desegin" - say redo "Berregin" - say cut "Ebaki" - say copy "Kopiatu" - say paste "Itsatsi" - say duplicate "Bikoiztu" - say select_all "Hautatu Dena" - say text_editor "Testu Editorea..." - say font "Letra Tipoa" - say tidy_up "Doitu" - say edit_mode "Edizio Modua" - say editmodeswitch "Edizio/Exekuzio modua" - - say canvascut "Ebaki" - say canvascopy "Kopiatu" - say canvasundo "Desegin" - say canvasredo "Berregin" - say canvaspaste "Itsatsi" - say canvasduplicate "Bikoiztu" - say canvasselect_all "Hautatu Dena" - say canvaseditmodeswitch "Edizio/Rxekuzio Modua" - -say view "Ikusi" - say reload "Berriz Kargatu" - say redraw "Eguneratu" - - say canvasreload "Berriz Kargatu" - say canvasredraw "Eguneratu" - -say find "Bilatu" - say find_again "Bilatu Berriro" - say find_last_error "Bilatu Azken Errorea" - say string "Bilatu Katea" -say canvasfind "Bilatu" - say canvasfind_again "Bilatu Berriro" - -# contents of Put menu is Phase 5C -say put "Jarri" - say Object "Objektua" - say Message "Mezua" - say Number "Zenbakia" - say Symbol "Ikurra" - say Comment "Iruzkina" - say Bang "Bang" - say Toggle "Konmutagailua" - say Number2 "2 Zenbakia" - say Vslider "Graduatzaile Bertikala" - say Hslider "Graduatzaile Horizontala" - say Vradio "Maila Bertikala" - say Hradio "Maila Horizontala" - say Canvas "Canvas" - say Array "Taula" - - say canvasobject "Objektua" - say canvasmessage "Mezua" - say canvasnumber "Zenbakia" - say canvassymbol "Ikurra" - say canvascomment "Iruzkina" - say canvasbang "Bang" - say canvastoggle "Konmutagailua" - say canvasnumber2 "2 Zenbakia" - say canvasvslider "Graduatzaile Bertikala" - say canvashslider "Graduatzaile Horizontala" - say canvasvradio "Maila Bertikala" - say canvashradio "Maila Horizontala" - say canvascanvas "Canvas" - say canvasarray "Taula" - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Probatu Audio eta MIDI" - say load_meter "Kargatu Neurgailua" - - say canvasaudio_on "Audio ON" - say canvasaudio_off "Audio OFF" - say clienttest_audio_and_midi "Probatu Audio eta MIDI" - say canvasload_meter "Kargatu Neurgailua" - -say window "Leihoa" - -say help "Laguntza" - say about "...(r)i buruz" - say pure_documentation "Dokumentazio Hutsa..." - say class_browser "Klase Arakatzailea..." - - say canvasabout "...(r)i buruz" - -say properties "Propietateak" -say open "Ireki" - -### for key binding editor -say general "Nagusia" -say audio_settings "Audio Ezarpenak" -say midi_settings "Midi Ezarpenak" -say latency_meter "Latentzia Neurgailua" -say Pdwindow "Pd Leihoa" - -say canvaspdwindow "Pd Leihoa" -say canvaslatency_meter "Latentzia Neurgailua" -say clientaudio_settings "Audio Ezarpenak" -say clientmidi_settings "Midi Ezarpenak" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "Zabalera(px)" -say h "Garaiera(px)" -say hold "Euste Denbora(ms)" -say break "Eten Denbora(ms)" -say min "Gutxienezko Balioa" -say max "Gehienezko Balioa" -say is_log "Modua" -say linear "Lineala" -say logarithmic "Logaritmikoa" -say isa "Hasi" -say n "Aukera Kopurua" -say steady "Erregulartasuna" -say steady_no "Klik egitean jauzi" -say steady_yes "Klik Egitean Finkatu" -say snd "Bidaltze Ikurra" -say rcv "Jasotze Ikurra" -say lab "Etiketa" -say ldx "Desplazatu x Etiketa" -say ldy "Desplazatu y Etiketa" -say fstyle "Letra Tipoa" -say fs "Letra Tamaina" -say bcol "Atzeko Planoaren Kolorea" -say fcol "Aurreko Planoaren Kolorea" -say lcol "Etiketaren Kolorea" -say yes "Bai" -say no "Ez" -say courier "Courier (idazmakina)" -say helvetica "Helvetica (sansserif)" -say times "Times (serif)" -say coords "Grafikoa Nagusian" - -say_category GAtomProperties -say width "Zabalera" -say lo "Beheko Muga" -say hi "Goiko Muga" -say label "Etiketa" -say wherelabel "Erakutsi On Etiketa" -say symto "Bidali Ikurra" -say symfrom "Jaso Ikurra" - -say_category GraphProperties -say x1 "x(e)tik" -say x2 "x(e)ra" -say xpix "Pantailaren Zabalera" -say y2 "y(e)tik" -say y1 "y(e)ra" -say ypix "Pantailaren Garaiera" - -say_category CanvasProperties -#say xscale "X Unitate/px" -#say yscale "Y Unitate/px" -say gop "Grafikoa Nagusian" -say xmargin "xmarjina" -say ymargin "ymarjina" -say height "Garaiera" -say_category ArrayProperties -say name "Izena" -say n "Tamaina" -say xfrom "x(e)tiko tartea" -say xto "x(e)rako tartea" -say yfrom "y(e)tiko tartea" -say yto "y(e)rako tartea" - - -say_category MainWindow -say in "in" -say out "out" -say audio "Audio" -say meters "Neurgailuak" -say io_errors "IO Akatsak" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Kutxa" - say tgl "Toggle Kutxa" - say nbx "Zenbaki Kutxa (IEM)" - say hsl "Graduatzailea (Horizontala)" - say vsl "Graduatzailea (Bertikala)" - say hradio "Aukera Kutxa (Horizontala)" - say vradio "Aukera Kutxa (Bertikala)" - say cnv "Canvas (IEM)" - say dropper "Arrastatu eta Jaregin Kutxa" - say vu "Vumeter" - - say_category GLUE - say bang "Bang Mezua Erakutsi" - say float "Zenbaki Bat Gorde eta Gogoratu" - say symbol "Ikur Bat Gorde eta Gogoratu" - say int "Osoko Bat Gorde eta Gogoratu" - say send "Mezu Bat Bidali Objektu Izendun Bati" - say receive "Bidalitako Mezuak Jaso" - say select "Pareko Zenbaki edo Ikurrak Aztertu" - say route "Lehenengo Elementuarekin Bat Datozen Mezuak Bideratu" - say pack "Mezu Konposatuak Egin" - say unpack "MEzu Konposatuetako Elementuak Jaso" - say trigger "Mezuak Sekuentziatu eta Bihurtu" - say spigot "Mezuen Konexio Etengarria" - say moses "Zenbakizko Transmisioa Zatitu" - say until "Begiztatze Mekanismoa" - say print "Inprimatu Mezuak" - say makefilename "Ikur Bat Formateatu Eremu Aldakor Batekin" - say change "Ezabatu Transmisio Batetik Errepikatutako Zenbakiak" - say swap "Trukatu Bi Zenbaki" - say value "Zenbakizko Balioa Partekatu" - - say_category TIME - say delay "Bidali Mezua Atzerapen Denbora eta Gero" - say metro "Bidali Mezua Aldizka" - say line "Bidali Linealki Mailakatutako Zenbaki Saila" - say timer "Neurtu Denbora Tartea" - say cputime "Neurtu CPU Denbora" - say realtime "Neurtu Denbora Erreala" - say pipe "Zenbakientzako Dinamikoki Hazkorra Den Atzerapen Linea" - - say_category MATH - say + "Gehitu" - say - "Kendu" - say * "Biderkatu" - say {/ div} "Zatitu" - say {% mod} "Zatiketaren Hondarra" - say pow "exponentziala" - say == "Berdin?" - say != "Ezberdin?" - say > "baino Gehiago?" - say < "baino Gutxiago?" - say >= "baino Gutxiago Ez?" - say <= "baino Gehiago Ez?" - say & "bitwise konjuntzioa (eta)" - say | "bitwise disjuntzioa (edo)" - say && "konjuntzio logikoa (eta)" - say || "disjuntzio logikoa (edo)" - say mtof "MIDItik Hertzetara" - say ftom "Hertzetatik MIDIra" - say powtodb "Wattetatik dBtara" - say dbtopow "dBtatik to Wattetara" - say rmstodb "Voltetatik dBetara" - say dbtorms "dBetatik Voltetara" - say {sin cos tan atan atan2 sqrt} "trigonometria" - say log "Euler logaritmoa" - say exp "Euler exponentziala" - say abs "balio absolutua" - say random "ausaz" - say max "Bi zenbakitan handiena" - say min "Bi zenbakitan handiena" - say clip "Behartu Zenbaki Bat Bitarte Batera" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI sarrera" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI irteera" - say makenote "antolatu note-on bati dagokion \"note off\" mezu atzeratu bat" - say stripnote "Kendu \"note off\" mezuak" - - say_category TABLES - say tabread "Irakurri zenbaki bat taula batetik" - say tabread4 "Irakurri zenbaki bat taula batetik, 4 interpolazio-punturekin" - say tabwrite "Idatzi Zenbaki Bat Taula Batean" - say soundfiler "Irakurri eta Idatzi Taulak Soinu Fitxategiei" - - say_category MISC - say loadbang "Bang Kargatu" - say serial "Serieko Atakaren Kontrolatzailea, NTrako soilik" - say netsend "Bidali Mezuak Interneten Gainetik" - say netreceive "Jaso Mezuak Interneten Gainetik" - say qlist "Mezu Sekuentziadorea" - say textfile "Bihurtu fitxategia mezu" - say openpanel "\"zabaldu\" Elkarrizketa" - say savepanel "\"Gorde Honela\" Elkarrizketa" - say bag "Zenbaki Multzoa" - say poly "Ahots Polifonikoaren Esleipena" - say {key keyup} "Teklaturako Zenbakizko Teklen Balioak" - say keyname "Tekla Izen Sinbolikoa" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "Seinalearen Gehienezko Balioa" - say min~ "Seinalearen Gutxienezko Balioa" - say clip~ "Behartu Seinalea Bi Mugen Artean Egotera" - say q8_rsqrt~ "Elkarrekiko Erro Karratu Ekonomikoa (Kontuz -- 8 bit!)" - say q8_sqrt~ "Erro Karratu Ekonomikoa (Kontuz -- 8 bit!)" - say wrap~ "Wraparound (Alde Zatikiar Mota)" - say fft~ "Aurreko Fourier-en transformatu Diskretu Konplexua" - say ifft~ "Alderantzizko Fourier-en transformatu Diskretu Konplexua" - say rfft~ "Aurreko Fourier-en transformatu Diskretu Erreala" - say rifft~ "Alderantzizko Fourier-en transformatu Diskretu Erreala" - say framp~ "Atera arrapala bat bloke bakoitzarentzat" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (Seinalearentzat)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio irteera" - say adc~ "audio sarrera" - say sig~ "Bihurtu Zenbakiak Audio Seinale" - say line~ "Sortu Audio Arrapalak" - say vline~ "Luxuzko linea~" - say threshold~ "Antzeman Seinalearen Atalaseak" - say snapshot~ "Lagindu seinale bat (Bihurtu Zenbaki)" - say vsnapshot~ "Luxuzko Argazkia~" - say bang~ "Badili Bang Mezu Bat DSP block Bakoitzaren Ostean" - say samplerate~ "Lortu Laginaren Maiztasuna" - say send~ "Konektatu Seinale Ez-Lokal Bat Banagune Batekin" - say receive~ "Lortu Seinatea send~etik" - say throw~ "Gehitu Summing Bus Batera" - say catch~ "Definitu eta Irakurri Summing Bus Bat" - say block~ "Zehaztu Blokearen Tamaina eta Teilakapena" - say switch~ "Piztu eta Itzali DSP kalkulagailua" - say readsf~ "Erreproduzitu Soinu Fitxategia Diskotik" - say writesf~ "Grabatu Soinua Diskoan" - - say_category "AUDIO OSZILADOREAK ETA TAULAK" - say phasor~ "Zerra Hortz Motako Osziladorea" - say {cos~ osc~} "Kosinu Osziladorea" - say tabwrite~ "Idatzi Taula Batean" - say tabplay~ "Erreproduzitu Taula Batetik (transposiziorik gabe)" - say tabread~ "Irakurri Interpolazio Gabeko Taula" - say tabread4~ "Irakurri 4 Interpolazio Puntuko Taula" - say tabosc4~ "Uhin Taulako Osziladorea" - say tabsend~ "Idatzi Bloke Bat Taula Batera Etengabe" - say tabreceive~ "Irakurri Bloke Bat Taula Batetik Etengabe" - - say_category "AUDIO IRAGAZKIAK" - say vcf~ "Tentsio Kontrolatuko Iragazkia" - say noise~ "Zarata Zuri Sortzailea" - say env~ "Inguratze Jarraitzailea" - say hip~ "Goi Paseko Iragazkia" - say lop~ "Behe Paseko Iragazkia" - say bp~ "Banda Paseko Iragazkia" - say biquad~ "Iragazki Gordina" - say samphold~ "Lagindu eta blokeatu Unitatea" - say print~ "Inprimatu \"Blocks\" Bat Edo Gehiago" - say rpole~ "Polo Bakarreko Balio Errealeko Iragazki Gordina" - say rzero~ "Zero-Bat Balio Errealeko Iragazki Gordina" - say rzero_rev~ "[say rzero~] (Denbora Alderantzizkatua)" - say cpole~ "[say rpole~] (Konplexua-Zenbatetsia)" - say czero~ "[say rzero~] (Konplexua-Zenbatetsia)" - say czero_rev~ "[say rzero_rev~] (Konplexua-Zenbatetsia)" - - say_category "AUDIO ATZERAPENA" - say delwrite~ "Idatzi Atzerapen Lerro Batean" - say delread~ "Irakurri Atzerapen Lerro Batetik" - say vd~ "Irakurri Atzerapen Lerro Batetik Atzerapen Lerro Aldakor Batean" - - say_category "AZPILEIHOAK" - say pd "Azpileiho Bat Definitu" - say table "Zenbaki Taula Azpileiho Batean" - say inlet "Gehitu Sarrera Bat PD Batean" - say outlet "Gehitu Irteera Bat PD Batean" - say inlet~ "[say inlet] (seinalearentzat)" - say outlet~ "[say outlet] (seinalearentzat)" - - say_category "DATU TXANTILIOIAK" - say struct "Definitu Datu Egitura Bat" - say {drawcurve filledcurve} "Marraztu Kurba Bat" - say {drawpolygon filledpolygon} "Marraztu Poligono Bat" - say plot "Trazatu Taula Bateko Eremu Bat" - say drawnumber "Inprimatu Zenbakizko Balio Bat" - - say_category "DATUETARAKO SARBIDEA" - say pointer "Seinalatu Txantilioi Batekoa Den Elementu Bat" - say get "Lortu Zenbakizko Eremuak" - say set "Zenbakizko Eremuak Aldatu" - say element "Lortu Taula Bateko Elementu Bat" - say getsize "Lortu Taula Baten Tamaina" - say setsize "Aldatu Taula Baten Tamaina" - say append "Gehitu Elementu Bat Zerrenda Batera" - say sublist "Lortu Erakusle Bat Beste Eskalar Bateko Elementua Den Zerrenda Batean" - say scalar "Marraztu Eskalar Bat Nagusian" - - say_category "ZAHARKITUA" - say scope~ "(Erabili tabwrite~ Orain)" - say namecanvas "" ;# what was this anyway? - say template "(Erabili struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "LAgin-Maiztasuna" - say -audioindev "Audio Sarrerako Gailuak" - say -audiooutdev "Audio Irteerako Gailuak" - say -inchannels "Audio Sarrerako Kanalak (Gailuko, adib. \"2\" edo \"16,8\")" - say -outchannels "Audio Irteerako Kanalen Kopurua (Berbera)" - say -audiobuf "Zehaztu Audio Bufferraren Tamaina Milisegundotan" - say -blocksize "Zehaztu S/I Audio Blokeak Lagin Markoetan" - say -sleepgrain "Zehaztu Lotarako Milisegundo Kopurua Inaktibo Dagoenean" - say -nodac "Ezabatu Audio Irteera" - say -noadc "Ezabatu Audio Sarrera" - say audio_api_choice "Audio API" - say default "Lehenetsia" - say -alsa "Erabili ALSA audio API" - say -jack "Erabili JACK audio API" - say -mmio "Erabili MMIO audio API (Windowserako Lehenetsia)" - say -portaudio "Erabili ASIO audio driver (Portaudio bidez)" - say -oss "Erabili OSS audio API" - say -32bit "Baimendu 32 bit OSS audio (RME Hammerfallerako)" - say {} "Lehenetsia" - -say section_midi "MIDI" - say -nomidiin "MIDI Sarrera Kendu" - say -nomidiout "MIDI Irteera Kendu" - say -midiindev "midi in Gailuen Zerrenda; adib., \"1,3\" lehenengo eta hirugarrenerako" - say -midioutdev "midi out Gailuen Zerrenda, Formatu Berbera" - -say section_externals "Kanpokoak" - say -path "Fitxategiak Topatzeko Bidea" - say -helppath "Laguntza Fitxategiak Topatzeko Bidea" - say -lib "Kargatu Objektuen Liburutegiak" - -say section_gui "Gooey" - say -nogui "Desgaitu GUI Hastea (Kontuz)" - say -guicmd "Ordeztu Beste GUI Programa (adib., rsh)" - say -console "Kontsolaren Atzerapen Lineak (0 = Desgaitu Kontsola)" - say -look "Botoi Barraren Ikonoak" - say -statusbar "Gaitu Egoera Barra" - say -font "Zehaztu LEtra Mota Lehenetsia Puntutan" - -say section_other "Bestelakoak" - say -open "Ireki Fitxategia(k) Hasieran" - say -verbose "Inprimatze Gehigarria Hasieran eta Fitxategiak Bilatzean" - say -d "Arazte Maila" - say -noloadbang "Desgaitu \[loadbang\] Efektua" - say -send "Bidali Mezu Bat Hasieran (Adabakiak Kargatu Eta Gero)" - say -listdev "Zerrendatu Audio eta MIDI Gailuak Hasieraren Gainetik" - say -realtime "Erabili Denbora Errealeko Lehenespena (sustrai-pribilegioa behar du)" - -say section_paths "Ibilbideak" - -# phase 4B: ddrc (keyword names not finalized!) - -say section_color "Koloreak" - say canvas_color "canvas" - say canvasbgedit "canvas Atzeko Planoa (edizio-modua)" - say canvasbgrun "canvas Atzeko Planoa (exekutatze-modua)" - say object_color "objektua" - say viewframe1 "Objektu Kutxaren Kolorea" - say viewframe2 "Objektu Kutxaren Kolorea" - say viewframe3 "Objektu Kutxaren Kolorea" - say viewframe4 "Objektu Kutxa Nabarmentzeko Kolorea" - say viewbg "Objektuaren Atzeko Planoa" - say viewfg "Objektuaren Aurreko Planoa" - say commentbg "Iruzkinaren Atzeko Planoa" - say commentfg "Iruzkinaren Aurreko Planoa" - say commentframe1 "Iruzkin Markoa" - say commentframe2 "Iruzkin Markoa" - say commentframe3 "Iruzkin Markoa" - say viewselectframe "Nabarmendu Kutxa" - say wire_color "Haria" - say wirefg "Hariaren Kolorea" - say wirefg2 "Nabarmendu Haria" - say wiredspfg "dsp Hari Kolorea" - say futurewiredash "Hari (Marratu) Berria" - say others_color "Bestelakoak" - say boxinletfg "Sarrera Kolorea" - say boxoutletfg "Irteera Kolorea" - say selrectrect "Hautapen Kutxa" -say keys "Teklak" -say others "Bestelakoak" -say canvashairstate "Gaitu Amarauna" -say canvashairsnap "Doitu Amarauna Objektuari" -say canvasstatusbar "Gaitu Egoera Barra" -say canvasbuttonbar "Gaitu Botoi Barra" -say wirewirearrow "Gezia Lotu" -say viewtooltip "Argibidea" -say canvasinsert_object "Txertatu Objektua" -say canvaschain_object "Kateatu Objektua" -say canvasclear_wires "Garbitu Hariak" -say canvasauto_wire "Ezabatu Objektua" -# phase 5A - -say cannot "Ezin" -say cancel "Ezeztatu" -say apply "Aplikatu" -say ok "Ados" -say popup_open "Ireki" -say popup_insert "Txertatu" -say popup_properties "Propietateak" -say popup_clear_wires "Garbitu Hariak" -say popup_auto_wire "Ezabatu Objektua" -say popup_help "Laguntza" -say filter "Iragazkia : " -say how_many_object_classes "Objektu Klaseen %d(r)en %d" -say do_what_i_mean "Egin Esan Nahi Dudana" -say save_changes? "Aldaketak Gorde?" -say reset "Garbitu" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Gehitu" -say up "Gora" -say down "Behera" -say remove "Ezabatu" -say lib_add "Gehitu Idatzitako Izena Zerrendara" -say lib_up "Trukatu Agindua Aurreko Liburutegiarekin" -say lib_down "Trukatu Agindua Hurrengo Liburutegiarekin" -say lib_remove "Ezabatu Zerrendan Aurkeratutako Liburutegia" -say dir_add "Gehitu Karpeta Bat Elkarrizketa Fitxategia Erabiliz" -say dir_up "Trukatu Agindua Aurreko Karpetarekin" -say dir_down "Trukatu Agindua Hurrengo Karpetarekin" -say dir_remove "Ezabatu Zerrendan Aukeratutako Karpeta" -say client_class_tree "Bezero Klaseen Zuhaitza" -say clipboard_view "Ikusi Arbela" -say history_view "Ikusi Historia" - -# during/after piksel: - -say auto_apply "Auto-Aplikatu" -say font_preview "Aurrebista:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Estiloa:" -say font_bold "Lodia" -say font_italic "Etzana" -say font_family "Izena:" -say font_size "Tamaina:" -say damn "Arraioa!" diff --git a/desiredata/src/locale/francais.tcl b/desiredata/src/locale/francais.tcl deleted file mode 100644 index f27e13fe..00000000 --- a/desiredata/src/locale/francais.tcl +++ /dev/null @@ -1,563 +0,0 @@ -#!/usr/bin/env tclsh -# French (franais) translations for PureData -# $Id: francais.tcl,v 1.1.2.5.2.8 2007-07-11 19:21:32 matju Exp $ -# by Patrice Colet - -say file "Fichier" - say new_file "Nouveau Fichier" - say open_file "Ouvrir Fichier..." - say server_prefs "Prfrences serveur..." - say client_prefs "Prfrences client..." - say send_message "Envoyer message..." - say paths "Chemins..." - say close "Fermer" - say save "Sauvegarder" - say save_as "Sauvegarder sous..." - say print "Imprimer..." - say quit "Quitter" - - say canvasnew_file "Nouveau Fichier" - say canvasopen_file "Ouvrir Fichier..." - say canvassave "Sauver" - say canvassave_as "Sauver sous..." - #say clientpdrc_editor "diteur de .pdrc" - #say clientddrc_editor "diteur de .ddrc" - say canvasclose "Fermer" - say canvasquit "Quitter" - -say edit "dition" - say undo "Dfaire" - say redo "Refaire" - say cut "Couper" - say copy "Copier" - say paste "Coller" - say duplicate "Dupliquer" - say select_all "Slectionner tout" - say text_editor "diteur de texte..." - say font "Police" - say tidy_up "Aligner" - say edit_mode "Mode d'dition" - say editmodeswitch "Mode dition/execution" - - say canvascut "Couper" - say canvascopy "Copier" - say canvasundo "Annuler" - say canvasredo "Rtablir" - say canvaspaste "Coller" - say canvasduplicate "Dupliquer" - say canvasselect_all "Slectionner Tout" - say canvaseditmodeswitch "Mode dition/execution" - -say view "Vue" - say reload "Recharger" - say redraw "Redessiner" - - say canvasreload "Recharger" - say canvasredraw "Redessiner" - - say find "Trouver" - say find_again "Trouver encore" - say find_last_error "Trouver la dernire erreur" - say string "Trouver chane de charactres" - say canvasfind "Trouver" - say canvasfind_again "Trouver encore" - -say put "Mettre" - say Object "Objet" - say Message "Message" - say Number "Nombre" - say Symbol "Symbole" - say Comment "Commentaire" - say Array "Tableau" - -say media "Mdia" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Tester l'audio et le MIDI" - say load_meter "CPU-mtre" - - say canvasaudio_on "Audio ON" - say canvasaudio_off "Audio OFF" - say clienttest_audio_and_midi "Tester l'audio et le MIDI" - say canvasload_meter "CPU-mtre" - -say window "Fentre" - -say help "Aide" - say about " propos de..." - say pure_documentation "Pure Documentation..." - say class_browser "Explorateur de classes..." - - say canvasabout " propos de..." - - say properties "Proprits" -say open "Ouvrir" - -### for key binding editor -say general "Gnerale" -say audio_settings "Paramtres audio" -say midi_settings "Paramtres MIDI" -say latency_meter "Latence-mtre" -say Pdwindow "Console PD" - -say canvaspdwindow "Console PD" -say canvaslatency_meter "Latence-mtre" -say clientaudio_settings "Paramtres audio" -say clientmidi_settings "Paramtres audio" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "Largeur(px)" -say h "Hauteur(px)" -say hold "Temps de maintien(ms)" -say break "temps d'arrt(ms)" -say min "Valeur minimum" -say max "Valeur maximum" -say is_log "Mode" -say linear "Lineaire" -say logarithmic "Logarithmique" -say isa "Initialisation" -say n "Nombre de choix" -say steady "Rgularit" -say steady_no "Caler sur le clic" -say steady_yes "Suivre le clic" -say snd "symbole d'envoi" -say rcv "symbole de reception" -say lab "tiquette" -say ldx "Dcalage x de l'tiquette" -say ldy "Dcalage y de l'tiquette" -say fstyle "Style de police" -say fs "Taille de la police" -say bcol "Couleur d'arrire plan" -say fcol "Couleur du premier plan" -say lcol "couleur de l'tiquette" -say yes "Oui" -say no "Non" -say courier "courrier (typewriter)" -say helvetica "helvetique (sansserif)" -say times "times (serif)" -say coords "Afficher sur le parent" - -say_category "Proprits du Gatom" -say width "Largeur" -say lo "Plus Petite Limite" -say hi "Plus Grande Limite" -say label "tiquette" -say wherelabel "O montrer l'tiquette" -say symto "Symbole d'envoi" -say symfrom "Symbole de reception" - -say_category "Proprits du graphe" -say x1 "Depuis x" -say x2 "Vers x" -say xpix "Largeur d'cran" -say y2 "Depuis y" -say y1 "Vers y" -say ypix "Hauteur d'cran" - -say_category "Proprits du canevas" -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "Afficher sur le parent" -say xmargin "Marge x" -say ymargin "Marge y" -say height "Hauteur" -say_category MainWindow -say name "Nom" -say n "Taille" -say xfrom "tendue sur x depuis" -say xto "tendue sur x jusque" -say yfrom "tendue sur y depuis" -say yto "tendue sur x jusque" - - -### Main Window - -say in "entre" -say out "sortie" -say audio "Audio" -say meters "Niveaux" -say io_errors "Erreurs d'E/S" -say cannot "ne peut" - -say_category Autre -say_namespace summary { - say_category IEMGUI -# say bng "Dclencheur" - say bng "Bang" - say tgl "Interrupteur" - say nbx "Boite de Nombre (IEM)" -# say Number2 "Nombre2" - say hsl "Glissire (Horizontale)" - say vsl "Glissire (Verticale)" -# say hsl "Slecteur (Horizontal)" - say hradio "Bote De Selection (Horizontale)" - say vradio "Bote De Selection (Verticale)" -# say cnv "Illustration (IEM)" - say cnv "Canevas (IEM)" - say dropper "Boite Pour Glisser-Dposer" - say vu "Vu-mtre" - - say_category GLUE - say bang "Envoyer un Dclenchement" - say float "Stocker et rapeller un nombre flottant" - say symbol "Stocker et rapeller un symbole" - say int "Stocker et rapeller un nombre entier" - say send "Envoyer un message vers un objet dfini" - say receive "Recevoir un message envoy" - say select "Tester la reception d'un chiffre ou d'un symbole" - say route "Diriger un message en fonction du premier lement" - say pack "Empaqueter un message" - say unpack "Dsempaqueter un message" - say trigger "Mettre en squence un message" - say spigot "Interrupteur de message" - say moses "partitionner un flot numrique en deux (mose)" - say until "Mchanisme de bouclage" - say print "Afficher un message dans la console" - say makefilename "Formater un symbole avec un champ variable" - say change "Supprimer les rpetitions d'un flot" - say swap "Permuter deux chiffres" - say value "Partager une valeur numrique" - - say_category TEMPS - say delay "Envoyer un dclenchement aprs un dlai" - say metro "Envoyer un dclenchement priodiquement" - say line "Envoyer linairement une serie de nombres " - say timer "Mesurer l'intervalle de temps" - say cputime "Mesurer le temps de calcul" - say realtime "Mesurer le temps rel" - say pipe "Dlai dynamique pour les nombres" - - say_category MATH - say + "Ajouter" - say - "Soustraire" - say * "Multiplier" - say {/ div} "Diviser" - say {% mod} "Retenue d'une Division" - say pow "Exponentiel" - say == "gal?" - say != "Different?" - say > "Plus Grand Que?" - say < "Plus Petit Que?" - say >= "Plus Grand ou gal ?" - say <= "Plus Petit ou gal ?" - say & "et logique (and)" - say | "ou logique (or)" - say && "et logique (and)" - say || "ou logique (or)" - say mtof "MIDI vers Hertz" - say ftom "Hertz vers MIDI" - say powtodb "Watts vers dB" - say dbtopow "dB vers Watts" - say rmstodb "Volts vers dB" - say dbtorms "dB vers Volts" - say {sin cos tan atan atan2 sqrt} "Trigonometrie" - say log "Logarithme d'Euler" - say exp "Exponentiel d'Euler" - say abs "Valeur absolue" - say random "Alatoire" - say max "Le plus grand des deux nombres" - say min "Le plus petit des deux nombres" - say clip "Forcer un nombre entre deux valeurs" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "Entre MIDI" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "Sortie MIDI" - say makenote "Programmer un message dcal \"note off\" correspondant un note-on" - say stripnote "ignorer les messages \"note off\" " - - say_category TABLEAUX - say tabread "Lire Un Nombre Depuis Une Tableau" - say tabread4 "Lire Un Nombre Depuis Une Tableau, avec 4 points d'interpolation" - say tabwrite "Ecrire un nombre dans une tableau" - say soundfiler "Lire et crire un tableau vers un fichier" - - say_category MISC - say loadbang "Dclencher au lancement" - say serial "Contrle du port serie pour NT seulement" - say netsend "Envoyer messages travers internet" - say netreceive "Recevoir messages travers internet" - say qlist "Squenceur de messages" - say textfile "Convertisseur de fichier vers messages" - say openpanel "dialogue \"Ouvrir\" " - say savepanel " dialogue \"Sauver sous\"" - say bag "Srie de nombres" - say poly "Allocation de voix polyphoniques" - say {key keyup} "Valeurs Numriques Du Clavier" - say keyname "Nom symbolique d'une touche de clavier" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "Valeur maximale de signaux" - say min~ "Valeur minimale de signaux" - say clip~ "Contraint le signal rester entre deux valeurs" - say q8_rsqrt~ "Racine carre rciproque (attention -- 8 bits!)" - say q8_sqrt~ "Racine carre (attention -- 8 bits!)" - say wrap~ "Envelopper autour (Genre De partie fractionnelle)" - say fft~ "Transformation discrte de Fourier" - say ifft~ "Partie complexe de la transforme de fourier" - say rfft~ "Partie relle de la transforme de fourier" - say rifft~ "Inverse de la Partie relle de la transforme de fourier" - say framp~ "Donne la rampe pour chaque block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (pour les signaux)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "Sortie audio" - say adc~ "Entre audio" - say sig~ "Conversion d'un nombre vers un signal" - say line~ "Gnre une rampe audio" - say vline~ "line~ de luxe" - say threshold~ "Dtecte les seuils d'un signal" - say snapshot~ "chantillonne un signal (converti en nombres)" - say vsnapshot~ "snapshot~ de luxe" - say bang~ "Envoie un signal de dclenchement aprs chaque block DSP" - say samplerate~ "Obtient la frquence d'chantillonnage" - say send~ "Connection d'un signal non-local avec un transcepteur" #fanout=transceiver=transcepteur - say receive~ "Reoit le signal venant de send~" - say throw~ "Additionne le Signal un bus" - say catch~ "Dfinit et lit la somme des signaux dans un bus" - say block~ "spcifie la taille et la convergence d'un block" - say switch~ "Permutation marche/arrt du calcul DSP" - say readsf~ "Lit un fichier audio depuis le disque" - say writesf~ "Enregistre un fichier audio sur le disque" - - say_category "OSCILLATEURS AUDIO ET TABLEAUX" - say phasor~ "Oscillateur en Dent De Scie" - say {cos~ osc~} "oscillateur cosinusodal" - say tabwrite~ "crit dans un tableau" - say tabplay~ "Lecture d'un tableau (non-transpositeur)" - say tabread~ "Lecture non-interpolatrice d'un tableau" - say tabread4~ "Lecture d'un tableau avec quatre points d'interpolation" - say tabosc4~ "Oscillateur table d'onde" - say tabsend~ "crit continuellement un block dans un tableau" - say tabreceive~ "Lit continuellement un block dans un tableau" - - say_category "FILTRES AUDIO" - say vcf~ "filtre contrl par un signal (voltage)" - say noise~ "gnrateur de bruit blanc" - say env~ "suiveur d'enveloppe" - say hip~ "filtre passe haut" - say lop~ "filtre passe bas" - say bp~ "filtre passe bande" - say biquad~ "filtre brut" - say samphold~ "chantillonneur bloqueur" - say print~ "imprime un ou plusieurs \"blocks\"" - say rpole~ "filtre valeurs relles brut un-ple" - say rzero~ "filtre valeurs relles brut zro-ple" - say rzero_rev~ "[say rzero~] (temps-invers)" - say cpole~ "[say rpole~] (valeurs-complexes)" - say czero~ "[say rzero~] (valeurs-complexes)" - say czero_rev~ "[say rzero_rev~] (valeurs-complexes)" - - say_category "DELAI AUDIO" - say delwrite~ "crit dans une ligne de delai" - say delread~ "lit depuis une ligne de delai" - say vd~ "lit depuis une ligne de delai un temps de delai variable" - - say_category "SUBWINDOWS" - say pd "Definie un subwindow" - say table "Tableau de nombres dans une sous-fentre" - say inlet "Ajouter une entre une abstraction ou sous-patch" - say outlet "Ajouter une sortie une abstraction ou sous-patch" - say inlet~ "[say inlet] (pour un signal)" - say outlet~ "[say outlet] (pour un signal)" - - say_category "CALIBRAGE DE DONNEES" - say struct "dfinit une structure de donnes" - say {drawcurve filledcurve} "Dessine une courbe" - say {drawpolygon filledpolygon} "Dessine un polygone" - say plot "parcelle le champ d'un tableau" - say drawnumber "Imprime une valeur numrique" - - say_category "ACCEDER AUX DONNEES" - say pointer "Pointe vers un objet appartenant un calibrage" - say get "Obtient des champs numriques" - say set "Change des champs numriques" - say element "Obtient l'lment d'un tableau" - say getsize "Obtient la taille d'un tableau" - say setsize "Change la taille d'un tableau" - say append "Ajoute un lment la liste" - say sublist "Obtient un pointeur dans la liste qui est l'lment d'un autre scalaire" - say scalar "Dessine un scalaire sur le parent" - - say_category "OBSOLETE" - say scope~ "(utiliser tabwrite~)" - say namecanvas "Donne un symbole de rception au canevas contenant cet objet" ;# what was this anyway? - say template "(utiliser struct)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "Frquence d'chantillonage" - say -audioindev "Appareils audio en entre" - say -audiooutdev "Appareils audio en sortie" - say -inchannels "Nombre de canaux d'entre audio(par appareil, comme \"2\" ou \"16,8\")" - say -outchannels "Nombre de canaux de sortie audio (pareil)" - say -audiobuf "specifie la taille de la mmoire tampon en msec" - say -blocksize "specifie la taille du block audio I/O en nombre d'chantillons" - say -sleepgrain "specify number of milliseconds to sleep when idle" - say -nodac "Supprime la sortie audio" - say -noadc "Supprime l'entre audio" - say audio_api_choice "Audio API" - say default "default" - say -alsa "use ALSA audio API" - say -jack "use JACK audio API" - say -mmio "use MMIO audio API (default for Windows)" - say -portaudio "use ASIO audio driver (via Portaudio)" - say -oss "use OSS audio API" - say -32bit "allow 32 bit OSS audio (for RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "Supprime l'entre MIDI" - say -nomidiout "Supprime la sortie MIDI" - say -midiindev "Liste des appareils MIDI en entre; e.g., \"1,3\" pour le premier, et le troisime" - say -midioutdev "Liste des appareils MIDI en sortie, mme format" - -say section_externals "Externals" - say -path "Chemin de recherche de fichiers" - say -helppath "Chemin de recherche des fichiers d'aides" - say -lib "Charge une librairie d'objets" - -say section_gui "Gooey" - say -nogui "supprime le dmarrage du GUI (attention)" - say -guicmd "substitue le GUI un autre programme (e.g., rsh)" - say -console "console scrollback lines (0 = disable console)" - say -look "icne de la barre des boutons" - say -statusbar "active la barre de status" - say -font "Specifie la taille par dfaut de la police" - -say section_other "Autre" - say -open "ouvrir un ou plusieurs fichier(s) au dmarrage" - say -verbose "extra printout on startup and when searching for files" - say -d "debug level" - say -noloadbang "disable the effect of \[loadbang\]" - say -send "envoie un message au dmarrage (aprs que les patches soient chargs)" - say -listdev "list audio and MIDI devices upon startup" - say -realtime "use real-time priority (needs root privilege)" - -say section_paths "Paths" - -# phase 4B: ddrc (keyword names not finalized!) - -say section_color "couleurs" - say canvas_color "canevas" - say canvasbgedit "arrire plan d'un canevas (edit mode)" - say canvasbgrun "arrire plan d'un canevas (run mode)" - say object_color "objet" - say viewframe1 "couleur de la boite d'objet" - say viewframe2 "couleur de la boite d'objet" - say viewframe3 "couleur de la boite d'objet" - say viewframe4 "couleur du point culminant de la boite d'objet" - say viewbg "arrire plan d'un objet" - say viewfg "arrire plan d'un objet" - say commentbg "arrire plan d'un commentaire" - say commentfg "premier plan d'un commentaire" - say commentframe1 "comment frame" - say commentframe2 "comment frame" - say commentframe3 "comment frame" - say viewselectframe "boite selectionne" - say wire_color "cordon" - say wirefg "couleur d'un cordon" - say wirefg2 "couleur du point culminant d'un cordon" - say wiredspfg "couleur d'un cordon DSP" - say futurewiredash "nouveau cordon (en pointill)" - say others_color "autres" - say boxinletfg "couleur de l'entre" - say boxoutletfg "couleur de la sortie" - say selrectrect "boite de selection" -say keys "touches" -say others "autres" -say canvashairstate "Activer le rticule" -say canvashairsnap "Crosshair snap to object" ;#TODO -say canvasstatusbar "Activer la barre du status" -say canvasbuttonbar "Activer la barre des boutons" -say wirewirearrow "Flche blanche" -say viewtooltip "ToolTip" -say canvasinsert_object "Insrer un objet" -say canvaschain_object "Enchaner un objet" -say canvasclear_wires "Supprimer les cordons" -say canvasauto_wire "Supprimer un objet" -# phase 5A - -say cannot "ne peut" -say cancel "Annuler" -say apply "Appliquer" -say ok "OK" -say popup_open "Ouvrir" -say popup_insert "Insrer" -say popup_properties "Proprits" -say popup_clear_wires "Supprimer les cordons" -say popup_auto_wire "Supprimer l'objet" -say popup_help "Aide" -say filter "Filtre: " -say how_many_object_classes "%d of %d classes d'objet" -say do_what_i_mean "Fais ce que je te dis" -say ask_cool "a serait cool, hein?" -say save_changes? "Sauvegarder les changements?" -say reset "Remise zero" -say Courier "Courier (chasse fixe)" -say Helvetica "Helvetica (sans srif)" -say Times "Times (serif)" -say add "Ajouter" -say up "Vers le haut" -say down "Vers le bas" -say remove "Supprimer" -say lib_add "Ajouter le nom la liste" -say lib_up "Inverser l'ordre avec la librairie prcdente" -say lib_down "Inverser l'ordre avec la librairie suivante" -say lib_remove "Supprimer la librairie selectionne dans la liste" -say dir_add "Ajouter un dossier avec la boite de dialogue" -say dir_up "Inverser l'ordre avec le dossier prcdent" -say dir_down "Inverser l'ordre avec le dossier suivant" -say dir_remove "Supprimer le dossier selectionn dans la liste" -say client_class_tree "Arbre des classes du client" -say clipboard_view "Vue du presse-papier" -say command_history_view "Vue de l'historique de commandes" -say event_history_view "Vue de l'historique d'vnements" - -# during/after piksel: - -say auto_apply "Appliquer automatiquement" -say font_preview "Aperu" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Style:" -say font_bold "Gras" -say font_italic "Italique" -say font_family "Nom:" -say font_size "Taille:" -say damn "Zut alors!" -say console_clear "Effacer la console" -say horizontal "Horizontal" -say vertical "Vertical" -say tcl_console "Client Tcl" -say pd_console "Serveur Pd" - -# 2007: - -say no_matches "(non trouv)" -say preset "prrglage" -say canvasgrid "Couleur du grillage" -say grid_size "Taille du grillage" -say gridstate "Activer le grillage de fond" -say snap_grid "Snap to grid" ;#TODO -say viewfont "police de l'objet" -say consolefont "police de la console" -say keyboarddialoguefont "police du clavier virtuel" -say keyboard_view "Clavier virtuel" -say log_height "Log Height" ;#TODO -say visual_diff "Visual diff" ;#TODO -say auto "Auto" - -# 2009: - -say oops "Oupse..." -say oops_text "Ce programme a effectu une opration niaiseuse et a t zigouill." - diff --git a/desiredata/src/locale/index.tcl b/desiredata/src/locale/index.tcl deleted file mode 100644 index 5d32938c..00000000 --- a/desiredata/src/locale/index.tcl +++ /dev/null @@ -1,51 +0,0 @@ -say english "English" -say francais "Franais" -say deutsch "Deutsch" -say catala "Catal" -say espanol "Espaol" -say portugues "Portugus" -say brasileiro "Portugus do Brasil" -say italiano "Italiano" -say euskara "Euskara" -say bokmal "Norsk Bokml" -say dansk "Dansk" -say nederlands "Nederlands" -say polski "Polski" -say turkce "Trke" - -# those were made using: -# iconv -f utf-8 -t ucs-2 | od -tx2 -An | sed 's/ /\\u/g' - -say russkij "\u0420\u0443\u0441\u0441\u043a\u0438\u0439" -say chinese "\u4e2d\u6587" -say nihongo "\u65e5\u672c\u8a9e" - -set ::langoptions { - english francais deutsch catala espanol portugues brasileiro - italiano euskara bokmal dansk nederlands turkce polski russkij chinese nihongo - -} - -proc figure_out_language {language} { - switch -regexp -- $language { - ^(en|english)$ {list iso8859-1 english} - ^(fr|francais)$ {list iso8859-1 francais} - ^(de|deutsch)$ {list iso8859-1 deutsch} - ^(ca|catala)$ {list iso8859-1 catala} - ^(es|espanol)$ {list iso8859-1 espanol} - ^(pt|portugues)$ {list iso8859-1 portugues} - ^(it|italiano)$ {list iso8859-1 italiano} - ^(nb|bokmal)$ {list iso8859-1 bokmal} - ^(ch|chinese)$ {list utf-8 chinese} - ^(eu|euskara)$ {list iso8859-1 euskara} - ^(eo|esperanto)$ {list utf-8 esperanto} - ^(pl|polski)$ {list utf-8 polski} - ^(dk|dansk)$ {list iso8859-1 dansk} - ^(ja|nihongo)$ {list utf-8 nihongo} - ^(br|brasileiro)$ {list iso8859-1 brasileiro} - ^(tr|turkce)$ {list utf-8 turkce} - ^(nl|nederlands)$ {list iso8859-1 nederlands} - ^(ru|russkij)$ {list utf-8 russkij} - default {error "unknown language: $language"} - } -} diff --git a/desiredata/src/locale/italiano.tcl b/desiredata/src/locale/italiano.tcl deleted file mode 100644 index 8513e4b9..00000000 --- a/desiredata/src/locale/italiano.tcl +++ /dev/null @@ -1,544 +0,0 @@ -#!/usr/bin/env tclsh -# English translations for PureData -# $Id: italiano.tcl,v 1.1.2.5.2.1 2006-12-05 04:51:47 matju Exp $ -# by Davide Morelli and Federico Ferri - -### Menus - -say file "File" - say new_file "Nuovo File" - say open_file "Apri File..." - say pdrc_editor "Editor di .pdrc" - say ddrc_editor "Editor di .ddrc" - say send_message "Invia un Messaggio..." - say paths "Percorsi..." - say close "Chiudi" - say save "Salva" - say save_as "Salva con nome..." - say print "Stampa..." - say quit "Esci" - - say canvasnew_file "Nuovo File" - say canvasopen_file "Apri File..." - say canvassave "Salva" - say canvassave_as "Salva con nome..." - say clientpdrc_editor ".pdrc Editor" - say clientddrc_editor ".ddrc Editor" - say canvasclose "Chiudi" - say canvasquit "Esci" - -say edit "Modifica" - say undo "Annulla" - say redo "Ripristina" - say cut "Taglia" - say copy "Copia" - say paste "Incolla" - say duplicate "Duplica" - say select_all "Seleziona tutto" - say text_editor "Editor di Testi..." - say font "Font" - say tidy_up "Tidy Up" - say edit_mode "Modalit modifica" - say editmodeswitch "Modalit modifica/esegui" - - say canvascut "Taglia" - say canvascopy "Copia" - say canvasundo "Annulla" - say canvasredo "Ripristina" - say canvaspaste "Incolla" - say canvasduplicate "Duplica" - say canvasselect_all "Seleziona tutto" - say canvaseditmodeswitch "Modalit modifica/esegui" - -say view "Visualizza" - say reload "Ricarica" - say redraw "Ridisegna" - - say canvasreload "Ricarica" - say canvasredraw "Ridisegna" - -say find "Trova" - say find_again "Cerca Ancora" - say find_last_error "Cerca l'ultimo errore" - say string "Cerca stringa" -say canvasfind "Trova" - say canvasfind_again "Cerca Ancora" - -# ??? -say put "Inserisci" - say Object "Oggetto" - say Message "Messaggio" - say Number "Numero" - say Symbol "Simbolo" - say Comment "Commento" - say Array "Array" - say Graph "Grafico" - say VU "Misuratore VU" - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Test Audio e MIDI" - say load_meter "Misura carico cpu" - - say canvasaudio_on "Audio ON" - say canvasaudio_off "Audio OFF" - say clienttest_audio_and_midi "Test Audio e MIDI" - say canvasload_meter "Misura carico cpu" - -say window "Finestra" - -say help "Aiuto" - say about "Informazioni su..." - say pure_documentation "Guida..." - say class_browser "Elenco delle classi..." - - say canvasabout "Informazioni su..." - -say properties "Propriet" -say open "Apri" - -### for key binding editor -say general "Generali" -say audio_settings "Impostazioni audio" -say midi_settings "Impostazioni MIDI" -say latency_meter "Misura latenza" -say Pdwindow "Pd window" - -say canvaspdwindow "Pd window" -say canvaslatency_meter "Misura latenza" -say clientaudio_settings "Impostazioni audio" -say clientmidi_settings "Impostazioni MIDI" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "larghezza(px)" -say h "altezza(px)" -say hold "hold time(ms)" -say break "break time(ms)" -say min "minimo" -say max "massimo" -say is_log "modo" -say linear "lineare" -say logarithmic "logaritmico" -say isa "val. iniziale" -say n "numero di scelte" -say steady "comportamento" -say steady_no "salta" -say steady_yes "stabile" -say snd "send-symbol" -say rcv "receive-symbol" -say lab "etichetta" -say ldx "etichetta offset-x" -say ldy "etichetta offset-y" -say fstyle "font" -say fs "dim. font" -say bcol "Colore sfondo" -say fcol "Colore primo piano" -say lcol "Colore etichetta" -say yes "si" -say no "no" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "grafico su parent" - -say_category GAtomProperties -say width "larghezza" -say lo "limite inferiore" -say hi "limite superiore" -say label "etichetta" -say wherelabel "mostra etichetta" -say symto "send symbol" -say symfrom "receive symbol" - -say_category GraphProperties -say x1 "x da" -say x2 "x a" -say xpix "larghezza schermo" -say y2 "y da" -say y1 "y a" -say ypix "altezza schermo" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "graph on parent" -say xmargin "margine-x" -say ymargin "margine-y" -say height "altezza" -say_category ArrayProperties -say name "nome" -say n "dimensione" -say xfrom "x range da" -say xto "x range a" -say yfrom "y range da" -say yto "y range a" - - -say_category MainWindow -say in "in" -say out "out" -say audio "Audio" -say meters "Livelli" -say io_errors "Errori IO" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box" -# say Bang "Bang" -# say Toggle "Toggle" - say tgl "Toggle Box" - say nbx "Number Box (IEM)" -# say Number2 "Number2" - say hsl "Slider (Orizzontale)" - say vsl "Slider (Verticale)" - say hradio "Choice Box (Orizzontale)" - say vradio "Choice Box (Verticale)" -# say Vradio "Radio verticale" -# say Hradio "Radio orizzontale" - say cnv "Canvas (IEM)" -# say Canvas "Canvas" - say vu "Vumeter" - say dropper "Drag-and-Drop Box" - - say_category GLUE - say bang "invia un bang" - say float "salva e richiama un numero in virgola mobile" - say symbol "salva e richiama un simbolo" - say int "salva e richiama un numero intero" - say send "invia un messaggio ad un oggetto con nome" - say receive "cattura i messaggi inviati" - say select "invia un bang quando i numeri o i simboli combaciano" - say route "instrada i messaggi in base al primo elemento della lista" - say pack "impacchetta i valori in un messaggio" - say unpack "ricava gli elementi di un pacchetto" - say trigger "converte i messaggi ed esegue in sequenza" - say spigot "connessione interrompibile" - say moses "divide un flusso numerico" - say until "meccanismo per creare un ciclo" - say print "stampa messaggi in console" - say makefilename "formatta un simbolo con argomenti" - say change "rimuove le ripetizioni numeriche da un flusso" - say swap "scambia tra loro due numeri" - say value "valore numerico condiviso" - - say_category TIME - say delay "invia un messaggio dopo un ritardo temporale" - say metro "invia un messaggio periodicamente" - say line "invia una serie di numeri interpolati linearmente" - say timer "misura intervalli di tempo" - say cputime "misura l'utilizzo della CPU" - say realtime "misura il tempo reale" - say pipe "linea di ritardo dinamicamente dimensionabile per numeri" - - say_category MATH - say + "somma" - say - "sottrai" - say * "moltiplica" - say {/ div} "dividi" - say {% mod} "resto delal divisione intera" - say pow "esponenziale" - say == "uguale?" - say != "non uguale?" - say > "maggiore?" - say < "minore?" - say >= "non maggiore?" - say <= "non minore?" - say & "congiunzione binaria (and)" - say | "disgiunzione binaria (or)" - say && "congiunzione logica (and)" - say || "disgiunzione logica (or)" - say mtof "da MIDI a Hertz" - say mtof "da Hertz a MIDI" - say powtodb "da Watts a dB" - say dbtopow "da dB a Watts" - say rmstodb "da Volts a dB" - say dbtorms "da dB a Volts" - say {sin cos tan atan atan2 sqrt} "trigonometria" - say log "logaritmo di Eulero" - say exp "esponenziale di Eulero" - say abs "valore assoluto" - say random "valore casuale" - say max "il maggiore tra due numeri" - say min "il minore tra due numeri" - say clip "forza un numero dentro un intervallo" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} \ - "MIDI input" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} \ - "MIDI output" - say makenote \ - "crea e metti in coda un messaggio \"note off\" corrispondente a questo note-on" - say stripnote "togli i messaggi di \"note off\"" - - say_category TABLES - say tabread "leggi un valore da una tabella" - say tabread4 "leggi un valore da una tabella con interpolazione su 4 punti" - say tabwrite "scrivi un valore in una tabella" - say soundfiler "leggi e scrivi tabelle in file audio" - - say_category MISC - say loadbang "bang al caricamento" - say serial "controllo per la porta seriale (solo per NT)" - say netsend "manda messaggi su internet" - say netreceive "riceve messaggi da internet" - say qlist "sequencer di messaggi" - say textfile "convertitore di file in messaggi" - say openpanel "\"Apri\" dialog" - say savepanel "\"salva con nome\" dialog" - say bag "insieme di numeri" - say poly "allocazione polifonica di voci" - say {key keyup} "valori numerici da tastiera" - say keyname "valori in simboli da tastiera" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (per segnali)"} - say max~ "il valore massimo" - say min~ "il valore minimo" - say clip~ "costringe il segnale all'interno di un intervallo" - say q8_rsqrt~ "radice quadrata reciproca veloce (attenzione -- 8 bits!)" - say q8_sqrt~ "radice quadrata veloce (attenzione -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "Trasformata di Fourier complessa discreta" - say ifft~ "Trasformata di Fourier complessa discreta inversa" - say rfft~ "Trasformata di Fourier reale discreta" - say rifft~ "Trasformata di Fourier reale discreta inversa" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (per segnali)" - } -} - - - ### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio output" - say adc~ "audio input" - say sig~ "converte numeri in segnali audio" - say line~ "genera una rampa sui segnali" - say vline~ "line~ con maggiore precisione" - say threshold~ "avverte il superamento di una soglia" - say snapshot~ "converte un segnale in numero" - say vsnapshot~ "snapshot~ con maggiore precisione" - say bang~ "invia un bang dopo ogni blicco DSP" - say samplerate~ "invia la frequenza di campionamento" - say send~ "invia segnali" - say receive~ "riceve segnali da send~" - say throw~ "aggiunge il segnale ad un bus" - say catch~ "legge il segnale da un bus" - say block~ "specifica la dimensione del blocco DSP" - say switch~ "attiva o disattiva la computazione DSP in questa finestra" - say readsf~ "riproduzione di un file audio" - say writesf~ "registrazione di un file audio" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "oscillatore a onda triangolare" - say {cos~ osc~} "oscillatore a onda sinusoidale" - say tabwrite~ "scrive il segnale in una tabella" - say tabplay~ "riproduce il segnale registrato in una tabella (senza trasportare)" - say tabread~ "legge il segnale da una tabella senza interpolazione" - say tabread4~ "legge il segnale da una tabella con interpolazione su 4 punti" - say tabosc4~ "oscillatore wavetable" - say tabsend~ "scrive continuamente un blocco su una tabella" - say tabreceive~ "legge continuamente un blocco da una tabella" - - say_category "AUDIO FILTERS" - say vcf~ "filtro a voltaggio controllato" - say noise~ "rumore bianco" - say env~ "indicatore di inviluppo" - say hip~ "filtro passa alto" - say lop~ "filtro passa basso" - say bp~ "filtro a banda passante" - say biquad~ "filtro biquadratico" - say samphold~ "campiona e trattiene un segnale" - say print~ "scrive uno o pi blocchi sulla console" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO DELAY" - say delwrite~ "scrive una linea di ritardo" - say delread~ "legge una linea di ritardo" - say vd~ "legge una linea di ritardo con tempo variabile" - - say_category "SUBWINDOWS" - say pd "definisce una sottofinestra" - say table "un vettore di numeri in una sottofinestra" - say inlet "aggiunge un inlet" - say outlet "aggiunge un outlet" - say inlet~ "[say inlet] (per segnali)" - say outlet~ "[say outlet] (per segnali)" - - say_category "DATA TEMPLATES" - say struct "definisce una struttura dati" - say {drawcurve filledcurve} "disegna una curva" - say {drawpolygon filledpolygon} "disegna un poligono" - say plot "disegna un vettore" - say drawnumber "stampa un valore numerico" - - say_category "ACCESSING DATA" - say pointer "puntatore ad un oggetto che appartiene ad un template" - say get "ottiene una propriet numerica" - say set "imposta una propriet numerica" - say element "ottiene una propriet vettore" - say getsize "imposta una propriet vettore" - say setsize "cambia le dimensioni di un vettore" - say append "aggiunge un elemento ad una lista" - say sublist "ottiene un puntatore da una lista che un elemento di un'altro scalare" - say scalar "disegna uno scalare sulla finestra" - - say_category "OBSOLETE" - say scope~ "(usa tabwrite~)" - say namecanvas "" ;# what was this anyway? - say template "(usa struct)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "frequenza di campionamento" - say -audioindev "periferiche audio in" - say -audiooutdev "periferiche audio out" - say -inchannels "canali audio input (per periferica, es.: \"2\" o \"16,8\")" - say -outchannels "numero di canali audio out (come sopra)" - say -audiobuf "dimensione del buffer audio in msec" - say -blocksize "dimensione del blocco I/O block in campioni" - say -sleepgrain "numero di millisecondi di attesa quando idle" - say -nodac "senza audio output" - say -noadc "senza audio input" - say audio_api_choice "Audio API" - say default "default" - say -alsa "usa ALSA audio API" - say -jack "usa JACK audio API" - say -mmio "usa MMIO audio API (default for Windows)" - say -portaudio "usa ASIO audio driver (via Portaudio)" - say -oss "usa OSS audio API" - say -32bit "permetti audio OSS a 32 bit (per RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "senza MIDI input" - say -nomidiout "senza MIDI output" - say -midiindev "lista periferiche midi in; es.: \"1,3\" per la prima e la terza" - say -midioutdev "lista periferiche midi out; come sopra" - -say section_externals "Externals" - say -path "percorso di ricerca files" - say -helppath "percorso di ricerca help" - say -lib "carica le seguenti librerie" - -say section_gui "Gooey" - say -nogui "senza avviare la GUI (attenzione)" - say -guicmd "programma GUI alternativo (es.: rsh)" - say -console "n. linee scrollback console (0 = disabilita la console)" - say -look "icone pulsantiera" - say -statusbar "abilita barra di stato" - say -font "dimensione di default per i font (in punti)" - -say section_other "Other" - say -open "apri file(s) all'avvio" - say -verbose "stampa messaggi extra all'avvio e durante la ricerca di files" - say -d "levello di debug" - say -noloadbang "disabilita l'effetto di \[loadbang\]" - say -send "manda un messaggio all'avvio (dopo il caricamento delle patch)" - say -listdev "elenca le periferiche audio e MIDI all'avvio" - say -realtime "usa real-time priority (necessita privilegi root)" - -say section_paths "Paths" - -# phase 4B: ddrc (keyword names not finalized!) - -say section_color "colors" - say canvas_color "canvas" - say canvasbgedit "sfondo canvas (modalit edit)" - say canvasbgrun "sfondo canvas (modalit run)" - say object_color "oggetto" - say viewframe1 "colore objectbox" - say viewframe2 "colore objectbox" - say viewframe3 "colore objectbox" - say viewframe4 "colore objectbox selezionato" - say viewbg "sfondo oggetto" - say viewfg "primo piano oggetto" - say commentbg "sfondo commento" - say commentfg "testo del commento" - say commentframe1 "cornice commento" - say commentframe2 "cornice commento" - say commentframe3 "cornice commento" - say viewselectframe "box selezione (viewselectframe)" - say wire_color "cavo" - say wirefg "colore cavo" - say wirefg2 "colore cavo selezionato" - say wiredspfg "colore cavo audio" - say futurewiredash "nuovo cavo (tratteggiato)" - say others_color "altro" - say boxinletfg "colore inlet color" - say boxoutletfg "colore outlet color" - say selrectrect "box selezione (selrectrect)" -say keys "tasti" -say others "altro" -say canvashairstate "Attiva cursore di precisione" -say canvashairsnap "Cursore \"magnetico\"" -say canvasstatusbar "Attiva barra di stato" -say canvasbuttonbar "Attiva pulsantiera" -say wirewirearrow "Wire Arrow" -say viewtooltip "Suggerimenti" -say canvasinsert_object "Inserisci oggetto" -say canvaschain_object "Cascata oggetto" -say canvasclear_wires "Elimina connessioni" -say canvasauto_wire "Rimuovi oggetto" -# phase 5A - -say cannot "non posso" -say cancel "Annulla" -say apply "Applica" -say ok "OK" -say popup_open "Apri" -say popup_insert "Inserisci" -say popup_properties "Propriet" -say popup_clear_wires "Elimina connessioni" -say popup_auto_wire "Rimuovi connessioni" -say popup_help "Aiuto" -say filter "Filtra: " -say how_many_object_classes "%d su %d oggetti" -say do_what_i_mean "Do What I Mean" -say save_changes? "Salvare le modifiche?" -say reset "Reset" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Aggiungi" -say up "Spusta su" -say down "Sposta gi" -say remove "Rimuovi" -say lib_add "aggiungi il nome che hai scritto alla lista" -say lib_up "inverti di ordine con la libreria precedente" -say lib_down "inverti di ordine con la libreria successiva" -say lib_remove "rimuove la libreria selezionata dalla lista" -say dir_add "aggiunge una directory" -say dir_up "inverti di ordine con la directory precedente" -say dir_down "inverti di ordine con la directory successiva" -say dir_remove "rimuove la directory selezionata dalla lista" -say client_class_tree "Albero delle Classi" -say clipboard_view "Appunti" -say history_view "Storia" - -# during/after piksel: - -say auto_apply "Auto-Applica" -say font_preview "Anteprima:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Stile:" -say font_bold "Grassetto" -say font_italic "Corsivo" -say font_family "Nome:" -say font_size "Dimensione font" diff --git a/desiredata/src/locale/localeutils.tcl b/desiredata/src/locale/localeutils.tcl deleted file mode 100755 index f53c5b66..00000000 --- a/desiredata/src/locale/localeutils.tcl +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env tclsh -# to check the difference between locale files -# arguments: -# -list view the list of supported locales -# -lang <locale> compare <locale> to english -# no option: summary of all locales - -proc lwithout {a b} { - set r {} - foreach x $b {set c($x) {}} - foreach x $a {if {![info exists c($x)]} {lappend r $x}} - return $r -} - -proc lintersection {a b} { - set r {} - foreach x $b {set c($x) {}} - foreach x $a {if {[info exists c($x)]} {lappend r $x}} - return $r -} - -proc say {k args} { - global text - if {[llength $args]} { - set ${::name}($k) [lindex $args 0] - } else { - if {[info exist text($k)]} { - puts "------------" - return $text($k) - } else {return "{{$k}}"} - } -} - -proc say_namespace {k code} {uplevel 1 $code} -proc say_category {text} {} - -set ::name ::index -array set ::index {} -source index.tcl - -foreach lang [array names ::index] { - set ::name ::$lang - source $lang.tcl -} - -proc summary {} { - foreach lang [lsort [lwithout [array names ::index] english]] { - puts "#-----------------------------8<-----CUT------8<-----------------------------#" - key_compare $lang; value_compare $lang - } -} - -proc compare {lang} { - key_compare $lang - value_compare $lang -} - -proc value_compare {lang} { - puts "\nFollowing entries have the same value as English:" - set values {} - set english2 [array names ::english] - set locale [array names ::$lang] - set intersect [lintersection $english2 $locale] - foreach item [lsort $intersect] { - set val1 $::english($item) - set val2 [set ::${lang}($item)] - if {$val1 == $val2} { - lappend values $item - } - } - foreach item $values {puts "\t $item"} -} - - -proc key_compare {lang} { - set english2 [array names ::english] - set locale [array names ::$lang] - set diff_missing [lwithout $english2 $locale] - set diff_extra [lwithout $locale $english2] - set percent_missing [expr int(([llength $diff_missing] / [llength $english2].0)*100)] - set percent_extra [expr int(([llength $diff_extra] / [llength $english2].0)*100)] - puts "\ncompare $lang to english --> ${percent_missing}% difference" - foreach item [lsort $diff_missing] { - puts " - $item" - } - puts "\ncompare english to $lang --> ${percent_extra}% difference" - foreach item [lsort $diff_extra] { - puts " + $item" - } -} - - -if {![llength $argv]} { - summary -} else { - switch -regexp -- [lindex $argv 0] { - ^-list\$ {puts [lwithout [array names ::index] english]} - ^-lang\$ { - set lang [lindex $argv 1] - if {[lsearch [array names ::index] $lang] > 0} {compare $lang} {puts "Unknown locale '$lang'"} - } - ^-h\$ { - puts "-list view the list of supported locales" - puts "-lang <locale> only report about <locale> instead of about all locales" - } - default {puts "Unknown option '[lindex $argv 0]'. try -h for help"} - } -} - diff --git a/desiredata/src/locale/nederlands.tcl b/desiredata/src/locale/nederlands.tcl deleted file mode 100644 index 277682fd..00000000 --- a/desiredata/src/locale/nederlands.tcl +++ /dev/null @@ -1,599 +0,0 @@ -#!/usr/bin/env tclsh -# English translations for PureData -# $Id: nederlands.tcl,v 1.1.2.1 2007-10-05 23:14:58 matju Exp $ - -### Menus - -say file "Bestand" - say new_file "Nieuw Bestand" - say open_file "Open Bestand" - say server_prefs "Server Voorkeuren..." - say client_prefs "Client Voorkeuren..." - say pdrc_editor ".pdrc Bewerken" - say ddrc_editor ".ddrc Bewerken" - say send_message "Zend Boodschap..." - say paths "Paden..." - say close "Sluiten" - say save "Opslaan" - say save_as "Opslaan Als..." - say print "Afdrukken..." - say abort_server "Server Afsluiten" - say quit "Sluiten" - - say canvasnew_file "Nieuw Bestand" - say canvasopen_file "Open Bestand..." - say canvassave "Opslaan" - say canvassave_as "Opslaan Als..." - say clientpdrc_editor ".pdrc Editor" - say clientddrc_editor ".ddrc Editor" - say canvasclose "Venster Sluiten" - say canvasquit "Sluiten" - -say edit "Bewerken" - say undo "Ongedaan Maken" - say redo "Bewerking Herdoen" - say cut "Knippen" - say copy "Kopieren" - say paste "Plakken" - say duplicate "Dupliceren" - say select_all "Alles Selecteren" - say text_editor "Text Editor..." - say font "Lettertype" - say tidy_up "Opkuisen" - say edit_mode "Edit modus" - say editmodeswitch "Edit/Run modus" - - say canvascut "Knip" - say canvascopy "Kopiëer" - say canvasundo "Maak Ongedaan" - say canvasredo "Bewerking Opnieuw" - say canvaspaste "Plak" - say canvasduplicate "Dupliceer" - say canvasselect_all "Selecteer Alles" - say canvaseditmodeswitch "Edit/Run modus" - -say view "Beeld" - say reload "Herlaad" - say redraw "Herteken" - - say canvasreload "Herlaad" - say canvasredraw "Herteken" - -say find "Zoek" - say find_again "Zoek Opnieuw" - say find_last_error "Zoek Laatste Fout" - say string "Zoek String" -say canvasfind "Zoek" - say canvasfind_again "Zoek Opnieuw" - -# contents of Put menu is Phase 5C -say put "Plaats" - say Object "Object" - say Message "Boodschap" - say Number "Nummer" - say Symbol "Symbool" - say Comment "Commentaar" - say Graph "Graph" - say Bang "Bang" - say Toggle "Toggle" - say Number2 "Nummer2" - say Vslider "Verticale Schuifregelaar" - say Hslider "Horizontale Schuifregelaar" - say Vradio "Verticale Radio" - say Hradio "Horizontale Radio" - say Canvas "Canvas" - say Array "Array" - - say canvasobject "Object" - say canvasmessage "Boodschap" - say canvasnumber "Nummer" - say canvassymbol "Symbool" - say canvascomment "Commentaar" - say canvasbang "Bang" - say canvastoggle "Toggle" - say canvasnumber2 "Nummer2" - say canvasvslider "Verticale Schuifregelaar" - say canvashslider "Horizontale Schuifregelaar" - say canvasvradio "Verticale Radio" - say canvashradio "Horizontale Radio" - say canvascanvas "Canvas" - say canvasarray "Array" - -say media "Media" - say audio_on "Audio AAN" - say audio_off "Audio UIT" - say test_audio_and_midi "Test Audio en MIDI" - say load_meter "Belasting Meter" - - say canvasaudio_on "Audio AAN" - say canvasaudio_off "Audio UIT" - say clienttest_audio_and_midi "Test Audio en MIDI" - say canvasload_meter "Belasting Meter" - -say window "Venster" - -say help "Hulp" - say about "Over..." - say pure_documentation "Pure Documentatie..." - say class_browser "Class Browser..." - - say canvasabout "Over..." - -say properties "Eigenschappen" -say open "Open" -say documentation "Documentatie..." - -### for key binding editor -say general "Algemeen" -say audio_Instellingen "Audio Instellingen" -say midi_Instellingen "Midi Instellingen" -say latency_meter "Vertraging Meter" -say Pdwindow "Pd venster" - -say canvaspdwindow "Pd venster" -say canvaslatency_meter "Vertraging Meter" -say clientaudio_Instellingen "Audio Istellingen" -say clientmidi_Instellingen "Midi Instellingen" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "breedte(px)" -say h "hoogte(px)" -say hold "houd tijd(ms)" -say break "breek tijd(ms)" -say min "minimum waarde" -say max "maximum waarde" -say is_log "modus" -say linear "lineair" -say logarithmic "logarithmisch" -say isa "init" -say n "aantal keuzen" -say steady "gelijkmatigheid" -say steady_no "verspring bij klik" -say steady_yes "blijf staan bij klik" -say snd "zend-symbool" -say rcv "ontvang-symbool" -say lab "etiket" -say ldx "etiket x afstand" -say ldy "etiket y afstand" -say fstyle "Lettertype" -say fs "letter grootte" -say bcol "achtergrond kleur" -say fcol "voorgrond kleur" -say lcol "etiket kleur" -say yes "ja" -say no "nee" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "graph on parent" - -say_category GAtomProperties -say width "breedte" -say lo "ondergrens" -say hi "bovengrens" -say label "etiket" -say wherelabel "toon etiket aan" -say symto "zend symbool" -say symfrom "ontvang symbool" - -say_category GraphProperties -say x1 "x van" -say x2 "x tot" -say xpix "scherm breedte" -say y2 "y van" -say y1 "y tot" -say ypix "scherm hoogte" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "graph on parent" -say xmargin "xmarge" -say ymargin "ymarge" -say height "hoogte" -say_category ArrayProperties -say name "naam" -say n "grootte" -say xfrom "x omvang van" -say xto "x omvang tot" -say yfrom "y omvang van" -say yto "y omvang tot" - - -say_category MainWindow -say in "in" -say out "uit" -say audio "Audio" -say meters "Meters" -say io_errors "IO Foutmeldingen" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box" - say tgl "Toggle Box" - say nbx "Nummer Box (IEM)" - say hsl "Schuifregelaar (Horizontaal)" - say vsl "Schuifregelaar (Verticaal)" - say hradio "Keuze Box (Horizontaal)" - say vradio "Keuze Box (Verticaal)" - say cnv "Canvas (IEM)" - say dropper "Drag-and-Drop Box" - say vu "Vumeter" - - say_category GLUE - say bang "stuur een bang boodschap uit" - say float "een nummer opslaan en opvragen" - say symbol "een symbool opslaan en opvragen" - say int "een geheel getal opslaan en opvragen" - say send "stuur een boodschap naar benoemd object" - say receive "ontvang verzonden boodschappen" - say select "geef bang bij overeenkomstige nummers of symbolen" - say route "leid boodschappen om volgens eerste element" - say pack "maak samengestelde boodschappen" - say unpack "splits samengestelde boodschappen" - say trigger "sequentie en conversie van boodschappen" - say spigot "onderbreekbare verbinding" - say moses "een nummer-stroom splitsen" - say until "lus mechanisme" - say print "druk boodschap af" - say makefilename "maak een symbool met een variabel teken" - say change "verwijder herhalingen uit een nummer-stroom" - say swap "twee nummers omwisselen" - say value "gedeelde waarde" - - say_category TIME - say delay "stuur een boodschap na een vertraging" - say metro "stuur een periodieke bang" - say line "stuur een reeks lineair gerangschikte nummers" - say timer "meet tijdsintervallen" - say cputime "meet CPU tijd" - say realtime "meet echte tijd" - say pipe "dynamisch aanpasbare vertraging" - - say_category MATH - say + "plus" - say - "min" - say * "vermenigvuldig" - say {/ div} "delen" - say {% mod} "rest na deling" - say pow "machtsverheffing" - say == "is gelijk aan?" - say != "verschillend van?" - say > "is groter dan?" - say < "is kleiner dan?" - say >= "is groter dan of gelijk aan?" - say <= "is kleiner dan of gelijk aan?" - say & "bitsgewijze conjunctie (and)" - say | "bitsgewijze disjunctie (or)" - say && "logische conjunctie (and)" - say || "logische disjunctie (or)" - say mtof "MIDI naar Hertz" - say ftom "Hertz naar MIDI" - say powtodb "Watt naar dB" - say dbtopow "dB naar Watt" - say rmstodb "Volt naar dB" - say dbtorms "dB naar Volt" - say {sin cos tan atan atan2 sqrt} "driehoeksmeting" - say log "Euler logaritme" - say exp "Euler exponentieel" - say abs "absolute waarde" - say random "toeval" - say max "bovengrens waarde" - say min "ondergrens waarde" - say clip "houd een getal binnen een bereik" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI ingang" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI uitgang" - say makenote "plan een uitgestelde \"note off\" boodschap voor elke note-on" - say stripnote "verwijder \"note off\" boodschappen" - - say_category TABLES - say tabread "lees een nummer uit een tabel" - say tabread4 "lees een nummer uit een tabel, met 4 punts interpolatie" - say tabwrite "schrijf een nummer in een tabel" - say soundfiler "lees en schrijf tabellen van en naar bestanden" - - say_category MISC - say loadbang "bang bij laden" - say serial "seriele apparaatcontrole enkel voor NT" - say netsend "stuur boodschappen over het internet" - say netreceive "ontvang boodschappen over het internet" - say qlist "boodschap sequencer" - say textfile "bestand naar boodschap omzetter" - say openpanel "\"Open\" dialoogvenster" - say savepanel "\"Save as\" dialoogvenster" - say bag "verzameling nummers" - say poly "polyphonische stemtoewijzing" - say {key keyup} "numerieke waarden van toetsen" - say keyname "symbolische naam van toetsen" - - say_category "AUDIO WISKUNDE" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "supremum van signalen" - say min~ "infimum van signalen" - say clip~ "beperk signaal tussen twee begrensingen" - say q8_rsqrt~ "goedkope reciprocal vierkantswortel (let op -- 8 bits!)" - say q8_sqrt~ "goedkope vierkantswortel (let op -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "real inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO LIJM" - say dac~ "audio uitgang" - say adc~ "audio ingang" - say sig~ "zet nummers om naar audiosignaal" - say line~ "genereer audio helling" - say vline~ "deluxe line~" - say threshold~ "detecteer audio grens" - say snapshot~ "neem staal van signaal (converteer terug naar nummer)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "stuur een bang boodschap na elke DSP blok" - say samplerate~ "geef de sample rate" - say send~ "niet-locale signaal verbinding met uitwaaiering" - say receive~ "ontvang signaal van send~" - say throw~ "voeg toe aan een summing bus" - say catch~ "definieer en lees van een summing bus" - say block~ "specifieer blok grootte en overlapping" - say switch~ "schakel DSP berekeningen aan een uit" - say readsf~ "speel een geluidsbestand af van schijf" - say writesf~ "neem geluid op naar schijf" - - say_category "AUDIO OSCILLATOREN AND TABELLEN" - say phasor~ "zaagtand oscillator" - say {cos~ osc~} "cosinus oscillator" - say tabwrite~ "schrijf naar een tabel" - say tabplay~ "speel af van een tabel (niet-transponerend)" - say tabread~ "niet-interpolerend lezen van tabel" - say tabread4~ "4 punts interpolerend lezen van tabel" - say tabosc4~ "golfvormtabel oscillator" - say tabsend~ "schijf een blok continu naar een tabel" - say tabreceive~ "lees een blok continu van een tabel" - - say_category "AUDIO FILTERS" - say vcf~ "voltage controlled filter" - say noise~ "witte ruis generator" - say env~ "envelope follower" - say hip~ "hoog doorlaat filter" - say lop~ "laag doorlaat filter" - say bp~ "band doorlaat filter" - say biquad~ "rauwe filter" - say samphold~ "sample and hold eenheid" - say print~ "druk een of meer \"blokken\" af" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO VERTRAGING" - say delwrite~ "schrijf naar vertragingslijn" - say delread~ "lees van vertragingslijn" - say vd~ "lees van een vertragingslijn met een variabele tijd" - - say_category "SUBVENSTERS" - say pd "definieer een subvenster" - say table "reeks nummers in een subvenster" - say inlet "voeg een ingang toe aan een subvenster" - say outlet "voeg een uitgang toe aan een subvenster" - say inlet~ "[say inlet] (voor signaal)" - say outlet~ "[say outlet] (voor signaal)" - - say_category "DATA TEMPLATES" - say struct "definieer een datastructuur" - say {drawcurve filledcurve} "teken een curve" - say {drawpolygon filledpolygon} "teken een veelhoek" - say plot "teken een array veld" - say drawnumber "druk een numerieke waarde af" - - say_category "DATA BEREIKEN" - say pointer "wijs naar een object dat bij een template hoort" - say get "numerieke velden lezen" - say set "numerieke velden schrijven" - say element "een array element lezen" - say getsize "de grootte van een array opvragen" - say setsize "de grootte van een array wijzigen" - say append "een element aan een lijst toevoegen" - say sublist "een pointer in een lijst krijgen die een element is van een andere scalar" - say scalar "teken een scalar op parent" - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ now)" - say namecanvas "" ;# what was this anyway? - say template "(use struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "sample rate" - say -audioindev "audio in apparaten" - say -audiooutdev "audio out apparaten" - say -inchannels "aantal audio-in kanalen (per apparaat, bijvoorbeeld \"2\" of \"16,8\")" - say -outchannels "aantal audio-uit kanalen (idem)" - say -audiobuf "specifieer grootte van audio buffer in msec" - say -blocksize "specifieer audio IN/UIT blok grootte in sample frames" - say -sleepgrain "specifieer het aantal milliseconden slaap wanneer inactief" - say -nodac "onderdruk audio uitgang" - say -noadc "onderdruk audio ingang" - say audio_api_choice "Audio API" - say default "default" - say -alsa "gebruik ALSA audio API" - say -jack "gebruik JACK audio API" - say -mmio "gebruik MMIO audio API (default voor Windows)" - say -portaudio "gebruik ASIO audio stuurprogramma (via Portaudio)" - say -oss "gebruik OSS audio API" - say -32bit "sta 32 bit OSS audio toe (voor RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "onderdruk MIDI ingang" - say -nomidiout "onderdruk MIDI uitgang" - say -midiindev "midi in apparatenlijst; bijvb., \"1,3\" voor eerste en derde" - say -midioutdev "midi uit apparatenlijst, (idem)" - -say section_externals "Externals" - say -path "zoek-pad voor bestanden" - say -helppath "zoek-pad voor help bestanden" - say -lib "laad objecten bibliotheek" - -say section_gui "Goe-wie" - say -nogui "start zonder grafische interface (opgelet)" - say -guicmd "gebruik een andere grafische interface (bijvb., rsh)" - say -console "console terug scroll lijnen (0 = schakel console uit)" - say -look "ikonen knoppenbalk" - say -statusbar "activeer statusbalk" - say -font "specifieer lettertekengrootte" - -say section_other "Andere" - say -open "open bestand bij opstarten" - say -verbose "extra informatie afdrukken vij opstarten en het zoeken naar bestanden" - say -d "debug niveau" - say -noloadbang "desactiveer \[loadbang\]" - say -send "stuur een boodschap (nadat de patches geladen zijn)" - say -listdev "geef lijst weer van audio en midi apparaten bij opstarten" - say -realtime "gebruik realtime prioriteit (vereist root-privileges)" - -say section_paths "Paden" - -# phase 4B: ddrc (keyword names not finalized!) - -say section_color "kleuren" - say canvas_color "canvas" - say canvasbgedit "canvas achtergrond (edit modus)" - say canvasbgrun "canvas achtergrond (run modus)" - say object_color "object" - say viewframe1 "objectbox kleur" - say viewframe2 "objectbox kleur" - say viewframe3 "objectbox kleur" - say viewframe4 "objectbox geselecteerd kleur" - say viewbg "object achtergrond" - say viewfg "object voorgrond" - say commentbg "comment achtergrond" - say commentfg "comment voorgrond" - say commentframe1 "commentaar frame" - say commentframe2 "commentaar frame" - say commentframe3 "commentaar frame" - say viewselectframe "geselecteerde box" - say wire_color "draad" - say wirefg "draad kleur" - say wirefg2 "draad geselecteerd" - say wiredspfg "dsp draad kleur" - say futurewiredash "nieuwe (stippelijn) draad" - say others_color "andere" - say boxinletfg "inlet kleur" - say boxoutletfg "outlet kleur" - say selrectrect "selectie box" -say keys "toetsen" -say others "andere" -say canvashairstate "Activeer crosshair" -say canvashairsnap "Crosshair spring naar object" -say canvasstatusbar "Activeer statusbalk" -say canvasbuttonbar "Activeer knoppenbalk" -say wirewirearrow "Draad Pijl" -say viewtooltip "ToolTip" -say canvasinsert_object "Voeg object in" -say canvaschain_object "Ketting object" -say canvasclear_wires "Wis draden" -say canvasauto_wire "Verwijder object" -say subpatcherize "Subpatcherizeer" -say keynav "toetsenbord navigatie" -say key_nav_up "omhoog" -say key_nav_up_shift "voeg toe aan selectie" -say key_nav_down "omlaag" -say key_nav_down_shift "voeg toe aan selectie" -say key_nav_right "rechts" -say key_nav_right_shift "voeg toe aan selectie" -say key_nav_left "links" -say key_nav_left_shift "voeg toe aan selectie" -say key_nav_ioselect "selecteer in/outlets" - -# phase 5A - -say cannot "Kan niet" -say cancel "Annuleer" -say apply "Pas Toe" -say ok "Akkoord" -say popup_open "Open" -say popup_insert "Invoegen" -say popup_properties "Eigenschappen" -say popup_clear_wires "Wis draden" -say popup_auto_wire "Verwijder object (autowire)" -say popup_help "Help" -say popup_remove_from_path "Verwijder object uit pad" -say popup_delete_from_path "Wis object uit pad" -say popup_help "Hulp" -say filter "Filter: " -say do_what_i_mean "Do What I Mean" -say ask_cool "Dit zou een leuke functie zijn he ?" -say reset "Reset" -say filter "Filter: " -say how_many_object_classes "%d of %d object classes" -say do_what_i_mean "Doe wat ik bedoel" -say save_changes? "Wijzigingen opslaan?" -say reset "Herstel" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Voeg toe" -say up "Opwaarts" -say down "Neerwaarts" -say remove "Verwijder" -say lib_add "Voeg de naam die u ingaf toe aan de lijst" -say lib_up "Verwissel volgorde met vorige bibliotheek" -say lib_down "Verwissel volgorde met volgende bibliotheek" -say lib_remove "verwijder bibliotheek geselecteerd in de lijst" -say dir_add "voeg een map toe door middel van een dialoogvenster" -say dir_up "verwissel volgorde met vorige map" -say dir_down "verwissel volgorde met volgende map" -say dir_remove "verwijder map geselecteerd in de lijst" -say client_class_tree "Client Class Tree" -say clipboard_view "Kladblok Weergave" -say history_view "Geschiedenis Weergave" -say command_history_view "Geschiedenis Commando's" -say event_history_view "Geschiedenis Gebeurtenissen" - -# during/after piksel: - -say auto_apply "Automatisch-Toepassen" -say font_preview "Voorsmaak:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Stijl:" -say font_bold "Vet" -say font_italic "Schuingedrukt" -say font_family "Naam:" -say font_size "Lettertekengrootte" -say damn "Miljaar!" -say console_clear "Console Leegmaken" -say horizontal "Horizontaal" -say vertical "Vertikaal" -say language "Taal" - -# 2007: - -say no_matches "(geen overeenkomsten)" -say preset "preset" -say canvasgrid "Grid kleur" -say grid_size "Grid grootte" -say gridstate "Activeer achtergrond grid" -say snap_grid "Verspring volgens grid eenheden" -say viewfont "lettertype voor objecten" -say consolefont "lettertype voor console" -say keyboarddialogfont "lettertype voor virtueel toetsenbord" -say keyboard_view "Virtueel toetsenbord" -say log_height "Log Hoogte" diff --git a/desiredata/src/locale/nihongo.tcl b/desiredata/src/locale/nihongo.tcl deleted file mode 100644 index 0101c8ff..00000000 --- a/desiredata/src/locale/nihongo.tcl +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env tclsh -# Japanese translations for PureData -# $Id: nihongo.tcl,v 1.1.2.1 2007-08-12 05:56:49 matju Exp $ -# by Kentaro Fukuchi and friends - -### Menus -say file "ファイル" - say new_file "新規作成" - say open_file "ファイルを開く..." - say server_prefs "サーバー設定..." - say client_prefs "クライアント設定..." - say send_message "メッセージ送信..." - say paths "パス..." - say close "閉じる" - say save "保存" - say save_as "名前を付けて保存..." - say print "印刷..." - say abort_server "サーバー停止" - say quit "終了" - - say canvasnew_file "新規作成" - say canvasopen_file "ファイルを開く..." - say canvassave "保存" - say canvassave_as "名前を付けて保存..." - say clientpdrc_editor ".pdrc エディター" - say clientddrc_editor ".ddrc エディター" - say canvasclose "閉じる" - say canvasquit "終了" - -say edit "編集" - say undo "元に戻す" - say redo "やり直し" - say cut "カット" - say copy "コピー" - say paste "ペースト" - say duplicate "複製" - say select_all "すべてを選択" - say clear_selection "選択を解除" - say text_editor "テキストエディタ..." - say font "フォント" - say tidy_up "整列";## tidy up これでよいか? - say edit_mode "編集モード" - say editmodeswitch "編集/実行モード切替" - say subpatcherize "サブパッチ化";## Subpacherizer これでよいか? - - say canvascut "カット" - say canvascopy "コピー" - say canvasundo "元に戻す" - say canvasredo "やり直し" - say canvaspaste "ペースト" - say canvasduplicate "複製" - say canvasselect_all "すべてを選択" - say canvaseditmodeswitch "編集/実行モード切替" - -say view "表示" - say reload "再読込み" - say redraw "再描画" - - say canvasreload "再読込み" - say canvasredraw "再描画" - -say find "検索" - say find_again "再検索" - say find_last_error "最後のエラーを検索" - say string "文字列の検索" -say canvasfind "Find" - say canvasfind_again "再検索" - -# contents of Put menu is Phase 5C -say put "挿入";## オブジェクトの挿入というニュアンスでよいか? - say Object "オブジェクト" - say Message "メッセージ" - say Number "ナンバー" - say Symbol "シンボル" - say Comment "コメント" - say Graph "グラフ" - say Array "配列" - -say media "メディア" - say audio_on "オーディオON" - say audio_off "オーディオOFF" - say test_audio_and_midi "オーディオとMIDIのテスト" - say load_meter "負荷メーター" - - say canvasaudio_on "オーディオON" - say canvasaudio_off "オーディオOFF" - say clienttest_audio_and_midi "オーディオとMIDIのテスト" - say canvasload_meter "負荷メーター" - -say window "ウィンドウ" - -say help "ヘルプ" - say about "Desire Dataについて..." - say documentation "ドキュメント..." - say class_browser "クラス・ブラウザー..." - - say canvasabout "Desire Dataについて..." - -say properties "プロパティ" -say open "開く" - -### for key binding editor -say general "一般" -say audio_settings "オーディオの設定" -say midi_settings "MIDIの設定" -say latency_meter "レイテンシ・メーター" -say Pdwindow "Pdウィンドウ" - -say canvaspdwindow "Pdウィンドウ" -say canvaslatency_meter "レイテンシ・メーター" -say clientaudio_settings "オーディオの設定" -say clientmidi_settings "MIDIの設定" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "幅(px)" -say h "高さ(px)" -say hold "ホールド(ms)" -say break "break time(ms)";## すみません、ニュアンスわかりません -say min "最小値" -say max "最大値" -say is_log "モード" -say linear "線型" -say logarithmic "対数" -say isa "初期化" -say n "number of choices" -say steady "クリック時動作";##Steadiness 意訳でよいか? -say steady_no "ジャンプ" -say steady_yes "ジャンプ無";##steady on clickこれでよいか? -say snd "送信先シンボル" -say rcv "受信元シンボル" -say lab "ラベル" -say ldx "ラベル x方向オフセット" -say ldy "ラベル y方向オフセット" -say fstyle "フォント" -say fs "サイズ" -say bcol "背景カラー";##「背景色」も検討したが「ラベル色」としないよう統一 -say fcol "前景カラー" -say lcol "ラベルカラー" -say yes "はい" -say no "いいえ" -say courier "courier (typewriter)";##フォント名のためママでよいか? -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "描画";##Graph on parent 意訳でよいか? - -say_category GAtomProperties -say width "幅" -say lo "最小値" -say hi "最大値" -say label "ラベル" -say wherelabel "ラベル表示位置";##おそらく未使用 -say symto "送信先シンボル" -say symfrom "受信元シンボル" - -say_category GraphProperties -say x1 "x 開始値" -say x2 "x 終了値" -say xpix "幅" -say y2 "y 開始値" -say y1 "y 終了値" -say ypix "高さ" - -say_category CanvasProperties -#say xscale "X ピクセル毎単位";##unitx/px この訳でよいか -#say yscale "Y ピクセル毎単位" -say gop "描画";##この訳でよいか? -say xmargin "xマージン" -say ymargin "yマージン" -say height "高さ" -say_category ArrayProperties -say name "名前" -say n "サイズ" -say xfrom "x 開始値" -say xto "x 終了値" -say yfrom "y 開始値" -say yto "y 終了値" - - -say_category MainWindow -say in "in" -say out "out" -say audio "オーディオ" -say meters "メーター" -say io_errors "I/Oエラー" -say tcl_console "Tclクライアント" -say pd_console "Pdサーバー" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bangボックス" - say tgl "トグル・ボックス" - say nbx "ナンバー・ボックス(IEM)" - say hsl "スライダー(水平)" - say vsl "スライダー(垂直)" - say hradio "選択ボックス(水平)" - say vradio "選択ボックス(垂直)" - say cnv "キャンバス(IEM)" - say dropper "ドラッグ&ドロップ・ボックス" - say vu "VUメーター" - - say_category GLUE - say bang "Bangを送信" - say float "数値の保存/読出し" - say symbol "シンボルの保存/読出し" - say int "整数の保存/読出し" - say send "オブジェクトへメッセージを送信" - say receive "送信されたメッセージの受信" - say select "数値またはシンボルの一致を検査する" - say route "先頭の要素を評価し、ルートを分岐する" - say pack "メッセージを結合する" - say unpack "結合されたメッセージを分離する" - say trigger "任意の形式に変換したメッセージを、任意の順で送信" - say spigot "メッセージをフィルタ" - say moses "連続する数値を、指定した値を境に分岐して出力" - say until "ループ機能" - say print "メッセージを表示" - say makefilename "変数を含むシンボルをファイル名の形式に変換" - say change "連続する数値のうち、重複するものをフィルタ" - say swap "二つの値を入れ替える" - say value "グローバル変数の保存/読出し" - - say_category TIME - say delay "メッセージを遅延させる" - say metro "定期的にメッセージを送信" - say line "直線的に変化する連続した数値を送信" - say timer "経過時間を計測" - say cputime "CPU時間を計測" - say realtime "実時間を計測" - say pipe "数値送信に用いる、可変長のディレイラインを作成" - - say_category MATH - say + "加算" - say - "減算" - say * "乗算" - say {/ div} "除算" - say {% mod} "余り" - say pow "対数" - say == "等号" - say != "不等号" - say > "大なり" - say < "小なり" - say >= "大なりイコール" - say <= "小なりイコール" - say & "ビット演算 (and)" - say | "ビット演算 (or)" - say && "論理積 (and)" - say || "論理和 (or)" - say mtof "MIDIノー・トナンバーを周波数に変換" - say ftom "周波数をMIDIノート・ナンバーに変換" - say powtodb "ワット数をdBに変換" - say dbtopow "dBをワット数に変換" - say rmstodb "電圧をdBに変換" - say dbtorms "dBを電圧に変換" - say {sin cos tan atan atan2 sqrt} "三角関数" - say log "自然対数" - say exp "指数関数" - say abs "絶対値" - say random "乱数" - say max "二項のうち、より大きい数" - say min "二項のうち、より小さい数" - say clip "数値をしきい値内におさめる" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI入力" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI出力" - say makenote "ノートオンを送信し、指定した時間経過後にノート・オフを送信" - say stripnote "連続するノート・オフをフィルター" - - say_category TABLES - say tabread "テーブルから数値読出し" - say tabread4 "4点による擬似補間を用いて、テーブルから数値を読出し" - say tabwrite "テーブルに数値を書込み" - say soundfiler "テーブルからファイルへ、相互に読出し/書込み" - - say_category MISC - say loadbang "読込時にBangを送信" - say serial "シリアル・デバイス・コントロール(NTのみ)" - say netsend "インターネットを介してメッセージ送信" - say netreceive "インターネットを介してメッセージ受信" - say qlist "メッセージ・シーケンサー" - say textfile "ファイルを読み込みメッセージを生成" - say openpanel "「ファイルを開く」ダイアログを表示" - say savepanel "「ファイルを保存」ダイアログを表示" - say bag "数値の集合を保持" - say poly "ポリフォニックの入力信号を管理" - say {key keyup} "キーボード入力のアスキー・コードを送信" - say keyname "キーボード入力文字を送信" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (シグナル用)"} - say max~ "シグナルの最大値" - say min~ "シグナルの最小値" - say clip~ "シグナルの値をしきい値内に強制変換" - say q8_rsqrt~ "簡易版平方根の逆数 (注意:8ビット)" - say q8_sqrt~ "簡易版平方根 (注意:8ビット)" - say wrap~ "入力値にもっとも近い整数との差 (入力が正の場合は小数部)" - say fft~ "複素離散フーリエ変換" - say ifft~ "複素逆離散フーリエ変換" - say rfft~ "実離散フーリエ変換" - say rifft~ "逆離散フーリエ変換" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (シグナル用)" - } -} - -### phase 3 - -say_namespace summary { - say_category "音声結線" - say dac~ "音声出力" - say adc~ "音声入力" - say sig~ "数値を音声信号に変換" - say line~ "音声に時間変化の勾配を付加" - say vline~ "line~の機能拡張版" - say threshold~ "信号からしきい値を検出" - say snapshot~ "信号をサンプリング(数値に書き戻す)" - say vsnapshot~ "snapshot~の機能拡張版" - say bang~ "BANGメッセージを以降の全てのDSPブロックに出力" - - say samplerate~ "サンプリング周波数を取得" - - say send~ "複数の出力を備えた遠隔接続" - say receive~ "send~より信号を受け取る" - say throw~ "加算バス(ミキサ)に追加する" - say catch~ "加算バス(ミキサ)の内容を読み出す" - say block~ "ブロックの大きさとオーバーラップを指定" - say switch~ "DSP処理をオン/オフ" - say readsf~ "ディスク上の音声ファイルを再生" - say writesf~ "音声をディスクに記録" - - say_category "オシレータとテーブル" - say phasor~ "鋸状波オシレータ" - say {cos~ osc~} "サイン波オシレータ" - say tabwrite~ "テーブルへ書き込む" - say tabplay~ "テーブルから再生(移調は伴わない)" - say tabread~ "補間を行わずにテーブルから読み込む" - say tabread4~ "四点多項式による補間を行いながらテーブルから読み込む" - say tabosc4~ "ウェーブテーブルオシレータ" - say tabsend~ "テーブルへ1ブロックを連続的に書き込む" - say tabreceive~ "テーブルから1ブロックを連続的に読み出す" - - say_category "フィルタ" - say vcf~ "電圧制御式バンドパスフィルタ" - say noise~ "ホワイトノイズ発生器" - say env~ "エンヴェロープフォロワ " - say hip~ "ハイパスフィルタ" - say lop~ "ローパスフィルタ" - say bp~ "バンドパスフィルタ" - say biquad~ "引数により様々な設計ができるフィルタ" - say samphold~ "サンプルアンドホールド" - say print~ "ひとつまたは複数のブロックの音声信号をコンソールに表示" - say rpole~ "単極(再帰)フィルタ" - say rzero~ "1ゼロ点(非再帰)フィルタ" - say rzero_rev~ "反転1ゼロ点(非再帰)フィルタ" - say cpole~ "複素単極(再帰)フィルタ" - say czero~ "複素1ゼロ点(非再帰)フィルタ" - say czero_rev~ "複素反転1ゼロ点(非再帰)フィルタ" - - say_category "ディレイ" - say delwrite~ "ディレイラインに書き込み" - say delread~ "ディレイラインから読み出す" - say vd~ "ディレイラインから任意のタイミングで読み出す" - - say_category "サブウインドウ" - say pd "サブウインドウを定義" - say table "サブウインドウ内で数値を配列" - say inlet "サブウインドウ内へ結線" - say outlet "サブウインドウ外へ結線" - say inlet~ "サブウインドウ内へ結線(音声信号用)" - say outlet~ "サブウインドウ外へ結線(音声信号用)" - - say_category "データテンプレート" - say struct "データの構造を定義" - say {drawcurve filledcurve} "曲線を描く" - say {drawpolygon filledpolygon} "多角形を描く" - say plot "配列を描画" - say drawnumber "数値を表示" - - say_category "データアクセス" - say pointer "テンプレートに属するオブジェクトを指定" - say get "数値データを取得" - say set "数値データを任意の値に書き換え" - say element "配列の要素を取得" - say getsize "配列の大きさを取得" - say setsize "配列の大きさを変更" - say append "リストに要素を付加" - say sublist "リストからポインタを取得(これは他のスケーラの一要素です)" - say scalar "スケーラを親ウインドウに表示" - - say_category "もう使う必要のないもの" - say scope~ "(tabwrite~に統合されました)" - say namecanvas "" ;# what was this anyway? 正直、これってなんだっけ? - say template "(structに統合されました)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "オーディオ" - say -r "サンプリング周波数" - say -audioindev "音声入力デバイス" - say -audiooutdev "音声出力デバイス" - say -inchannels "音声入力チャンネル(デバイスによる。例えば“2”や“16,8”のように。)" - say -outchannels "音声出力チャンネル(入力に同じ)" - say -audiobuf "音声バッファの大きさをミリ秒で定義" - say -blocksize "音声入力/出力のブロックの大きさをサンプルフレーム数で定義" - say -sleepgrain "ミリ秒で定義される値をアイドル時にスリープさせる" - say -nodac "音声出力を停止" - say -noadc "音声入力を停止" - say audio_api_choice "オーディオAPI" - say default "デフォルト" - say -alsa "オーディオAPIとしてALSAを使う" - say -jack "オーディオAPIとしてJACKを使う" - say -mmio "オーディオAPIとしてMMIOを使う(Windows標準)" - say -portaudio "ASIOドライバを使う(Portaudioを通じて)" - say -oss "オーディオAPIとしてOSSを使う" - say -32bit "32ビットのOSSオーディオを許可する(RME Hammerfallのみ)" - say {} "デフォルト" - -say section_midi "MIDI" - say -nomidiin "MIDI入力を停止" - say -nomidiout "MIDI出力を停止" - say -midiindev "MIDIインデバイスのリスト(用例:“1,3”で1番目と3番目)" - say -midioutdev "MIDIアウトデバイスのリスト(用例:“1,3”で1番目と3番目)" - -say section_externals "エクスターナル" - say -path "ファイルの検索パス" - say -helppath "ヘルプファイルの検索パス" - say -lib "オブジェクトのライブラリをロード" - -say section_gui "GUI" - say -nogui "GUIなしで起動する(危険です)" - say -guicmd "他のGUIプログラムと置き換える(例えばrshのような)" - say -look "ボタンバーのアイコン" - say -font "起動時のフォントのサイズをpointで定義" - -say section_other "その他" - say -open "起動時にファイルを開く" - say -verbose "起動時とファイル検索時のコンソールへの表示を詳細化" - say -d "デバッグレベル" - say -noloadbang "“loadbang”を無効にする" - say -send "起動時にメッセージを送信する(全てのパッチが読み込まれた直後に)" - say -listdev "オーディオデバイスとMIDIデバイスのリストを起動時に表示する" - say -realtime "優先度を最優先にする(管理者権限が必要)" - -say section_paths "パス" - -# phase 4B: ddrc (keyword names not finalized!) -say console "コンソールウインドウの表示行数 (0 = コンソールを停止)" -say lang "使用言語" -say pointer_sense "マウス感度" -say section_color "アピアランス" - say canvas_color "カンバス" - say canvasbgedit "カンバス背景(エディットモード時)" - say canvasbgrun "カンバス背景(実行モード時)" - say object_color "オブジェクト" - say viewframe1 "オブジェクトボックスの色" - say viewframe2 "オブジェクトボックスの色" - say viewframe3 "オブジェクトボックスの色" - say viewframe4 "オブジェクトボックス選択時の色" - say viewbg "オブジェクト背景" - say viewfg "オブジェクト前景" - say commentbg "コメント背景" - say commentfg "コメント前景" - say commentframe1 "コメントフレーム" - say commentframe2 "コメントフレーム" - say commentframe3 "コメントフレーム" - say viewselectframe "選択されたボックス" - say wire_color "結線" - say wirefg "結線色" - say wirefg2 "選択された結線" - say wiredspfg "音声信号用結線の色" - say futurewiredash "新規結線" - say others_color "その他" - say boxinletfg "インレットの色" - say boxoutletfg "アウトレットの色" - say selrectrect "セレクションボックス" -say keys "キー" -say others "その他" -say hairstate "十字型カーソルを表示" -say hairsnap "十字型カーソルをオブジェクトにスナップ" -say statusbar "ステータスバーを表示" -say buttonbar "ボタンバーを表示" -say menubar "メニューバーを表示" -say scrollbar "オートスクロールバーを表示" -say wirearrow "結線端の信号の方向を示す矢印" -say tooltip "ツールチップ" -say insert_object "オブジェクトを挿入" -say chain_object "オブジェクトを繋ぐ" -say clear_wires "結線を全て外す" -say auto_wire "オブジェクトを消去" -say subpatcherize "サブパッチとして独立させる" -say keynav "キーボードナビゲーション" -say key_nav_up "上へ移動" -say key_nav_up_shift "上へ移動して選択" -say key_nav_down "下へ移動" -say key_nav_down_shift "下へ移動して選択" -say key_nav_right "右へ移動" -say key_nav_right_shift "右へ移動して選択" -say key_nav_left "左へ移動" -say key_nav_left_shift "左へ移動して選択" -say key_nav_ioselect "インレット/アウトレットを選択" - -# phase 5A - -say cannot "不可能です" -say cancel "キャンセル" -say apply "適用する" -say ok "OK" -say popup_open "開く" -say popup_insert "挿入する" -say popup_properties "プロパティ" -say popup_clear_wires "結線を全て外す" -say popup_remove_from_path "パスからオブジェクトを外す" -say popup_delete_from_path "パスからオブジェクトを消去する" -say popup_help "ヘルプ" -say filter "フィルタ: " -say how_many_object_classes "%2\$d 中 %1\$d 個のオブジェクトクラス" -say do_what_i_mean "言ったとおりにやってよね" -say ask_cool "マジでこの機能を使う事が出来たならなぁ..." -say save_changes? "変更を保存しますか?" -say reset "リセット" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "追加" -say up "上へ" -say down "下へ" -say remove "消去" -say lib_add "リストに書いた名前を加える" -say lib_up "前のライブラリと順番を入れ替える" -say lib_down "次のライブラリと順番を入れ替える" -say lib_remove "リスト中の選択されたライブラリを外す" -say dir_add "ダイアログを使ってフォルダを加える" -say dir_up "前のフォルダと順番を入れ替える" -say dir_down "次のフォルダと順番を入れ替える" -say dir_remove "リスト中の選択されたフォルダを外す" -say client_class_tree "クライアント構成" -say clipboard_view "クリップボードを表示" -say command_history_view "操作履歴を表示" -say event_history_view "イベント履歴を表示" - -# during/after piksel: - -say auto_apply "自動的に適用する" -say font_preview "プレビュー:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "スタイル:" -say font_bold "太字" -say font_italic "斜体" -say font_family "名前:" -say font_size "大きさ:" -say damn "最低!" -say console_clear "コンソールをクリア" -say horizontal "水平方向" -say vertical "鉛直方向" -say language "言語" - -# 2007: - -say no_matches "(適合するものなし)" -say preset "プリセット" -say canvasgrid "グリッドの色" -say grid_size "グリッドの大きさ" -say gridstate "背景にグリッドを表示" -say snap_grid "グリッドにスナップ" -say viewfont "オブジェクトのフォント" -say consolefont "コンソールのフォント" -say keyboarddialogfont "仮想キーボードのフォント" -say keyboard_view "仮想キーボード" diff --git a/desiredata/src/locale/polski.tcl b/desiredata/src/locale/polski.tcl deleted file mode 100644 index 5be7cd48..00000000 --- a/desiredata/src/locale/polski.tcl +++ /dev/null @@ -1,557 +0,0 @@ -#!/usr/bin/env tclsh -# Polish (polski) translations for PureData -# $Id: polski.tcl,v 1.1.2.2 2007-08-01 04:24:43 matju Exp $ -# by Michal Seta, mis@artengine.ca - -say file "Plik" - say new_file "Nowy Plik" - say open_file "Otwórz Plik..." - say server_prefs "Preferencje servera..." - say client_prefs "Preferencje klienta..." - say send_message "Wysłać Wiadomość..." - say paths "Ścieżki..." - say close "Zamknąć" - say save "Zapisz" - say save_as "Zapisz Jako..." - say print "Wydrukuj..." - say quit "Zakończ" - - say canvasnew_file "Nowy Plik" - say canvasopen_file "Otwórz Plik..." - say canvassave "Zapisz" - say canvassave_as "Zapisz Jako..." - say clientpdrc_editor "Edycja .pdrc" - say clientddrc_editor "Edycja .ddrc" - say canvasclose "Zamknij" - say canvasquit "Zakończ" - -say edit "Edycja" - say undo "Cofnij" - say redo "Ponów" - say cut "Wytnij" - say copy "Skopiuj" - say paste "Wklei" - say duplicate "Powiel" - say select_all "Zaznacz wszystko" - say text_editor "Edytor tekstu..." - say font "Czcionka" - say tidy_up "Wyrównać" - say edit_mode "Tryb edycji" - say editmodeswitch "Tryb edycji/pracy" - - say canvascut "Wytnij" - say canvascopy "Skopiuj" - say canvasundo "Anuluj" - say canvasredo "Ponów" - say canvaspaste "Wklei" - say canvasduplicate "Powiel" - say canvasselect_all "Zaznacz wszystko" - say canvaseditmodeswitch "Tryb edycji/pracy" - -say view "Widok" - say reload "Załaduj ponownie" - say redraw "Odśwież" - - say canvasreload "Załaduj ponownie" - say canvasredraw "Odśwież" - - say find "Szukaj" - say find_again "Szukaj ponownie" - say find_last_error "Znajdź ostatni błąd" - say string "Znajdź ciąg znaków" - say canvasfind "Szukaj" - say canvasfind_again "Szukaj ponownie" - -say put "Połóż" - say Object "Objekt" - say Message "Komunikat" - say Number "Liczba" - say Symbol "Znak" - say Comment "Komentarz" - say Array "Tabela" - -say media "Media" - say audio_on "Włącz dźwięk" - say audio_off "Wyłącz dźwięk" - say test_audio_and_midi "Próba dżwięku i MIDI" - say load_meter "Miernik procesora" - - say canvasaudio_on "Włącz dźwięk" - say canvasaudio_off "Wyłącz dźwięk" - say clienttest_audio_and_midi "Próba dżwięku i MIDI" - say canvasload_meter "Miernik procesora" - -say window "Okno" - -say help "Pomoc" - say about "Na temat..." - say pure_documentation "Dokumentacja..." - say class_browser "Przeglądarka klas..." - - say canvasabout "Na temat..." - - say properties "Właściwości" -say open "Otwórz" - -### for key binding editor -say general "Ogólne" -say audio_settings "Ustawienia dżwięku" -say midi_settings "Ustawienia MIDI" -say latency_meter "Miernik opóźnienia" -say Pdwindow "Okno PD" - -say canvaspdwindow "Konsola PD" -say canvaslatency_meter "Miernik opóźnienia" -say clientaudio_settings "Ustawienia dżwięku" -say clientmidi_settings "Ustawienia MIDI" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "Szerokość(px)" -say h "Wysokość(px)" -say hold "Czas utrzymania(ms)" -say break "Czas zatrzymania(ms)" -say min "Zmienna minimalna" -say max "Zmienna maxymalna" -say is_log "Tryb" -say linear "Liniowy" -say logarithmic "Logarytmiczny" -say isa "Uruchomienie" -say n "Ilość wyboru" -say steady "Równomierny" -say steady_no "Skok po kliknięciu" -say steady_yes "Stały po kliknięciu" -say snd "oznakowanie wysłania" -say rcv "oznakowanie pobrania" -say lab "etykieta" -say ldx "przesunięcie etykiety po x" -say ldy "przesunięcie etykiety po y" -say fstyle "Czcionka" -say fs "Rozmiar czcionki" -say bcol "Kolor tła" -say fcol "Kolor przedni" -say lcol "Kolor etykiety" -say yes "Tak" -say no "Nie" -say courier "courrier (typewriter)" -say helvetica "helvetique (sansserif)" -say times "times (serif)" -say coords "grafika na nadrzędnym" - -say_category GAtomProperties -say width "szerokość" -say lo "ograniczenie niskie" -say hi "ograniczenie wysole" -say label "etykieta" -say wherelabel "wyświetlić etykietę" -say symto "wyślij znak" -say symfrom "pobierz znak" - -say_category GraphProperties -say x1 "x od" -say x2 "x do" -say xpix "szerokość ekranu" -say y2 "y od" -say y1 "y do" -say ypix "wysokość ekranu" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "grafika na nadrzędnym" -say xmargin "margines x" -say ymargin "margines y" -say height "wysokość" -say_category ArrayProperties -say name "nazwa" -say n "rozmiar" -say xfrom "zakres x od" -say xto "zakres x do" -say yfrom "zakres y od" -say yto "zakres y do" - - -say_category MainWindow -say in "wejście" -say out "wyjście" -say audio "Dźwięk" -say meters "Pomiary" -say io_errors "Błędy I/O" -say tcl_console "Klient Tcl" -say pd_console "Server pd" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang" - say tgl "Przerzutnik" - say nbx "Liczba" - say hsl "Suwak (poziomy)" - say vsl "Suwak (Pionowy)" - say hradio "Pole wyboru (poziome)" - say vradio "Pole wyboru (pionowe)" - say cnv "Płótno" - say dropper "Drag-and-Drop Box" - say vu "Miernik VU" - - say_category GLUE - say bang "output a bang message" - say float "store and recall a number" - say symbol "store and recall a symbol" - say int "store and recall an integer" - say send "send a message to a named object" - say receive "catch sent messages" - say select "test for matching numbers or symbols" - say route "route messages according to first element" - say pack "make compound messages" - say unpack "get elements of compound messages" - say trigger "sequence and convert messagess" - say spigot "interruptible message connection" - say moses "part a numeric stream" - say until "looping mechanism" - say print "print out messages" - say makefilename "format a symbol with a variable field" - say change "remove repeated numbers from a stream" - say swap "swap two numbers" - say value "shared numeric value" - - say_category TIME - say delay "send a message after a time delay" - say metro "send a message periodically" - say line "send a series of linearly stepped numbers" - say timer "measure time intervals" - say cputime "measure CPU time" - say realtime "measure real time" - say pipe "dynamically growable delay line for numbers" - - say_category MATH - say + "add" - say - "substract" - say * "multiply" - say {/ div} "divide" - say {% mod} "division remainder" - say pow "exponentiate" - say == "equal?" - say != "not equal?" - say > "more than?" - say < "less than?" - say >= "not less than?" - say <= "not more than?" - say & "bitwise conjunction (and)" - say | "bitwise disjunction (or)" - say && "logical conjunction (and)" - say || "logical disjunction (or)" - say mtof "MIDI to Hertz" - say ftom "Hertz to MIDI" - say powtodb "Watts to dB" - say dbtopow "dB to Watts" - say rmstodb "Volts to dB" - say dbtorms "dB to Volts" - say {sin cos tan atan atan2 sqrt} "trigonometry" - say log "Euler logarithm" - say exp "Euler exponential" - say abs "absolute value" - say random "random" - say max "greater of two numbers" - say min "lesser of two numbers" - say clip "force a number into a range" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI input" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI output" - say makenote "schedule a delayed \"note off\" message corresponding to a note-on" - say stripnote "strip \"note off\" messages" - - say_category TABLES - say tabread "read a number from a table" - say tabread4 "read a number from a table, with 4 point interpolation" - say tabwrite "write a number to a table" - say soundfiler "read and write tables to soundfiles" - - say_category MISC - say loadbang "bang on load" - say serial "serial device control for NT only" - say netsend "send messages over the internet" - say netreceive "receive them" - say qlist "message sequencer" - say textfile "file to message converter" - say openpanel "\"Open\" dialog" - say savepanel "\"Save as\" dialog" - say bag "set of numbers" - say poly "polyphonic voice allocation" - say {key keyup} "numeric key values from keyboard" - say keyname "symbolic key name" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (for signals)"} - say max~ "supremum of signals" - say min~ "infimum of signals" - say clip~ "constrict signal to lie between two bounds" - say q8_rsqrt~ "cheap reciprocal square root (beware -- 8 bits!)" - say q8_sqrt~ "cheap square root (beware -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "real inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio output" - say adc~ "audio input" - say sig~ "convert numbers to audio signals" - say line~ "generate audio ramps" - say vline~ "deluxe line~" - say threshold~ "detect signal thresholds" - say snapshot~ "sample a signal (convert it back to a number)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "send a bang message after each DSP block" - say samplerate~ "get the sample rate" - say send~ "nonlocal signal connection with fanout" - say receive~ "get signal from send~" - say throw~ "add to a summing bus" - say catch~ "define and read a summing bus" - say block~ "specify block size and overlap" - say switch~ "switch DSP computation on and off" - say readsf~ "soundfile playback from disk" - say writesf~ "record sound to disk" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "sawtooth oscillator" - say {cos~ osc~} "cosine oscillator" - say tabwrite~ "write to a table" - say tabplay~ "play back from a table (non-transposing)" - say tabread~ "non-interpolating table read" - say tabread4~ "four-point interpolating table read" - say tabosc4~ "wavetable oscillator" - say tabsend~ "write one block continuously to a table" - say tabreceive~ "read one block continuously from a table" - - say_category "AUDIO FILTERS" - say vcf~ "voltage controlled filter" - say noise~ "white noise generator" - say env~ "envelope follower" - say hip~ "high pass filter" - say lop~ "low pass filter" - say bp~ "band pass filter" - say biquad~ "raw filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO DELAY" - say delwrite~ "write to a delay line" - say delread~ "read from a delay line" - say vd~ "read from a delay line at a variable delay time" - - say_category "SUBWINDOWS" - say pd "define a subwindow" - say table "array of numbers in a subwindow" - say inlet "add an inlet to a pd" - say outlet "add an outlet to a pd" - say inlet~ "[say inlet] (for signal)" - say outlet~ "[say outlet] (for signal)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "draw a curve" - say {drawpolygon filledpolygon} "draw a polygon" - say plot "plot an array field" - say drawnumber "print a numeric value" - - say_category "ACCESSING DATA" - say pointer "point to an object belonging to a template" - say get "get numeric fields" - say set "change numeric fields" - say element "get an array element" - say getsize "get the size of an array" - say setsize "change the size of an array" - say append "add an element to a list" - say sublist "get a pointer into a list which is an element of another scalar" - say scalar "draw a scalar on parent" - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ now)" - say namecanvas "" ;# what was this anyway? - say template "(use struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "sample rate" - say -audioindev "audio in devices" - say -audiooutdev "audio out devices" - say -inchannels "audio input channels (by device, like \"2\" or \"16,8\")" - say -outchannels "number of audio out channels (same)" - say -audiobuf "specify size of audio buffer in msec" - say -blocksize "specify audio I/O block size in sample frames" - say -sleepgrain "specify number of milliseconds to sleep when idle" - say -nodac "suppress audio output" - say -noadc "suppress audio input" - say audio_api_choice "Audio API" - say default "default" - say -alsa "use ALSA audio API" - say -jack "use JACK audio API" - say -mmio "use MMIO audio API (default for Windows)" - say -portaudio "use ASIO audio driver (via Portaudio)" - say -oss "use OSS audio API" - say -32bit "allow 32 bit OSS audio (for RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "suppress MIDI input" - say -nomidiout "suppress MIDI output" - say -midiindev "midi in device list; e.g., \"1,3\" for first and third" - say -midioutdev "midi out device list, same format" - -say section_externals "Externals" - say -path "file search path" - say -helppath "help file search path" - say -lib "load object libraries" - -say section_gui "Gooey" - say -nogui "suppress starting the GUI (caution)" - say -guicmd "substitute another GUI program (e.g., rsh)" - say -look "buttonbar icons" - say -font "specify default font size in points" - -say section_other "Other" - say -open "open file(s) on startup" - say -verbose "extra printout on startup and when searching for files" - say -d "debug level" - say -noloadbang "disable the effect of \[loadbang\]" - say -send "send a message at startup (after patches are loaded)" - say -listdev "list audio and MIDI devices upon startup" - say -realtime "use real-time priority (needs root privilege)" - -say section_paths "Paths" - -# phase 4B: ddrc (keyword names not finalized!) -say console "console scrollback lines (0 = disable console)" -say lang "Language to use" -say pointer_sense "Mouse pointer sensitivity" -say section_color "colors" - say canvas_color "canvas" - say canvasbgedit "canvas background (edit mode)" - say canvasbgrun "canvas background (run mode)" - say object_color "object" - say viewframe1 "objectbox color" - say viewframe2 "objectbox color" - say viewframe3 "objectbox color" - say viewframe4 "objectbox highlight color" - say viewbg "object background" - say viewfg "object foreground" - say commentbg "comment background" - say commentfg "comment forground" - say commentframe1 "comment frame" - say commentframe2 "comment frame" - say commentframe3 "comment frame" - say viewselectframe "hilight box" - say wire_color "wire" - say wirefg "wire color" - say wirefg2 "wire highlight" - say wiredspfg "dsp wire color" - say futurewiredash "new (dashed) wire" - say others_color "others" - say boxinletfg "inlet color" - say boxoutletfg "outlet color" - say selrectrect "selection box" -say keys "keys" -say others "others" -say hairstate "Activate crosshair" -say hairsnap "Crosshair snap to object" -say statusbar "Activate statusbar" -say buttonbar "Activate buttonbar" -say menubar "Activate menubar" -say scrollbar "Active auto scrollbar" -say wirearrow "Wire Arrow" -say tooltip "ToolTip" -say insert_object "Insert object" -say chain_object "Chain object" -say clear_wires "Clear wires" -say auto_wire "Remove object" -say subpatcherize "Subpatcherize" -say keynav "keyboard navigation" -say key_nav_up "move up" -say key_nav_up_shift "plus select" -say key_nav_down "move down" -say key_nav_down_shift "plus select" -say key_nav_right "move right" -say key_nav_right_shift "plus select" -say key_nav_left "move left" -say key_nav_left_shift "plus select" -say key_nav_ioselect "select in/outlets" -# phase 5A - -say cannot "can't" -say cancel "Cancel" -say apply "Apply" -say ok "OK" -say popup_open "Open" -say popup_insert "Insert" -say popup_properties "Properties" -say popup_clear_wires "Clear wires" -say popup_remove_from_path "Remove object from path" -say popup_delete_from_path "Delete object from path" -say popup_help "Help" -say filter "Filter: " -say how_many_object_classes "%d of %d object classes" -say do_what_i_mean "Do What I Mean" -say ask_cool "This would be a cool feature, eh?" -say save_changes? "Save changes?" -say reset "Reset" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Add" -say up "Up" -say down "Down" -say remove "Remove" -say lib_add "add the name you typed to the list" -say lib_up "swap order with previous library" -say lib_down "swap order with next library" -say lib_remove "remove library selected in the list" -say dir_add "add a folder using a file dialog" -say dir_up "swap order with previous folder" -say dir_down "swap order with next folder" -say dir_remove "remove folder selected in the list" -say client_class_tree "Client Class Tree" -say clipboard_view "Clipboard View" -say command_history_view "Command History View" -say event_history_view "Event History View" - -# during/after piksel: - -say auto_apply "Auto-Apply" -say font_preview "Preview:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Style:" -say font_bold "Bold" -say font_italic "Italic" -say font_family "Name:" -say font_size "Size:" -say damn "Damn!" -say console_clear "Clear Console" -say horizontal "Horizontal" -say vertical "Vertical" -say language "Language" - -# 2007: - -say no_matches "(no matches)" -say preset "preset" diff --git a/desiredata/src/locale/portugues.tcl b/desiredata/src/locale/portugues.tcl deleted file mode 100644 index 64385356..00000000 --- a/desiredata/src/locale/portugues.tcl +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env tclsh -# Portuguese (Portugus) translations for PureData -# $Id: portugues.tcl,v 1.1.2.5 2006-10-13 16:00:56 matju Exp $ -# by Nuno Godinho - -# (waiting for a version that has 8859-1 accents) - -### Menus - -say file "Ficheiro" - say new_file "Novo Ficheiro" - say open_file "Abrir Ficheiro..." - say pdrc_editor "Editor .pdrc" - say send_message "Enviar Mensagem..." - say paths "Caminhos..." - say close "Fechar" - say save "Gravar" - say save_as "Gravar Como..." - say print "Imprimir..." - say quit "Sair" - -say edit "Editar" - say undo "Desfazer" - say redo "Refazer" - say cut "Cortar" - say copy "Copiar" - say paste "Colar" - say duplicate "Duplicar" - say select_all "Seleccionar Tudo" - say text_editor "Editor de Texto..." - say tidy_up "Arranjar" - say edit_mode "Modo Editar" - -say view "Vista" - say reload "Recarregar" - say redraw "Redesenhar" - -say find "Procurar" - say find_again "Procurar Novamente" - say find_last_error "Encontrar Ultimo Erro" - -say put "Colocar" - -say media "Media" - say audio_on "Audio ON" - say audio_off "Audio OFF" - say test_audio_and_midi "Testar Audio e MIDI" - say load_meter "Medidor de Carga" - -say window "Janela" - -say help "Ajuda" - say about "Acerca..." - say pure_documentation "Documentao do Pure..." - say class_browser "Listar Classes..." - - -### Main Window - -say in "entrada" -say out "saida" -say audio "Audio" -say meters "Medidores" -say io_errors "Erros de IO" - -### Other - -say cannot "impossivel" - -### phase 4 - -say section_audio "udio" - say -r "frequncia de amostragem" - say -audioindev "dispositivos de entradaa udio" - say -audiooutdev "dispositivos de sada udio" - say -inchannels "canais de entrada udio (por dispositivo, como \"2\" ou \"16,8\")" - say -outchannels "nmero de canais de sada udio (igual)" - say -audiobuf "especificar tamanho do buffer de udio em ms" - say -blocksize "especificar tamanho do bloco I/O udio em nmero de amostras" - say -sleepgrain "especificar nmero de milisegundos que dorme quando inactivo" - say -nodac "inibir sada de udio" - say -noadc "inibir entrada de udio" - say audio_api_choice "udio API" - say default "defeito" - say -alsa "usar ALSA audio API" - say -jack "usar JACK audio API" - say -mmio "usar MMIO audio API (por defeito para Windows)" - say -portaudio "usar ASIO audio driver (via Portaudio)" - say -oss "usar OSS audio API" - say -32bit "permitir OSS udio a 32 bit (para RME Hammerfall)" - -say section_midi "MIDI" - say -nomidiin "inibir entrada MIDI" - say -nomidiout "inibir sada MIDI" - say -midiindev "lista de dispositivos de entrada midi; ex., \"1,3\" para primeiro e terceiro" - say -midioutdev "lista de dispositivos de sada midi, mesmo formato" - -say section_externals "Externals" - say -path "adicionar a caminho de pesquisa de ficheiros" - say -helppath "adicionar a caminho de pesquisa de ficheiros de ajuda" - say -lib "carregar biblioteca(s) de objectos" - -say section_gui "Gooey" - say -nogui "inibir inicializao de GUI (cuidado)" - say -guicmd "substituir programa de GUI (ex., rsh)" - say -console "linhas armazenadas na consola (0 = inibir consola)" - say -look "pasta contendo icons para barra de botes" - say -statusbar "inibir barra de status" - say -font "especificar tamanho da fonte por defeito em pontos" - -say section_other "Outros" - say -open "abrir ficheiro(s) na inicializao" - say -verbose "impresses extra na inicializao e durante pesquisa de ficheiros" - say -d "nvel de depurao" - say -noloadbang "inibir efeito de \[loadbang\]" - say -send "enviar mensagem na inicializao (depois dos patches carregados)" - say -listdev "listar dispositivos udio e MIDI aps inicializao" - say -realtime "usar prioridade de tempo-real (necessrios privilgios de root)" - diff --git a/desiredata/src/locale/russkij.tcl b/desiredata/src/locale/russkij.tcl deleted file mode 100644 index 448c4bf5..00000000 --- a/desiredata/src/locale/russkij.tcl +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env tclsh -# русский перевод PureData (пьюр дата - англ., "чисто данные") -# by Ilya Dmitrichenko, 'errordeveloper"^at^"gmail"^dot^"com' -# $Id: russkij.tcl,v 1.1.2.1 2007-10-26 20:17:14 matju Exp $ - -### Menus - -say file "Файл" - say new_file "Новый файл" - say open_file "Открыть файл..." - say server_prefs "Настройки сервера..." - say client_prefs "Настройки клиента..." - say send_message "Послать сообщение..." - say paths "Расположение расширений..." - say close "Закрыть" - say save "Сохранить" - say save_as "Сохранить с именем..." - say print "Распечатать..." - say abort_server "О сервере" - say quit "Покинуть программу" - - say canvasnew_file "Новый файл" - say canvasopen_file "Отрыть файл..." - say canvassave "Сохранить" - say canvassave_as "Сохранить как..." - say clientpdrc_editor "отредактировать .pdrc" - say clientddrc_editor "отредактировать .ddrc" - say canvasclose "Закрыть" - say canvasquit "Выход" - -say edit "Правка" - say undo "Шаг назад" - say redo "Шаг вперёд" - say cut "Вырезать" - say copy "Копировать" - say paste "Вставить" - say duplicate "Дублировать" - say select_all "Выбрать всё" - say clear_selection "Отменить выбор" - say text_editor "Текстовый редактор..." - say font "Шрифт" - say tidy_up "Упорядочить" - say edit_mode "Режим редактирования" - say editmodeswitch "Режим исполнения/редактирования" - say subpatcherize "Превратить в суб-патч" - - say canvascut "Вырезать" - say canvascopy "Копировать" - say canvasundo "Шаг назад" - say canvasredo "Шаг вперёд" - say canvaspaste "Вставить" - say canvasduplicate "Дублировать" - say canvasselect_all "Выбрать всё" - say canvaseditmodeswitch "Режим исполнения/редактирования" - -say view "Вид" - say reload "Перезагрузить" - say redraw "Обновить" - - say canvasreload "Перезагрузить" - say canvasredraw "Обновить" - -say find "Поиск" - say find_again "Найти ещё" - say find_last_error "Найти последнею ошибку" - say string "Искать текст" -say canvasfind "Найти" - say canvasfind_again "Найти ещё" - -# contents of Put menu is Phase 5C -say put "Положить" - say Object "Обьект" - say Message "Сообщение" - say Number "Номер" - say Symbol "Символ" - say Comment "Комментарий" - say Graph "Пустая графа" - say Array "Графа с данными" - -say media "Мотор" - say audio_on "ВКЛ звук" - say audio_off "ВЫКЛ звук" - say test_audio_and_midi "Проверка аудио и MIDI" - say load_meter "Измеритель загруженности" - - say canvasaudio_on "ВКЛ звук" - say canvasaudio_off "ВЫКЛ звук" - say clienttest_audio_and_midi "Проверка звука и MIDI" - say canvasload_meter "загруз. метр" - -say window "Окна" - -say help "Помощь" - say about "О программе..." - say documentation "Документация..." - say class_browser "Браузер классов..." - - say canvasabout "О программе..." - -say properties "Свойства" -say open "Открыть" - -### for key binding editor -say general "Общее" -say audio_settings "Настройки звука" -say midi_settings "Настройки MIDI" -say latency_meter "Измеритель опозданий" -say Pdwindow "Основное окно" - -say canvaspdwindow "Основное окно" -say canvaslatency_meter "Измеритель задержек" -say clientaudio_settings "Настройки аудио" -say clientmidi_settings "Настройки MIDI" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "ширина, px" -say h "высота, px" -say hold "время удержки, мс" -say break "break time, мс" -say min "наименьшее значение" -say max "наибольшее значение" -say is_log "режим" -say linear "линейный" -say logarithmic "логорифмичекий" -say isa "init" -say n "колличество вариантов" -say steady "стойкость" -say steady_no "сдвиг при клике" -say steady_yes "стойкий при клике" -say snd "отправлять с символом" -say rcv "получать по сиволу" -say lab "название" -say ldx "смещение названия Х" -say ldy "смещение названия У" -say fstyle "шрифт" -say fs "размер шрифта" -say bcol "цвет фона" -say fcol "основной цвет" -say lcol "цвет названия" -say yes "да" -say no "нет" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "graph on parent" - -say_category GAtomProperties -say width "ширина" -say lo "нижний предел" -say hi "верхний предел" -say label "обозначение" -say wherelabel "отображать" -say symto "отправлять с символом" -say symfrom "получать по сиволу" - -say_category GraphProperties -say x1 "значения x с" -say x2 "x до" -say xpix "ширина" -say y2 "значения y с" -say y1 "y до" -say ypix "высота" - -say_category CanvasProperties -#say xscale "X units/px" -#say yscale "Y units/px" -say gop "graph on parent" -say xmargin "предел по оси X" -say ymargin "предел по оси Y" -say height "высота" -say_category ArrayProperties -say name "название" -say n "размер" -say xfrom "значения x с" -say xto "значения x до" -say yfrom "значения у с" -say yto "значения у до" - - -say_category MainWindow -say in "вход" -say out "выход" -say audio "Аудио" -say meters "Уровни" -say io_errors "Ошибки на входе и выходе" -say tcl_console "клиент Tcl" -say pd_console "pd сервер" - -### phase 2 - -say_category Other -say_namespace summary { - say_category IEMGUI - say bng "Bang Box" - say tgl "Toggle Box" - say nbx "Number Box (IEM)" - say hsl "Slider (Горизонтальный)" - say vsl "Slider (Вертикальный)" - say hradio "Choice Box (Горизонтальный)" - say vradio "Choice Box (Вертикальный)" - say cnv "Полотно (IEM)" - say dropper "Drag-and-Drop Box" - say vu "Уровень громкости (VU-meter)" - - say_category GLUE - say bang "выдать 'bang'" - say float "store and recall a number" - say symbol "store and recall a symbol" - say int "сохранить число" - say send "отсылка сообсчений с символы" - say receive "приём отосланных сообсчений по символу" - say select "test for matching numbers or symbols" - say route "route messages according to first element" - say pack "make compound messages" - say unpack "get elements of compound messages" - say trigger "sequence and convert messagess" - say spigot "прерываемый поток сообщений" - say moses "разбить поток чисел" - say until "механизм кругового действия" - say print "текстовый вывод" - say makefilename "создать текст с переменными полями" - say change "убрать повторяющееся число из потока" - say swap "поменять два числа местами" - say value "сохранить обсщедоступную переменную с заданным именем" - - say_category TIME - say delay "выдавать соовщение с заданной задержкой" - say metro "выдавать переодическое соовщение с заданным интервалом" - say line "выдать линейную прогрессию" - say timer "отмерить временной промеуток" - say cputime "отмерить промежуток по процесорному времени" - say realtime "отмерить реальный временной промежуток" - say pipe "динамически нарастающий накопитель чисел с задержкой вывода" - - say_category MATH - say + "сумма" - say - "разность" - say * "произведение" - say {/ div} "частное" - say {% mod} "деление с остатком" - say pow "возвести в стапань" - say == "равно?" - say != "не равно?" - say > "больше?" - say < "меньше?" - say >= "не меньше?" - say <= "не больше?" - say & "bitwise conjunction (and)" - say | "bitwise disjunction (or)" - say && "logical conjunction (and)" - say || "logical disjunction (or)" - say mtof "MIDI > Герцы" - say ftom "Герцы > MIDI" - say powtodb "Ватты > dB" - say dbtopow "dB > Ватты" - say rmstodb "Вольты > dB" - say dbtorms "dB > Вольты" - say {sin cos tan atan atan2 sqrt} "Тригонометрические функции" - say log "Натуральный логоритм" - say exp "Экспонента Эвлера" - say abs "Значение по модулю" - say random "Случайное число" - say max "Наибольшее из двух" - say min "Наименьшее из дцух" - say clip "Ограничить значения в потоке чисел" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI вход" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI выход" - say makenote "schedule a delayed \"note off\" message corresponding to a note-on" - say stripnote "strip \"note off\" messages" - - say_category TABLES - say tabread "получить значение из таблицы (по индексу)" - say tabread4 "read a number from a table, with 4 point interpolation" - say tabwrite "вписать значение в таблицу" - say soundfiler "считывать аудио-файл в/из таблиц" - - say_category MISC - say loadbang "выдать 'bang' при загрузке" - say serial "доступ к серийному порту (только в NT)" - say netsend "посылать сообщения по сети (по TCP или UDP)" - say netreceive "получать сообщения из сети (по TCP или UDP)" - say qlist "message sequencer" - say textfile "file to message converter" - say openpanel "диалоговое окно \"Открыть\"" - say savepanel "диалоговое окно \"Save as\"" - say bag "набор чисел" - say poly "полифонизатор" - say {key keyup} "числовые значения клавиш клавиатуры" - say keyname "именные значения клавиш" - - say_category "AUDIO MATH" - foreach word {+ - * /} {say $word~ "[say $word] (для сигналов)"} - say max~ "supremum of signals" - say min~ "infimum of signals" - say clip~ "ограничить амплитуду сигнала" - say q8_rsqrt~ "упрощенный алгоритм (8 бит) обратного квадратного корня" - say q8_sqrt~ "упрощенный алгоритм (8 бит) квадратного корня" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "вещественный обратный inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category GLUE - say dac~ "аудио выход" - say adc~ "аудио вход" - say sig~ "превратить число в сигнал" - say line~ "generate audio ramps" - say vline~ "улучшенный line~" - say threshold~ "detect signal thresholds" - say snapshot~ "семплироавть сигнал (представить в виде числа)" - say vsnapshot~ "улучшенный snapshot~" - say bang~ "посылать 'bang' с каждым аудио-блоком" - say samplerate~ "узнать частоту дискретизации" - say send~ "отослать сигнал для удалённого приёма" - say receive~ "получить отосланный сигнал" - say throw~ "отослать сигнал в суммарный канал" - say catch~ "считывать с суммарного канала" - say block~ "размер аудио-блока и нахлестки" - say switch~ "switch DSP computation on and off" - say readsf~ "чтение с диска" - say writesf~ "запись на диск" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "генератор пилообразного сигнала" - say {cos~ osc~} "генератор синусодального сигнала" - say tabwrite~ "писать сигнал в таблицу" - say tabplay~ "play back from a table (non-transposing)" - say tabread~ "non-interpolating table read" - say tabread4~ "four-point interpolating table read" - say tabosc4~ "табличный вибратор" - say tabsend~ "постоянно вписывать блок в таблицу" - say tabreceive~ "постоянно считывать блок из таблицы" - - say_category "AUDIO FILTERS" - say vcf~ "фильтр контролирумый напряжением" - say noise~ "генератор \"белого\" шума" - say env~ "envelope follower" - say hip~ "high pass filter" - say lop~ "low pass filter" - say bp~ "band pass filter" - say biquad~ "raw filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (комплексный)" - say czero~ "[say rzero~] (комплексный)" - say czero_rev~ "[say rzero_rev~] (комплексный)" - - say_category "AUDIO DELAY" - say delwrite~ "write to a delay line" - say delread~ "read from a delay line" - say vd~ "read from a delay line at a variable delay time" - - say_category "SUBWINDOWS" - say pd "новое окно" - say table "таблица в новом окне" - say inlet "добавляет впуск" - say outlet "добавляет выпуск" - say inlet~ "[say inlet] (для сигналов)" - say outlet~ "[say outlet] (для сигналов)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "начертить кривую" - say {drawpolygon filledpolygon} "начертить многоугольник" - say plot "plot an array field" - say drawnumber "print a numeric value" - - say_category "Доступ к данным" - say pointer "указать на объект в шаблоне" - say get "получить численное значение" - say set "изменить численное значение" - say element "получить значение из таблицы" - say getsize "получить размер таблицы" - say setsize "изменить размер таблицы" - say append "добавить к списку" - say sublist "get a pointer into a list which is an element of another scalar" - say scalar "draw a scalar on parent" - - say_category "Ныне отсутсвующее" - say scope~ "(теперь используется tabwrite~)" - say namecanvas "именовать полотно" ;# what was this anyway? - say template "(теперь используется struct)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "частота дискретизации" - say -audioindev "аудио вход" - say -audiooutdev "аудио выход" - say -inchannels "кол-во входных каналов (в соответствии с устройствами, на пример: \"2\" или \"16,8\")" - say -outchannels "кол-во выходных каналов" - say -audiobuf "размер сигнального буфера (милисек)" - say -blocksize "указать размер аудио-блока в сэмпл-фреймах" - say -sleepgrain "указать время (милисек) для перехода в режим сна когда неактивен" - say -nodac "предотвратить звук на входе (при запуске)" - say -noadc "предотвратить звук на выходе (при запуске)" - say audio_api_choice "Выбор аудио API" - say default "по умолчанию" - say -alsa "использовать ALSA аудио API" - say -jack "использовать JACK аудио API" - say -mmio "использовать MMIO API (в Windows, по-умолчанию)" - say -portaudio "использовать дарйвера ASIO (при помощи Portaudio)" - say -oss "использовать OSS аудио API" - say -32bit "включить 32-битный режим аудио (OSS, для карт RME Hammerfall)" - say {} "по умолчанию" - -say section_midi "MIDI" - say -nomidiin "предотвратить MIDI вход" - say -nomidiout "предотвратить MIDI выход" - say -midiindev "midi in device list; e.g., \"1,3\" for first and third" - say -midioutdev "midi out device list, same format" - -say section_externals "Расширения" - say -path "путь поиска файлов" - say -helppath "путь поиска вспомогательных примеров" - say -lib "загрузить библиотеку (по имени)" - -say section_gui "Графический интерфейс" - say -nogui "отключит графический интерфейс" - say -guicmd "запуск с использованием иной программы (например: rsh или ssh)" - say -look "иконки на панельке" - say -font "размер шрифта в точках" - -say section_other "Остальное" - say -open "открыть файл(ы) при запуске" - say -verbose "вывод дополнительной информации" - say -d "уровень debug" - say -noloadbang "отключить действие \[loadbang\]" - say -send "послать сообсчение при запуске (как только все патчи загружены)" - say -listdev "вывод доступных аудио и MIDI устройств" - say -realtime "исполнение в \"реальном времени\" (требует привелегий спец-пользователя)" - -say section_paths "Путь" - -# phase 4B: ddrc (keyword names not finalized!) -say console "колличество полос памяти на консоли (0 = отключить консоль)" -say lang "язык" -say pointer_sense "чувствительность курсора" -say section_color "вид" - say canvas_color "полотно" - say canvasbgedit "цвет фона в режиме редактора" - say canvasbgrun "цвет фона в режиме исполнения" - say object_color "объект" - say viewframe1 "цвет рамки" - say viewframe2 "цвет рамки" - say viewframe3 "цвет рамки" - say viewframe4 "цвет выделенной рамки" - say viewbg "цвет фона объекта" - say viewfg "основной цвет объекта" - say commentbg "фон комментария" - say commentfg "цвет текста комментария" - say commentframe1 "рамка комментария" - say commentframe2 "рамка комментария" - say commentframe3 "рамка комментария" - say viewselectframe "выделенная рамка" - say wire_color "провод" - say wirefg "цвет провода" - say wirefg2 "выделенный провод" - say wiredspfg "цвет провода несущего сигнал" - say futurewiredash "новый провод (пунктиром)" - say others_color "другое" - say boxinletfg "цвет inlet" - say boxoutletfg "цвет outlet" - say selrectrect "выделение" -say keys "клавиши" -say others "другие" -say hairstate "включить крестик (crosshair)" -say hairsnap "crosshair snap to object" -say statusbar "включить строку статуса" -say buttonbar "включить панельку кнопок" -say menubar "включить менюшку" -say scrollbar "включить автопромотку" -say wirearrow "wire стрелка" -say tooltip "подсказки" -say insert_object "Вставить объект" -say chain_object "Цепочка оьектов" -say clear_wires "Прибрать провода" -say auto_wire "Удалить объект" -say subpatcherize "Превратить в суб-патч" -say keynav "Навигация припомощи клавиатуры" -say key_nav_up "вверх" -say key_nav_up_shift "выделение с добавкой" -say key_nav_down "вниз" -say key_nav_down_shift "выделение с добавкой" -say key_nav_right "направо" -say key_nav_right_shift "выделение с добавкой" -say key_nav_left "налево" -say key_nav_left_shift "выделение с добавкой" -say key_nav_ioselect "select in/outlets" -# phase 5A - -say cannot "Не получается .." -say cancel "Сброс" -say apply "Применить" -say ok "Окей" -say popup_open "Открыть" -say popup_insert "Вставить" -say popup_properties "Свойства" -say popup_clear_wires "Прибрать провода" -say popup_remove_from_path "Remove object from path" -say popup_delete_from_path "Delete object from path" -say popup_help "Помощь" -say filter "Фильтровать: " -say how_many_object_classes "%d из %d классов объектов" -say do_what_i_mean "Сделай всё!" -say ask_cool "Было бы круто добавить такой наворот! Не так ли?" -say save_changes? "Сохранить?" -say reset "Сброс" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Добавить" -say up "Вверх" -say down "Вниз" -say remove "Удалить" -say lib_add "добавить к списку" -say lib_up "поменять местами с предыдущей библиотекой" -say lib_down "поменять местами со следующей библиотекой" -say lib_remove "удалить выбранную библиотеку" -say dir_add "указать местонахождения" -say dir_up "поменять местами с предыдущей папкой" -say dir_down "поменять местами со следующей папкой" -say dir_remove "удалить из списка" -say client_class_tree "Дерево классов" -say clipboard_view "Clipboard View" -say command_history_view "Просмотр истории команд" -say event_history_view "Просмотр истории событий" - -# during/after piksel: - -say auto_apply "Автопримение" -say font_preview "Просмотр:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Стиль:" -say font_bold "Жирный" -say font_italic "Курсивом" -say font_family "Название:" -say font_size "Размер:" -say damn "Эх!" -# say damn "Нах!" -# say damn "Тьфу! Да ну тебя!" -say console_clear "Очистить консоль" -say horizontal "Горизонталь" -say vertical "Вертикаль" -say language "Язык" - -# 2007: - -say no_matches "(совпадений нет)" -say preset "preset" -say canvasgrid "цвет клеток" -say grid_size "размер клеточки" -say gridstate "показать клеточки" -say snap_grid "подгонка под клетки" -say viewfont "шрифт имён объектов" -say consolefont "консольный шрифт" -say keyboarddialogfont "шрифт разметки виртуальной клавиатуры" -say keyboard_view "Виртуальные клавиши" diff --git a/desiredata/src/locale/turkce.tcl b/desiredata/src/locale/turkce.tcl deleted file mode 100644 index e33cb235..00000000 --- a/desiredata/src/locale/turkce.tcl +++ /dev/null @@ -1,572 +0,0 @@ -#!/usr/bin/env tclsh -# Turkish translations for PureData -# $Id: turkce.tcl,v 1.1.2.1 2007-10-05 23:14:23 matju Exp $ -# by Koray Tahiroglu - -### Menus - -say file "Dosya" - say new_file "Yeni" - say open_file "Aç..." - say server_prefs "Sunucu Tercihleri..." - say client_prefs "Kullanıcı Tercihleri..." - say send_message "Mesajı Gönder..." - say paths "Yollar..." - say close "Kapat" - say save "Kaydet" - say save_as "Farklı Kaydet..." - say print "Yazdır..." - say abort_server "Sunucuyu Durdur" - say quit "Çıkış" - - say canvasnew_file "Yeni" - say canvasopen_file "Aç..." - say canvassave "Kaydet" - say canvassave_as "Farklı Kaydet..." - say clientpdrc_editor ".pdrc Düzenleyicisi" - say clientddrc_editor ".ddrc Düzenleyicisi" - say canvasclose "Kapat" - say canvasquit "Çıkış" - -say edit "Düzen" - say undo "Geri Al" - say redo "Yeniden Yap" - say cut "Kes" - say copy "Kopyala" - say paste "Yapıştır" - say duplicate "Çoğalt" - say select_all "Tümünü Seç" - say clear_selection "Seçimi Kaldır" - say text_editor "Not Defteri..." - say font "Yazı Tipi" - say tidy_up "Derle Toparla" - say edit_mode "Düzenleme Durumu" - say editmodeswitch "Düzenleme/Çalıştırma Durumu" - say subpatcherize "Alt-Bağlantı" - - say canvascut "Kes" - say canvascopy "Kopyala" - say canvasundo "Geri Al" - say canvasredo "Yeniden Yap" - say canvaspaste "Yapıştır" - say canvasduplicate "Çoğalt" - say canvasselect_all "Tümünü Seç" - say canvaseditmodeswitch "Düzenleme/Çalıştırma Durumu" - -say view "Görünüm" - say reload "Yeniden Yükle" - say redraw "Yeniden Çiz" - - say canvasreload "Yeniden Yükle" - say canvasredraw "Yeniden Çiz" - -say find "Bul" - say find_again "Sonrakini Bul" - say find_last_error "En Son Hatayı Bul" - say string "Diziyi Bul" -say canvasfind "Bul" - say canvasfind_again "Sonrakini Bul" - -# contents of Put menu is Phase 5C -say put "Yerleştir" - say Object "Nesne" - say Message "Mesaj" - say Number "Sayı" - say Symbol "Simge" - say Comment "Not" - say Graph "Grafik" - say Array "Dizilim" - -say media "Ortam" - say audio_on "Ses Aç" - say audio_off "Ses Kapat" - say test_audio_and_midi "Ses ve MIDI Testi" - say load_meter "Ölçeri Yükle" - - say canvasaudio_on "Ses Aç" - say canvasaudio_off "Ses Kapat" - say clienttest_audio_and_midi "Ses ve MIDI Testi" - say canvasload_meter "Ölçeri Yükle" - -say window "Pencere" - -say help "Yardım" - say about "Hakkında..." - say documentation "Belgeleme..." - say class_browser "Sınıf Gözatıcısı..." - - say canvasabout "Hakkında..." - -say properties "Özellikler" -say open "Aç" - -### for key binding editor -say general "Genel" -say audio_settings "Ses Ayarları" -say midi_settings "Midi Ayarları" -say latency_meter "Gecikme Ölçeri" -say Pdwindow "Pd penceresi" - -say canvaspdwindow "Pd penceresi" -say canvaslatency_meter "Gecikme Ölçeri" -say clientaudio_settings "Ses Ayarları" -say clientmidi_settings "Midi Ayarları" - -### for Properties Dialog (phase 5B) -say_category IEM -say w "genişlik(px)" -say h "yükseklik(px)" -say hold "tutma zamanı(ms)" -say break "kesme zamanı(ms)" -say min "en az değer" -say max "en fazla değer" -say is_log "durum" -say linear "doğrusal" -say logarithmic "logaritmik" -say isa "init" -say n "seçenek sayısı" -say steady "kararlı" -say steady_no "tıklama ile sıçra" -say steady_yes "tıklama ile kararli ol" -say snd "simge-gönder" -say rcv "simge-al" -say lab "Etiket" -say ldx "Etiket x kaydır" -say ldy "Etiket y kaydır" -say fstyle "Yazı Biçimi" -say fs "Yazitippi boyutu" -say bcol "arkaplan rengi" -say fcol "önalan rengi" -say lcol "Etiket rengi" -say yes "evet" -say no "hayır" -say courier "courier (typewriter)" -say helvetica "helvetica (sansserif)" -say times "times (serif)" -say coords "üstteki grafik" - -say_category GAtomÖzellikleri -say width "genişlik" -say lo "alt sınır" -say hi "üst sınır" -say label "etiket" -say wherelabel "etiket göster" -say symto "simge gönder" -say symfrom "simge al" - -say_category GrafikÖzellikleri -say x1 "x'den" -say x2 "x'e" -say xpix "görüntü alanı genişliği" -say y2 "y'den" -say y1 "y'e" -say ypix "görüntü alanı yükselkiği" - -say_category KanavaÖzellikleri -#say xscale "X birim/px" -#say yscale "Y birim/px" -say gop "üstteki grafik" -say xmargin "x-kenar boşluğu" -say ymargin "y-kenar boşluğu" -say height "yükseklik" -say_category DizilimÖzellikleri -say name "adı" -say n "boyutu" -say xfrom "x aralığından" -say xto "x aralığına" -say yfrom "y aralığından" -say yto "y aralığına" - - -say_category AnaPencere -say in "giriş" -say out "çıkış" -say audio "Ses" -say meters "Ölçerler" -say io_errors "IO Hataları" -say tcl_console "Tcl Kullanıcısi" -say pd_console "Pd Sunucusu" - -### phase 2 - -say_category Diğer -say_namespace özet { - say_category IEMGUI - say bng "Patlama Kutusu" - say tgl "Düğme Kutusu" - say nbx "Sayı Kutusu (IEM)" - say hsl "Kaydırıcı (yatay)" - say vsl "Kaydırıcı (düşey)" - say hradio "Seçme Kutusu (yatay)" - say vradio "Seçme Kutusu (düşey)" - say cnv "Kanava (IEM)" - say dropper "Taşı-ve-Bırak Kutusu" - say vu "Vumeter" - - say_category GLUE - say bang "patlama mesajı ver" - say float "sayıyı sakla ve yeniden çağır" - say symbol "simgeyi sakla ve yeniden çağır" - say int "tamsayıyı sakla ve yeniden çağır" - say send "isimlendirilmiş bir nesneye mesaj gönder" - say receive "gönderilen mesajları al" - say select "eşleşen sayı ve simgeler için test" - say route "ilk öğelerine göre mesajları yönlendir" - say pack "make bileşik mesajlar oluştur" - say unpack "get elements of compound messages" - say trigger "mesajları sırala ve dönüştür" - say spigot "kesilebilir mesaj bağlantısı" - say moses "sayısal akımı ayır" - say until "döngü meaknizması" - say print "mesajları yazdır" - say makefilename "simgeyi bir değişken alanı ile biçimlendir" - say change "tekrar edilen sayıları akımdan ayır" - say swap "iki sayıyı takas et" - say value "paylaşılan sayısal değer" - - say_category ZAMAN - say delay "zaman geciktirmesi sonunda mesaj gönder" - say metro "belirli aralıklarla mesaj gönder" - say line "send a series of linearly stepped numbers" - say timer "zaman aralıklarını hesapla" - say cputime "CPU zamanını hesapla" - say realtime "gerçek zamanı hesapla" - say pipe "sayılar için dinamik olarak büyüyen gecikme hattı" - - say_category MATEMATİK - say + "topla" - say - "çıkart" - say * "çarp" - say {/ div} "böl" - say {% mod} "bölümden kalan" - say pow "üs al" - say == "eşit?" - say != "eşit değil?" - say > "büyük?" - say < "küçük?" - say >= "küçük değil?" - say <= "büyük değil?" - say & "bit olarak birleşme (and)" - say | "bit olarak ayırtım (or)" - say && "mantıksal birleşme (and)" - say || "mantıksal ayırtım (or)" - say mtof "MIDI'den Hertz'e" - say ftom "Hertz'den MIDI'ye" - say powtodb "Watts'dan dB'e" - say dbtopow "dB'den Watts'a" - say rmstodb "Gerilimden dB'e" - say dbtorms "dB'den Gerilime" - say {sin cos tan atan atan2 sqrt} "trigonometri" - say log "Euler logaritma" - say exp "Euler Üssel" - say abs "mutlak değer" - say random "rasgele" - say max "iki sayının en büyüğü" - say min "iki sayının en küçüğü" - say clip "sayıyı belirli bir değer aralığına indirge" - - say_category MIDI - say {notein ctlin pgmin bendin touchin polytouchin midiin sysexin} "MIDI giriş" - say {noteout ctlout pgmout bendout touchout polytouchout midiout} "MIDI çıkış" - say makenote " note-on a uygun olarak gecikmeli bir \"note off\" mesajı düzenle" - say stripnote "strip \"note off\" mesajı" - - say_category TABLOLAR - say tabread "tablodan bir sayı oku" - say tabread4 "tablodan 4 noktalı aradeğerleme ile sayı oku" - say tabwrite "tabloya bir sayı yaz" - say soundfiler "tabloları ses dosyalarına yaz ve oku" - - say_category MISC - say loadbang "yüklendiği zaman patlama gönder" - say serial "yalnızca NT için dizisel aygıt kontrolü" - say netsend "internet üzerinden mesaj gönder" - say netreceive "internet üzerinden mesaj al" - say qlist "mesaj ardıştırıcısı" - say textfile "dosyayı mesaja çevirici" - say openpanel "\"Aç\" diyalog" - say savepanel "\"Farklı Kaydet\" diyalog" - say bag "sayılar kümesi" - say poly "çoksesli ses ayırması" - say {key keyup} "klavyeden sayısal tuş değerleri" - say keyname "simgelsel tuş ismi" - - say_category "Ses Matematiği" - foreach word {+ - * /} {say $word~ "[say $word] (sinyaller için)"} - say max~ "sinyallerin enyükseği" - say min~ "sinyallerin en düşüğü" - say clip~ "sinyalin iki sınır arasında yer almasının sağlanması" - say q8_rsqrt~ "indirimli ters karekökü (dikkat -- 8 bits!)" - say q8_sqrt~ "ndirimli karekök (dikkat -- 8 bits!)" - say wrap~ "wraparound (fractional part, sort of)" - say fft~ "complex forward discrete Fourier transform" - say ifft~ "complex inverse discrete Fourier transform" - say rfft~ "real forward discrete Fourier transform" - say rifft~ "real inverse discrete Fourier transform" - say framp~ "output a ramp for each block" - foreach word {mtof ftom rmstodb dbtorms rmstopow powtorms} { - say $word~ "[say $word] (for signals)" - } -} - -### phase 3 - -say_namespace summary { - say_category "AUDIO GLUE" - say dac~ "audio output" - say adc~ "audio input" - say sig~ "convert numbers to audio signals" - say line~ "generate audio ramps" - say vline~ "deluxe line~" - say threshold~ "detect signal thresholds" - say snapshot~ "sample a signal (convert it back to a number)" - say vsnapshot~ "deluxe snapshot~" - say bang~ "send a bang message after each DSP block" - say samplerate~ "get the sample rate" - say send~ "nonlocal signal connection with fanout" - say receive~ "get signal from send~" - say throw~ "add to a summing bus" - say catch~ "define and read a summing bus" - say block~ "specify block size and overlap" - say switch~ "switch DSP computation on and off" - say readsf~ "soundfile playback from disk" - say writesf~ "record sound to disk" - - say_category "AUDIO OSCILLATORS AND TABLES" - say phasor~ "sawtooth oscillator" - say {cos~ osc~} "cosine oscillator" - say tabwrite~ "write to a table" - say tabplay~ "play back from a table (non-transposing)" - say tabread~ "non-interpolating table read" - say tabread4~ "four-point interpolating table read" - say tabosc4~ "wavetable oscillator" - say tabsend~ "write one block continuously to a table" - say tabreceive~ "read one block continuously from a table" - - say_category "AUDIO FILTERS" - say vcf~ "voltage controlled filter" - say noise~ "white noise generator" - say env~ "envelope follower" - say hip~ "high pass filter" - say lop~ "low pass filter" - say bp~ "band pass filter" - say biquad~ "raw filter" - say samphold~ "sample and hold unit" - say print~ "print out one or more \"blocks\"" - say rpole~ "raw real-valued one-pole filter" - say rzero~ "raw real-valued one-zero filter" - say rzero_rev~ "[say rzero~] (time-reversed)" - say cpole~ "[say rpole~] (complex-valued)" - say czero~ "[say rzero~] (complex-valued)" - say czero_rev~ "[say rzero_rev~] (complex-valued)" - - say_category "AUDIO DELAY" - say delwrite~ "write to a delay line" - say delread~ "read from a delay line" - say vd~ "read from a delay line at a variable delay time" - - say_category "SUBWINDOWS" - say pd "define a subwindow" - say table "array of numbers in a subwindow" - say inlet "add an inlet to a pd" - say outlet "add an outlet to a pd" - say inlet~ "[say inlet] (for signal)" - say outlet~ "[say outlet] (for signal)" - - say_category "DATA TEMPLATES" - say struct "define a data structure" - say {drawcurve filledcurve} "draw a curve" - say {drawpolygon filledpolygon} "draw a polygon" - say plot "plot an array field" - say drawnumber "print a numeric value" - - say_category "ACCESSING DATA" - say pointer "point to an object belonging to a template" - say get "get numeric fields" - say set "change numeric fields" - say element "get an array element" - say getsize "get the size of an array" - say setsize "change the size of an array" - say append "add an element to a list" - say sublist "get a pointer into a list which is an element of another scalar" - say scalar "draw a scalar on parent" - - say_category "OBSOLETE" - say scope~ "(use tabwrite~ now)" - say namecanvas "" ;# what was this anyway? - say template "(use struct now)" -} - -# phase 4 (pdrc & ddrc) - -say section_audio "Audio" - say -r "sample rate" - say -audioindev "audio in devices" - say -audiooutdev "audio out devices" - say -inchannels "audio input channels (by device, like \"2\" or \"16,8\")" - say -outchannels "number of audio out channels (same)" - say -audiobuf "specify size of audio buffer in msec" - say -blocksize "specify audio I/O block size in sample frames" - say -sleepgrain "specify number of milliseconds to sleep when idle" - say -nodac "suppress audio output" - say -noadc "suppress audio input" - say audio_api_choice "Audio API" - say default "default" - say -alsa "use ALSA audio API" - say -jack "use JACK audio API" - say -mmio "use MMIO audio API (default for Windows)" - say -portaudio "use ASIO audio driver (via Portaudio)" - say -oss "use OSS audio API" - say -32bit "allow 32 bit OSS audio (for RME Hammerfall)" - say {} "default" - -say section_midi "MIDI" - say -nomidiin "suppress MIDI input" - say -nomidiout "suppress MIDI output" - say -midiindev "midi in device list; e.g., \"1,3\" for first and third" - say -midioutdev "midi out device list, same format" - -say section_externals "Externals" - say -path "file search path" - say -helppath "help file search path" - say -lib "load object libraries" - -say section_gui "Gooey" - say -nogui "suppress starting the GUI (caution)" - say -guicmd "substitute another GUI program (e.g., rsh)" - say -look "buttonbar icons" - say -font "specify default font size in points" - -say section_other "Other" - say -open "open file(s) on startup" - say -verbose "extra printout on startup and when searching for files" - say -d "debug level" - say -noloadbang "disable the effect of \[loadbang\]" - say -send "send a message at startup (after patches are loaded)" - say -listdev "list audio and MIDI devices upon startup" - say -realtime "use real-time priority (needs root privilege)" - -say section_paths "Paths" - -# phase 4B: ddrc (keyword names not finalized!) -say console "console scrollback lines (0 = disable console)" -say lang "Language to use" -say pointer_sense "Mouse pointer sensitivity" -say section_color "Apparences" - say canvas_color "canvas" - say canvasbgedit "canvas background (edit mode)" - say canvasbgrun "canvas background (run mode)" - say object_color "object" - say viewframe1 "objectbox color" - say viewframe2 "objectbox color" - say viewframe3 "objectbox color" - say viewframe4 "objectbox highlight color" - say viewbg "object background" - say viewfg "object foreground" - say commentbg "comment background" - say commentfg "comment forground" - say commentframe1 "comment frame" - say commentframe2 "comment frame" - say commentframe3 "comment frame" - say viewselectframe "hilight box" - say wire_color "wire" - say wirefg "wire color" - say wirefg2 "wire highlight" - say wiredspfg "dsp wire color" - say futurewiredash "new (dashed) wire" - say others_color "others" - say boxinletfg "inlet color" - say boxoutletfg "outlet color" - say selrectrect "selection box" -say keys "keys" -say others "others" -say hairstate "Activate crosshair" -say hairsnap "Crosshair snap to object" -say statusbar "Activate statusbar" -say buttonbar "Activate buttonbar" -say menubar "Activate menubar" -say scrollbar "Active auto scrollbar" -say wirearrow "Wire Arrow" -say tooltip "ToolTip" -say insert_object "Insert object" -say chain_object "Chain object" -say clear_wires "Clear wires" -say auto_wire "Remove object" -say subpatcherize "Subpatcherize" -say keynav "keyboard navigation" -say key_nav_up "move up" -say key_nav_up_shift "plus select" -say key_nav_down "move down" -say key_nav_down_shift "plus select" -say key_nav_right "move right" -say key_nav_right_shift "plus select" -say key_nav_left "move left" -say key_nav_left_shift "plus select" -say key_nav_ioselect "select in/outlets" -# phase 5A - -say cannot "can't" -say cancel "Cancel" -say apply "Apply" -say ok "OK" -say popup_open "Open" -say popup_insert "Insert" -say popup_properties "Properties" -say popup_clear_wires "Clear wires" -say popup_remove_from_path "Remove object from path" -say popup_delete_from_path "Delete object from path" -say popup_help "Help" -say filter "Filter: " -say how_many_object_classes "%d of %d object classes" -say do_what_i_mean "Do What I Mean" -say ask_cool "This would be a cool feature, eh?" -say save_changes? "Save changes?" -say reset "Reset" -say Courier "Courier (monospaced)" -say Helvetica "Helvetica (sansserif)" -say Times "Times (serif)" -say add "Add" -say up "Up" -say down "Down" -say remove "Remove" -say lib_add "add the name you typed to the list" -say lib_up "swap order with previous library" -say lib_down "swap order with next library" -say lib_remove "remove library selected in the list" -say dir_add "add a folder using a file dialog" -say dir_up "swap order with previous folder" -say dir_down "swap order with next folder" -say dir_remove "remove folder selected in the list" -say client_class_tree "Client Class Tree" -say clipboard_view "Clipboard View" -say command_history_view "Command History View" -say event_history_view "Event History View" - -# during/after piksel: - -say auto_apply "Auto-Apply" -say font_preview "Preview:" -say font_preview_2 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789" -say font_style "Style:" -say font_bold "Bold" -say font_italic "Italic" -say font_family "Name:" -say font_size "Size:" -say damn "Damn!" -say console_clear "Clear Console" -say horizontal "Horizontal" -say vertical "Vertical" -say language "Language" - -# 2007: - -say no_matches "(no matches)" -say preset "preset" -say canvasgrid "Grid color" -say grid_size "Grid size" -say gridstate "Activate background grid" -say snap_grid "Snap to grid" -say viewfont "object font" -say consolefont "console font" -say keyboarddialogfont "virtual keyboard font" -say keyboard_view "Virtual keyboard"
\ No newline at end of file diff --git a/desiredata/src/m_atomic.h b/desiredata/src/m_atomic.h deleted file mode 100644 index f7314d11..00000000 --- a/desiredata/src/m_atomic.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2005, Tim Blechmann - * For information on usage and redistribution, and for a DISCLAIMER OF ALL - * WARRANTIES, see the file, "LICENSE.txt" in this distribution. */ - - -#if defined(__GNUC__) && (defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)) - -/* gcc, x86 */ -#define ATOMIC_INC(X) \ - asm __volatile__("lock incl (%0) \n" \ - : :"r"(X) :"memory") - - -#define ATOMIC_DEC(X) \ - asm __volatile__("lock decl (%0) \n" \ - : :"r"(X) :"memory") - - - -#elif defined(NT) && defined(_MSC_VER) - -/* msvc */ -#include <windows.h> -#define ATOMIC_INC(X) InterlockedIncrement(X) -#define ATOMIC_DEC(X) InterlockedDecrement(X) - - -#elif defined(__GNUC__) && defined(__POWERPC__) - -/* ppc */ -#define ATOMIC_INC(X) { \ -int X##_i; \ -asm __volatile__( \ - "1: \n" \ - "lwarx %0, 0, %2 \n" \ - "addic %0, %0, 1 \n" \ - "stwcx. %0, 0, %2 \n" \ - "bne- 1b \n" \ - :"=&r"(X##_i), "=m"(X) \ - : "r" (&X), "m"(X) \ - : "cc"); } - - -#define ATOMIC_DEC(X) { \ -int X##_i; \ -asm __volatile__( \ - "1: \n" \ - "lwarx %0, 0, %2 \n" \ - "addic %0, %0, -1 \n" \ - "stwcx. %0, 0, %2 \n" \ - "bne- 1b \n" \ - :"=&r"(X##_i), "=m"(X) \ - : "r" (&X), "m"(X) \ - : "cc"); } -#endif diff --git a/desiredata/src/m_fifo.c b/desiredata/src/m_fifo.c deleted file mode 100644 index 34d19d1b..00000000 --- a/desiredata/src/m_fifo.c +++ /dev/null @@ -1,443 +0,0 @@ -/* Copyright (c) 2004, Tim Blechmann - * supported by vibrez.net - * For information on usage and redistribution, and for a DISCLAIMER OF ALL - * WARRANTIES, see the file, "LICENSE.txt" in this distribution. */ - - -#include <stddef.h> -#include <stdlib.h> -#include "m_pd.h" - -#ifndef LOCKFREE - -/* we always have the implementation for posix systems with threadlocks */ - -#include "pthread.h" -#include "errno.h" - -typedef struct _fifocell -{ - struct _fifocell* next; - void* data; /* pointer to our data */ -} t_fifocell; - -struct _fifo { - t_fifocell * head; - t_fifocell * tail; - pthread_mutex_t mutex; -}; - -t_fifo *fifo_init(void) { - t_fifo* ret = (t_fifo*)malloc(sizeof(t_fifo)); - t_fifocell * fifo_begin = (t_fifocell*)malloc(sizeof(t_fifocell)); - fifo_begin->data = 0; - fifo_begin->next = 0; - ret->head = fifo_begin; - ret->tail = fifo_begin; - pthread_mutex_init(&ret->mutex, 0); - pthread_mutex_unlock(&ret->mutex); - return ret; -} - -void fifo_destroy(t_fifo* fifo) { - void *data; - do data = fifo_get(fifo); while (data); - pthread_mutex_lock(&fifo->mutex); - pthread_mutex_destroy(&fifo->mutex); - free(fifo); - return; -} - -/* fifo_put and fifo_get are the only threadsafe functions!!! */ -void fifo_put(t_fifo* fifo, void* data) { - if (data) { - t_fifocell * cell = (t_fifocell*)malloc(sizeof(t_fifocell)); - cell->data = data; - cell->next = 0; - pthread_mutex_lock(&fifo->mutex); - fifo->tail->next = cell; - fifo->tail = cell; - pthread_mutex_unlock(&fifo->mutex); - } - return; -} - -/* this fifo_get returns 0 if the fifo is empty or locked by another thread */ -void* fifo_get(t_fifo* fifo) { - t_fifocell * cell; - void *data; - if(pthread_mutex_trylock(&fifo->mutex) != EBUSY) { - cell = fifo->head->next; - if (cell) { - fifo->head->next = cell->next; - if(cell == fifo->tail) - fifo->tail = fifo->head; - data = cell->data; - free(cell); - } else data = 0; - pthread_mutex_unlock(&fifo->mutex); - } else data = 0; - return data; -} - -#else /* LOCKFREE */ - -/* - lockfree fifo adapted from the midishare: Copyright � Grame 1999 - Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France - grame@rd.grame.fr -*/ - -typedef struct _fifocell { - struct _fifocell *next; - void *data; /* pointer to our data */ -} t_fifocell; - -typedef struct _lifo { - unsigned long ic; /* operation counter */ - t_fifocell* top; /* stack pointer */ - unsigned long oc; /* operation counter */ -#ifdef __POWERPC__ - long unused [5]; /* lifo size must be at least 32 bytes */ - /* to avoid livelock in multiprocessor */ -#endif -} t_lifo; - -struct _fifo { - t_lifo in; - t_lifo out; -}; - -/* platform dependent code */ - -#ifdef __SMP__ -#define LOCK lock ; -#else -#define LOCK -#endif - -#if defined(__GNUC__) && (defined(__POWERPC__) || defined(__PPC__)) - -static void* lifo_pop(t_lifo* lifo) { - register void * data; - register volatile long a, b; - register long c=0; - asm volatile ( - "# LFPOP \n" - "0: \n" - " lwarx %4, %1, %2 \n" /* creates a reservation on lf */ - " cmpwi %4, 0 \n" /* test if the lifo is empty */ - " beq- 1f \n" - " lwz %5, 0(%4) \n" /* next cell in b */ - " sync \n" /* synchronize instructions */ - " stwcx. %5, %1, %2 \n" /* if the reservation is not altered */ - /* modify lifo top */ - " bne- 0b \n" /* otherwise: loop and try again */ - "0: \n" - " lwarx %5, %1, %3 \n" /* creates a reservation on lf->count */ - " addi %5, %5, -1 \n" /* dec count */ - " sync \n" /* synchronize instructions */ - " stwcx. %5, %1, %3 \n" /* conditionnal store */ - " bne- 0b \n" - "1: \n" - " mr %0, %4 \n" - :"=r" (data), "=r" (c) - : "r" (&lifo->top), "r" (&lifo->oc), "r" (a), "r" (b), "1" (c) - : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ - /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ - /* compiles the instruction "addi 0, 0, n" as li 0, n */ - ); - return data; -} - -static void* lifo_push(register t_lifo *lifo, register void *data) { - register volatile long t1; - register long t2=0; - asm volatile ( - "# LFPUSH \n" - "0: \n" - " lwarx %0, %3, %1 \n" - " stw %0, 0(%2) \n" - " sync \n" - " stwcx. %2, %3, %1 \n" - " bne- 0b \n" - "0: \n" - " lwarx %0, %3, %4 \n" - " addi %0, %0, 1 \n" - " sync \n" - " stwcx. %0, %3, %4 \n" - " bne- 0b \n" - : "=r" (t1) - : "r" (&lifo->top), "r" (data), "r" (t2), "r" (&lifo->oc), "0" (t1) - : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ - /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ - /* compiles the instruction "addi 0, 0, n" as li 0, n */ - ); -} - -#elif defined(__ppc__) && defined(__APPLE__) - -static void *lifo_pop(t_lifo *lifo) { - register void *data; - register long a, b; - asm { - addi lifo, lifo, 4 - loop: - lwarx a, 0, lifo /* creates a reservation on lifo */ - cmpwi a, 0 /* test if the lifo is empty */ - beq- empty - lwz b, 0(a) /* next cell in b */ - sync /* synchronize instructions */ - stwcx. b, 0, lifo /* if the reservation is not altered */ - /* modify lifo top */ - bne- loop /* otherwise: loop and try again */ - - addi lifo, lifo, 4 - dec: - lwarx b, 0, lifo /* creates a reservation on lifo->count */ - addi b, b, -1 /* dec count */ - sync /* synchronize instructions */ - stwcx. b, 0, lifo /* conditionnal store */ - bne- dec - - empty: - mr data, a - } - return data; -} - -static void lifo_push (register t_lifo * lifo, register void * data) -{ - register long tmp; - asm { - addi lifo, lifo, 4 - loop: - lwarx tmp, 0, lifo /* creates a reservation on lifo */ - stw tmp, 0(data) /* link the new cell to the lifo */ - sync /* synchronize instructions */ - stwcx. data, 0, lifo /* if the reservation is not altered */ - /* modify lifo top */ - bne- loop /* otherwise: loop and try again */ - - addi lifo, lifo, 4 - inc: - lwarx tmp, 0, lifo /* creates a reservation on lifo->count */ - addi tmp, tmp, 1 /* inc count */ - sync /* synchronize instructions */ - stwcx. tmp, 0, lifo /* conditionnal store */ - bne- inc - } -} - - - -#elif defined(__GNUC__) && (defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)) - -static void* lifo_pop(t_lifo* lifo) -{ - void * data = 0; - __asm__ __volatile__ ( - "# LFPOP \n\t" - "pushl %%ebx \n\t" - "pushl %%ecx \n\t" - "movl 4(%%esi), %%edx \n\t" - "movl (%%esi), %%eax \n\t" - "testl %%eax, %%eax \n\t" - "jz 2f \n" - "1:\t" - "movl (%%eax), %%ebx \n\t" - "movl %%edx, %%ecx \n\t" - "incl %%ecx \n\t" - LOCK "cmpxchg8b (%%esi) \n\t" - "jz 2f \n\t" - "testl %%eax, %%eax \n\t" - "jnz 1b \n" - "2:\t" - "popl %%ecx \n\t" - "popl %%ebx \n\t" - :"=a" (data) - :"S" (&lifo->top) - :"memory", "edx"); - return data; -} - -static void lifo_push(t_lifo * lifo, void * data) -{ - __asm__ __volatile__ ( - "# LFPUSH \n\t" - "pushl %%ebx \n\t" - "pushl %%ecx \n\t" - "movl 0(%%esi), %%eax \n\t" - "movl 4(%%esi), %%edx \n" - "1:\t" - "movl %%eax, %%ebx \n\t" - "incl %%ebx \n\t" - "movl %%edx, (%%ecx) \n\t" - LOCK "cmpxchg8b (%%esi) \n\t" - "jnz 1b \n\t" - "popl %%ecx \n\t" - "popl %%ebx \n\t" - :/* no output */ - :"S" (lifo), "c" (data) - :"memory", "eax", "edx"); -} - -#elif defined(__GNUC__) && defined(__x86_64__) - -/* this will not work for all revisions of the amd64 architecture ... */ - -static void* lifo_pop(t_lifo* lifo) -{ - void * data = 0; - __asm__ __volatile__ ( - "# LFPOP \n\t" - "push %%rbx \n\t" - "push %%rcx \n\t" - "mov 8(%%rdi), %%rdx \n\t" - "mov (%%rdi), %%rax \n\t" - "test %%rax, %%rax \n\t" - "jz 2f \n" - "1:\t" - "mov (%%rax), %%rbx \n\t" - "mov %%rdx, %%rcx \n\t" - "inc %%rcx \n\t" - LOCK "cmpxchg16b (%%rdi) \n\t" - "jz 2f \n\t" - "test %%rax, %%rax \n\t" - "jnz 1b \n" - "2:\t" - "pop %%rcx \n\t" - "pop %%rbx \n\t" - :"=a" (data) - :"D" (&lifo->top) - :"memory", "rdx"); - return data; -} - -static void lifo_push(t_lifo * lifo, void * data) -{ - __asm__ __volatile__ ( - "# LFPUSH \n\t" - "push %%rbx \n\t" - "push %%rcx \n\t" - "mov 0(%%rdi), %%rax \n\t" - "mov 8(%%rdi), %%rdx \n" - "1:\t" - "mov %%rax, %%rbx \n\t" - "inc %%rbx \n\t" - "mov %%rdx, (%%rcx) \n\t" - LOCK "cmpxchg16b (%%rdi) \n\t" - "jnz 1b \n\t" - "pop %%rcx \n\t" - "pop %%rbx \n\t" - :/* no output */ - :"D" (lifo), "c" (data) - :"memory", "rax", "rdx"); -} - -#elif defined(_WIN32) && defined(_MSC_VER) - -static void* lifo_pop(t_lifo* lifo) -{ - __asm - { - push ebx - push ecx - push edx - push esi - mov esi, lifo - add esi, 4 - mov edx, dword ptr [esi+4] - mov eax, dword ptr [esi] - test eax, eax - jz _end - _loop: - mov ebx, dword ptr [eax] - mov ecx, edx - inc ecx - LOCK cmpxchg8b qword ptr [esi] - jz _end - test eax, eax - jnz _loop - _end: - pop esi - pop edx - pop ecx - pop ebx - } -} - -static void lifo_push(t_lifo * lifo, void * data) -{ - __asm - { - push eax - push ebx - push ecx - push edx - push esi - mov esi, lifo - mov eax, dword ptr [esi] - mov ecx, data - mov edx, dword ptr 4[esi] - _loop: - mov ebx, eax - inc ebx - mov [ecx], edx - LOCK cmpxchg8b qword ptr [esi] - jnz _loop - pop esi - pop edx - pop ecx - pop ebx - pop eax - } -} - - -#else -#error lockfree fifos not available on this platform -#endif - -static void lifo_init(t_lifo* lifo) { - lifo->ic = 0; - lifo->top = 0; - lifo->oc = 0; -} - -t_fifo *fifo_init(void) { - t_fifo *ret = (t_fifo *)malloc(sizeof(t_fifo)); - lifo_init(&ret->in); - lifo_init(&ret->out); - return ret; -} - -void fifo_destroy(t_fifo *fifo) { - void *data; - do data = fifo_get(fifo); while (data); - free(fifo); - return; -} - -void fifo_put(t_fifo *fifo, void *data) {lifo_push(&fifo->in, data);} - -void* fifo_get(t_fifo *fifo) { - void *data; - t_lifo *out = &fifo->out; - data = lifo_pop(out); - if (!data) { - void *tmp; - t_lifo *in = &fifo->in; - data = lifo_pop(in); - if (data) { - while((tmp = lifo_pop(in))) { - lifo_push(out, data); - data = tmp; - } - } - - } - return data; -} - -#endif diff --git a/desiredata/src/m_pd.h b/desiredata/src/m_pd.h deleted file mode 100644 index 2a930757..00000000 --- a/desiredata/src/m_pd.h +++ /dev/null @@ -1,974 +0,0 @@ -/* $Id$ - This file is part of DesireData. - - Copyright (c) 2006,2007,2009 Mathieu Bouchard. - Copyright (c) 1997-1999 Miller Puckette. - For information on usage and redistribution, and for a DISCLAIMER OF ALL - WARRANTIES, see the file, "LICENSE.txt", in this distribution. -*/ -/* - PD_PLUSPLUS_FACE is not considered as part of the main interface for externals, - even though it has become the main interface for internals. please don't rely on - it outside of the desiredata source code (yet). -*/ - -#ifndef __m_pd_h_ - -#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) -#include <iostream> - -#ifdef __cplusplus -template <class K, class V> class t_hash /* : t_pd */ { - struct entry { - K k; - V v; - struct entry *next; - }; - long capa; - long n; - entry **tab; -/* when iterating: */ - long i; - entry *m_next; -public: - t_hash(long capa_) : capa(capa_), n(0), i(0) { - tab = new entry *[capa]; - for (long j=0; j<capa; j++) tab[j]=0; - } - ~t_hash() { - for (long j=0; j<capa; j++) while (tab[j]) del(tab[j]->k); - delete[] tab; - } - size_t size() {return n;} - V get(K k) { - long h = hash(k); - for (entry *e=tab[h]; e; e=e->next) {if (e->k==k) return e->v;} - return 0; - } - void set(K k, V v) { - long h = hash(k); - for (entry *e=tab[h]; e; e=e->next) {if (e->k==k) {e->v=v; return;}} - entry *nu = new entry; nu->k=k; nu->v=v; nu->next=tab[h]; - n++; - tab[h] = nu; - } - V del(K k) { - long h = hash(k); - for (entry **ep=&tab[h]; *ep; ep=&(*ep)->next) { - if ((*ep)->k==k) { - V v=(*ep)->v; - entry *next=(*ep)->next; - delete *ep; n--; - *ep = next; - return v; - } - } - return 0; - } - int exists(K k) { - long h = hash(k); - for (entry *e=tab[h]; e; e=e->next) {if (e->k==k) return 1;} - return 0; - } - void start() {i=0; m_next=0;} - int next(K *kp, V *vp) { - while (!m_next && i<capa) m_next = tab[i++]; - if (m_next) { - *kp = m_next->k; - *vp = m_next->v; - m_next = m_next->next; - return 1; - } - return 0; - } - #define hash_foreach(k,v,h) for (h->start(); h->next(&k,&v); ) - long hash(K k) {return (((long)k*0x54321) & 0x7FFFFFFF)%capa;} -}; -#endif - -/* needed for all those strcmp.h in here */ -#include <string.h> - -extern "C" { -#endif - -#define DESIRE 1 -#define PD_MAJOR_VERSION 1 -#define PD_MINOR_VERSION 0 -#define PD_DEVEL_VERSION 0 -#define PD_TEST_VERSION "" - -/* old name for "MSW" flag -- we have to take it for the sake of many old -"nmakefiles" for externs, which will define NT and not MSW */ -#if (defined(_WIN32) || defined(NT)) && !defined(MSW) -#define MSW -#endif - -#ifdef __CYGWIN__ -#define UNISTD -#endif - -#ifdef _MSC_VER -/* #pragma warning( disable : 4091 ) */ -#pragma warning( disable : 4305 ) /* uncast const double to float */ -#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */ -#pragma warning( disable : 4101 ) /* unused automatic variables */ -#endif /* _MSC_VER */ - -/* the external storage class is "extern" on Linux and OSX; on Win32 it's ugly like this: */ -#if defined(MSW) && !defined (__GNUC__) -#ifdef PD_INTERNAL -#define EXTERN __declspec(dllexport) extern -#else -#define EXTERN __declspec(dllimport) extern -#endif /* PD_INTERNAL */ -#else -#define EXTERN extern -#endif /* MSW */ - -#if !defined(_SIZE_T) && !defined(_SIZE_T_) -#include <stddef.h> -#endif - -#include <stdarg.h> - -#define MAXPDSTRING 1000 /* use this for anything you want */ -#define MAXPDARG 5 /* max number of args we can typecheck today */ - -/* signed and unsigned integer types the size of a pointer: */ -/* GG: long is the size of a pointer */ -typedef long t_int; - -typedef float t_float; /* a floating-point number at most the same size */ -typedef float t_floatarg; /* floating-point type for function calls */ - -typedef struct _class t_class; -typedef struct _outlet t_outlet; -typedef struct _inlet t_inlet; -typedef struct _clock t_clock; -typedef struct _glist t_glist, t_canvas; -typedef struct _symbol t_symbol; -typedef struct _atom t_atom; - -#ifdef PD_PLUSPLUS_FACE -struct t_pd { - t_class *_class; -}; -#else -typedef t_class *t_pd; /* pure datum: nothing but a class pointer */ -#endif - -struct _symbol { - char *name; /* the const string that represents this symbol */ - t_pd *thing; /* pointer to the target of a receive-symbol or to the bindlist of several targets */ - struct _symbol *next; /* brochette of all symbols (only for permanent symbols) */ - size_t refcount; /* refcount<0 means that the symbol is permanent */ - size_t n; /* size of name (support for NUL characters) */ -#ifdef PD_PLUSPLUS_FACE - bool operator == (const char *s) const {return strcmp(this->name,s)==0;} - bool operator != (const char *s) const {return strcmp(this->name,s);} -#endif -}; -#define s_name name -#define s_thing thing -#define s_next next - -#ifdef PD_PLUSPLUS_FACE -typedef struct t_list : t_pd { -#else -typedef struct t_list { - t_pd *pd; -#endif - struct _atom *v; - size_t capa; - size_t refcount; - size_t n; -} t_list, t_binbuf; - -typedef struct _array t_array; /* g_canvas.h */ - -/* pointers to glist and array elements go through a "stub" which sticks -around after the glist or array is freed. The stub itself is deleted when -both the glist/array is gone and the refcount is zero, ensuring that no -gpointers are pointing here. */ - -#ifdef PD_PLUSPLUS_FACE -typedef struct _gpointer { - union { - struct _scalar *scalar; /* scalar we're in (if glist) */ - union word *w; /* raw data (if array) */ - }; - union { - struct _glist *canvas; - struct _array *array; - struct t_text *o; - }; - size_t dummy; - size_t refcount; -//#define gs_refcount refcount -#define gs_refcount canvas->refcount -} t_gpointer; -#else -typedef struct _gpointer { - union { - struct _scalar *gp_scalar; /* scalar we're in (if glist) */ - union word *gp_w; /* raw data (if array) */ - } gp_un; - union { - struct _glist *canvas; - struct _array *array; - struct _text *o; - } un; - size_t dummy; - size_t refcount; -//#define gs_refcount un.canvas->gl_obj.refcount -#define gs_refcount refcount -} t_gpointer; -#endif - -#define w_list w_canvas -typedef union word { - t_float w_float; /* A_FLOAT */ - t_symbol *w_symbol; /* A_SYMBOL or A_DOLLSYM */ - t_gpointer *w_gpointer; /* A_POINTER */ - t_array *w_array; /* DT_ARRAY */ - struct _glist *w_canvas; /* DT_LIST */ - t_int w_index; /* A_SEMI or A_COMMA or A_DOLLAR */ -} t_word; - -typedef enum { - A_NULL, /* non-type: represents end of typelist */ - A_FLOAT, A_SYMBOL, A_POINTER, /* stable elements */ - A_SEMI, A_COMMA, /* radioactive elements of the first kind */ - A_DEFFLOAT, A_DEFSYM, /* pseudo-types for optional (DEFault) arguments */ - A_DOLLAR, A_DOLLSYM, /* radioactive elements of the second kind */ - A_GIMME, /* non-type: represents varargs */ - A_CANT, /* bottom type: type constraint is impossible */ -/* regular pd stops here, before #12 */ - A_ATOM, /* top type: type constraint doesn't constrain */ - A_LIST, /* t_list *, the 4th stable element (future use) */ - A_GRID, /* reserved for GridFlow */ - A_GRIDOUT, /* reserved for GridFlow */ -} t_atomtype; - -#define A_DEFSYMBOL A_DEFSYM /* better name for this */ - -struct _atom { - t_atomtype a_type; - union word a_w; -#ifdef __cplusplus - operator float () {return a_w.w_float;} - operator t_symbol *() {return a_w.w_symbol;} - //bool operator == (_atom &o) {return a_type==o.a_type && a_w.w_index==o.a_w.w_index;} - //bool operator != (_atom &o) {return a_type!=o.a_type || a_w.w_index!=o.a_w.w_index;} -#endif -}; - -struct t_arglist {long c; t_atom v[0];}; - -typedef unsigned long long uint64; - -/* t_appendix is made of the things that logically ought to be in t_gobj but have been put in a - separate memory space because this allows most externals to work unmodified on both DesireData - and non-DesireData systems. The equivalent in the Tcl side is really part of every view object. */ -typedef struct t_appendix { - t_canvas *canvas; /* the holder of this object */ -/* actual observable */ - size_t nobs; /* number of spies */ - struct _gobj **obs; /* I spy with my little I */ -/* miscellaneous */ -#ifdef __cplusplus - t_hash<t_symbol *, t_arglist *> *visual; -#else - void *visual; -#endif - long index; /* index of an object within its canvas scope. */ - uint64 elapsed; -} t_appendix; -t_appendix *appendix_new (struct _gobj *master); -void appendix_free(struct _gobj *self); -void appendix_save(struct _gobj *master, t_binbuf *b); - -#ifdef PD_PLUSPLUS_FACE -#define g_pd _class -typedef struct _gobj : t_pd { -#else -typedef struct _gobj /* a graphical object */ -{ - t_pd g_pd; /* pure datum header (class) */ -#endif - t_appendix *dix; -#define g_adix dix -#ifdef PD_PLUSPLUS_FACE - _gobj *next(); -#endif -} t_gobj; - -#ifdef PD_PLUSPLUS_FACE -typedef struct _outconnect : _gobj { - struct _outconnect *next; - t_pd *oc_to; - struct t_text *from; - struct t_text *to; - short outlet, inlet; -} t_outconnect, t_wire; -#define oc_next next -#else -typedef struct _outconnect t_outconnect; -#endif - -#ifdef PD_PLUSPLUS_FACE -typedef struct _scalar : t_gobj { -#else -typedef struct _scalar /* a graphical object holding data */ -{ - t_gobj sc_gobj; /* header for graphical object */ -#endif - t_symbol *t; /* template name (LATER replace with pointer) */ - t_word v[1]; /* indeterminate-length array of words */ -} t_scalar; - -#define sc_template t -#define sc_vec v - -#ifdef PD_PLUSPLUS_FACE -typedef struct t_text : t_gobj { -#else -typedef struct _text /* patchable object - graphical, with text */ -{ - t_gobj te_g; /* header for graphical object */ -#endif - t_binbuf *binbuf; /* holder for the text */ - t_outlet *outlet; /* linked list of outlets */ - t_inlet *inlet; /* linked list of inlets */ - short x,y; /* x&y location (within the toplevel) */ - int refcount; /* there used to be a bitfield here, which may be a problem with ms-bitfields (?) */ -#ifdef PD_PLUSPLUS_FACE - t_inlet * in(int n); - t_outlet *out(int n); -#endif -} t_text, t_object; - -#define te_binbuf binbuf -#define te_outlet outlet -#define te_inlet inlet -#define te_xpix x -#define te_ypix y -#define te_width width -#define te_type type - -#define ob_outlet te_outlet -#define ob_inlet te_inlet -#define ob_binbuf te_binbuf -#ifdef PD_PLUSPLUS_FACE -#define te_pd g_pd -#define ob_pd g_pd -#else -#define te_pd te_g.g_pd -#define ob_pd te_g.g_pd -#endif -#define ob_g te_g - -/* don't take those three types for cash (on average). they're lying because the type system can't express what there is to be expressed. */ -typedef void (*t_method)(void); -typedef void *(*t_newmethod)(void); -typedef void (*t_gotfn)(void *x, ...); - -/* ---------------- pre-defined objects and symbols --------------*/ -EXTERN t_pd pd_objectmaker; /* factory for creating "object" boxes */ -EXTERN t_pd pd_canvasmaker; /* factory for creating canvases */ -EXTERN t_symbol s_pointer, s_float, s_symbol; -EXTERN t_symbol s_bang, s_list, s_anything, s_signal; -EXTERN t_symbol s__N, s__X, s_x, s_y, s_; - -/* --------- central message system ----------- */ -EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv); -EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv); -EXTERN t_symbol *gensym(const char *s); -EXTERN t_symbol *gensym2(const char *s, size_t n); -EXTERN t_symbol *symprintf(const char *s, ...); -EXTERN t_gotfn getfn(t_pd *x, t_symbol *s); -EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s); -EXTERN void nullfn(void); -EXTERN void pd_vmess(t_pd *x, t_symbol *s, const char *fmt, ...); -#define mess0(x,s) (getfn((x),(s))((x))) -#define mess1(x,s,a) (getfn((x),(s))((x),(a))) -#define mess2(x,s,a,b) (getfn((x),(s))((x),(a),(b))) -#define mess3(x,s,a,b,c) (getfn((x),(s))((x),(a),(b),(c))) -#define mess4(x,s,a,b,c,d) (getfn((x),(s))((x),(a),(b),(c),(d))) -#define mess5(x,s,a,b,c,d,e) (getfn((x),(s))((x),(a),(b),(c),(d),(e))) -EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv); -EXTERN t_pd *pd_newest(void); /* multiclient race conditions? */ - -/* --------------- memory management -------------------- */ -EXTERN void *getbytes(size_t nbytes); /* deprecated, use malloc() */ -EXTERN void *copybytes(void *src, size_t nbytes); -EXTERN void freebytes(void *x, size_t nbytes); /* deprecated, use free() */ -EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize); /* deprecated, use realloc() */ - -/* T.Grill - functions for aligned memory (according to CPU SIMD architecture) */ -EXTERN void *getalignedbytes(size_t nbytes); -EXTERN void *copyalignedbytes(void *src, size_t nbytes); -EXTERN void freealignedbytes(void *x,size_t nbytes); -EXTERN void *resizealignedbytes(void *x,size_t oldsize, size_t newsize); -/* -------------------- atoms ----------------------------- */ - -#define atom_decref(atom) (void)42 -#define atom_incref(atom) (void)42 -#define SETATOM(atom,type,field,value) (atom_decref(atom), (atom)->a_type=type, (atom)->a_w.field=value, atom_incref(atom)) -#define SETSEMI(atom) SETATOM(atom,A_SEMI, w_index,0) -#define SETCOMMA(atom) SETATOM(atom,A_COMMA, w_index,0) -#define SETPOINTER(atom, gp) SETATOM(atom,A_POINTER,w_gpointer,(gp)) /* looks unsafe... */ -#define SETFLOAT(atom, f) SETATOM(atom,A_FLOAT, w_float,(f)) -#define SETSYMBOL(atom, s) SETATOM(atom,A_SYMBOL, w_symbol,(s)) -#define SETSTRING(atom, s) SETATOM(atom,A_SYMBOL, w_symbol,gensym(s)) -#define SETDOLLAR(atom, n) SETATOM(atom,A_DOLLAR, w_index,(n)) -#define SETDOLLSYM(atom, s) SETATOM(atom,A_DOLLSYM,w_symbol,(s)) - -EXTERN t_float atom_getfloat( t_atom *a); -EXTERN t_int atom_getint( t_atom *a); -EXTERN t_symbol *atom_getsymbol(t_atom *a); /* this call causes a t_symbol to become ternal */ -EXTERN const char *atom_getstring(t_atom *a); /* the return value should be used only immediately */ -EXTERN t_float atom_getfloatarg( int which, int argc, t_atom *argv); -EXTERN t_int atom_getintarg( int which, int argc, t_atom *argv); -EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv); -EXTERN const char *atom_getstringarg(int which, int argc, t_atom *argv); /* see above */ - -EXTERN t_symbol *atom_gensym( t_atom *a); - -/* this function should produce a literal, whereas getstring gives the exact string */ -EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize); -#ifdef __cplusplus -EXTERN void atom_ostream(t_atom *a, std::ostream &buf); -inline std::ostream &operator <<(std::ostream &buf, t_atom *a) {atom_ostream(a,buf); return buf;} -#endif - -/* goes with desiredata's CLASS_NEWATOM */ -EXTERN void atom_init(t_atom *a, size_t n); -EXTERN void atom_copy(t_atom *a, t_atom *b, size_t n); -EXTERN void atom_delete(t_atom *a, size_t n); - -/* ------------------ binbufs --------------- */ - -EXTERN t_binbuf *binbuf_new(void); -EXTERN void binbuf_free(t_binbuf *x); -EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y); - -EXTERN void binbuf_text(t_binbuf *x, const char *text, size_t size); -EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp); -EXTERN char *binbuf_gettext2(t_binbuf *x); -EXTERN void binbuf_clear(t_binbuf *x); -EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv); -EXTERN void binbuf_addv(t_binbuf *x, const char *fmt, ...); -EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y); -EXTERN void binbuf_addsemi(t_binbuf *x); -EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv); -EXTERN void binbuf_print(t_binbuf *x); -EXTERN int binbuf_getnatom(t_binbuf *x); -EXTERN t_atom *binbuf_getvec(t_binbuf *x); -EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv); -EXTERN int binbuf_read( t_binbuf *b, const char *filename, const char *dirname, int flags); -EXTERN int binbuf_read_via_canvas(t_binbuf *b, const char *filename, t_canvas *canvas, int flags); -EXTERN int binbuf_read_via_path( t_binbuf *b, const char *filename, const char *dirname, int flags); -EXTERN int binbuf_write( t_binbuf *x, const char *filename, const char *dir, int flags); -EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir); -EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, int tonew); - -/* ------------------ clocks --------------- */ - -EXTERN t_clock *clock_new(void *owner, t_method fn); -EXTERN void clock_set(t_clock *x, double systime); -EXTERN void clock_delay(t_clock *x, double delaytime); -EXTERN void clock_unset(t_clock *x); -EXTERN double clock_getlogicaltime(void); -EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */ -EXTERN double clock_gettimesince(double prevsystime); -EXTERN double clock_getsystimeafter(double delaytime); -EXTERN void clock_free(t_clock *x); - -/* ----------------- pure data ---------------- */ -EXTERN t_pd *pd_new(t_class *cls); -EXTERN void pd_free(t_pd *x); -EXTERN void pd_bind( t_pd *x, t_symbol *s); -EXTERN void pd_unbind(t_pd *x, t_symbol *s); -EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c); -EXTERN void pd_pushsym(t_pd *x); -EXTERN void pd_popsym( t_pd *x); -EXTERN t_symbol *pd_getfilename(void); -EXTERN t_symbol *pd_getdirname(void); -EXTERN void pd_bang( t_pd *x); -EXTERN void pd_pointer( t_pd *x, t_gpointer *gp); -EXTERN void pd_float( t_pd *x, t_float f); -EXTERN void pd_symbol( t_pd *x, t_symbol *s); -EXTERN void pd_string( t_pd *x, const char *s); /* makes a refcounted symbol (copying s) */ -EXTERN void pd_list( t_pd *x, t_symbol *s, int argc, t_atom *argv); -#define pd_anything pd_typedmess - -#ifdef PD_PLUSPLUS_FACE -#define pd_class(x) ((x)->_class) -#else -#define pd_class(x) (*(x)) -#endif - -EXTERN void gobj_subscribe (t_gobj *self, t_gobj *observer); -EXTERN void gobj_unsubscribe (t_gobj *self, t_gobj *observer); -EXTERN void gobj_changed (t_gobj *self, const char *k); -EXTERN void gobj_changed2 (t_gobj *self, int argc, t_atom *argv); -EXTERN void gobj_changed3 (t_gobj *self, t_gobj *origin, int argc, t_atom *argv); - -/* ----------------- pointers ---------------- */ -EXTERN void gpointer_init(t_gpointer *gp); -EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto); -EXTERN void gpointer_unset(t_gpointer *gp); -EXTERN int gpointer_check(const t_gpointer *gp, int headok); - -/* ----------------- patchable "objects" -------------- */ -EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1, t_symbol *s2); -EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp); -EXTERN t_inlet *floatinlet_new( t_object *owner, t_float *fp); -EXTERN t_inlet *symbolinlet_new( t_object *owner, t_symbol **sp); -EXTERN t_inlet *stringinlet_new( t_object *owner, t_symbol **sp); /* for future use */ -EXTERN t_inlet *signalinlet_new( t_object *owner, t_float f); -EXTERN void inlet_free(t_inlet *x); - -EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s); -EXTERN void outlet_bang( t_outlet *x); -EXTERN void outlet_float( t_outlet *x, t_float f); -EXTERN void outlet_symbol( t_outlet *x, t_symbol *s); -EXTERN void outlet_string( t_outlet *x, const char *s); /* makes a refcounted symbol (copying s) */ -EXTERN void outlet_pointer( t_outlet *x, t_gpointer *gp); -EXTERN void outlet_atom( t_outlet *x, t_atom *a); -EXTERN void outlet_list( t_outlet *x, t_symbol *s, int argc, t_atom *argv); /* ignores s, uses &s_list instead */ -EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv); -EXTERN t_symbol *outlet_getsymbol(t_outlet *x); -EXTERN void outlet_free(t_outlet *x); - -struct _outlet { -#ifdef PD_PLUSPLUS_FACE - void send() {outlet_bang( this);} - void send(t_float v) {outlet_float( this,v);} - void send(t_symbol *v) {outlet_symbol( this,v);} - void send(const char *v) {outlet_string( this,v);} - void send(t_gpointer *v) {outlet_pointer(this,v);} - void send(t_atom *v) {outlet_atom( this,v);} - void send( int argc, t_atom *argv) {outlet_list( this,0,argc,argv);} - void send(t_symbol *s, int argc, t_atom *argv) {outlet_anything(this,s,argc,argv);} - //private: -#endif - t_object *owner; - struct _outlet *next; - t_outconnect *connections; - t_symbol *sym; -}; - - -EXTERN t_object *pd_checkobject(t_pd *x); - -/* -------------------- canvases -------------- */ - -EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir); -EXTERN void canvas_setargs(int argc, t_atom * argv ); -EXTERN void canvas_getargs(int *argcp, t_atom **argvp); -EXTERN t_symbol *canvas_getcurrentdir(void); -EXTERN t_glist *canvas_getcurrent(void); -/* if result==0 then it will allocate a result and return it */ -EXTERN char *canvas_makefilename(t_glist *c, char *file, char *result, int resultsize); -EXTERN t_symbol *canvas_getdir(t_glist *x); -EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b); -EXTERN int canvas_open( t_canvas *x, const char *name, const char *ext, char * dirresult, char **nameresult, unsigned int size, int bin); -EXTERN int canvas_open2(t_canvas *x, const char *name, const char *ext, char **dirresult, char **nameresult, int bin); - -// new abstracted calls -EXTERN t_gobj *canvas_first(t_canvas *x); -EXTERN t_gobj *gobj_next(t_gobj *x); - -/* -------------------- classes -------------- */ - -#define CLASS_DEFAULT 0 /* flags for new classes below */ -#define CLASS_PD 1 -#define CLASS_GOBJ 2 -#define CLASS_PATCHABLE 3 -#define CLASS_NOINLET 8 -#define CLASS_NEWATOMS 16 -#define CLASS_TYPEMASK 3 - -#ifdef __cplusplus -typedef int t_atomtypearg; -#else -typedef t_atomtype t_atomtypearg; -#endif - -EXTERN t_class *class_find (t_symbol *s); -EXTERN t_class *class_new( t_symbol *name,t_newmethod nu,t_method freem,size_t size,int flags,t_atomtypearg arg1, ...); -EXTERN t_class *class_new2(const char *name,t_newmethod nu,t_method freem,size_t size,int flags,const char *sig); -EXTERN void class_addcreator( t_newmethod nu, t_symbol *sel, t_atomtypearg arg1, ...); -EXTERN void class_addcreator2(const char *name, t_newmethod nu, const char *sig); -EXTERN void class_addmethod( t_class *c, t_method fn, t_symbol *sel, t_atomtypearg arg1, ...); -EXTERN void class_addmethod2( t_class *c, t_method fn, const char *sel, const char *sig); -#define class_new2(NAME,NU,FREE,SIZE,FLAGS,SIG) class_new2(NAME,(t_newmethod)NU,(t_method)FREE,SIZE,FLAGS,SIG) -#define class_addcreator2(NAME,NU,SIG) class_addcreator2(NAME,(t_newmethod)NU,SIG) -#define class_addmethod2(NAME,METH,SEL,SIG) class_addmethod2(NAME,(t_method)METH,SEL,SIG) - -EXTERN void class_addbang( t_class *c, t_method fn); -EXTERN void class_addpointer( t_class *c, t_method fn); -EXTERN void class_doaddfloat( t_class *c, t_method fn); -EXTERN void class_addsymbol( t_class *c, t_method fn); -EXTERN void class_addstring( t_class *c, t_method fn); /* for future use */ -EXTERN void class_addlist( t_class *c, t_method fn); -EXTERN void class_addanything(t_class *c, t_method fn); -EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s); -EXTERN char *class_getname(t_class *c); -EXTERN char *class_gethelpname(t_class *c); -EXTERN void class_setdrawcommand(t_class *c); -EXTERN int class_isdrawcommand(t_class *c); -EXTERN void class_domainsignalin(t_class *c, int onset); -#define CLASS_MAINSIGNALIN(c, type, field) \ - class_domainsignalin(c, (char *)(&((type *)0xdead0000)->field) - (char *)0xdead0000) - -/* in "class" observer: observable calls this to notify of a change */ -typedef void (*t_notice)(t_gobj *x, t_gobj *origin, int argc, t_atom *argv); -EXTERN void class_setnotice(t_class *c, t_notice notice); - -/* in "class" observable: observable sends initial data to observer */ -/* this is called by gobj_subscribe to find out all the indirect subscriptions of aggregators. */ -/* every class that redefines this is an aggregator; every aggregator should redefine this. */ -/* "calling super" is done by calling gobj_onsubscribe with same args */ -typedef void (*t_onsubscribe)(t_gobj *x, t_gobj *observer); -EXTERN void class_setonsubscribe(t_class *c, t_onsubscribe onsubscribe); -EXTERN void gobj_onsubscribe(t_gobj *x, t_gobj *observer); /* default handler, that you may inherit from */ - -/* prototype for functions to save Pd's to a binbuf */ -typedef void (*t_savefn)(t_gobj *x, t_binbuf *b); -EXTERN void class_setsavefn(t_class *c, t_savefn f); -EXTERN t_savefn class_getsavefn(t_class *c); - -#ifndef PD_CLASS_DEF -#define class_addbang( x,y) class_addbang( (x),(t_method)(y)) -#define class_addpointer( x,y) class_addpointer( (x),(t_method)(y)) -#define class_addfloat( x,y) class_doaddfloat( (x),(t_method)(y)) -#define class_addsymbol( x,y) class_addsymbol( (x),(t_method)(y)) -#define class_addstring( x,y) class_addstring( (x),(t_method)(y)) /* for future use */ -#define class_addlist( x,y) class_addlist( (x),(t_method)(y)) -#define class_addanything(x,y) class_addanything((x),(t_method)(y)) -#endif - -EXTERN void class_settip(t_class *x,t_symbol* s); -EXTERN void inlet_settip(t_inlet* i,t_symbol* s); -EXTERN void class_setfieldnames(t_class *x, const char *s); /* where s is split on spaces and tokenized */ -EXTERN int class_getfieldindex(t_class *x, const char *s); -typedef int (*t_loader)(t_canvas *canvas, char *classname); -EXTERN void sys_register_loader(t_loader loader); - -/* ------------ printing --------------------------------- */ -EXTERN void post(const char *fmt, ...) __attribute__((format(printf,1,2))); -EXTERN void startpost(const char *fmt, ...) __attribute__((format(printf,1,2))); -EXTERN void poststring(const char *s); -EXTERN void postfloat(float f); -EXTERN void postatom(int argc, t_atom *argv); -EXTERN void endpost(void); -EXTERN void error(const char *fmt, ...) __attribute__((format(printf,1,2))); -EXTERN void verror(const char *fmt, va_list args); -EXTERN void verbose(int level, const char *fmt, ...) __attribute__((format(printf,2,3))); -EXTERN void bug(const char *fmt, ...) __attribute__((format(printf,1,2))); -EXTERN void pd_error(void *object, const char *fmt, ...) __attribute__((format(printf,2,3))) /*__attribute__ ((deprecated))*/; -EXTERN void sys_logerror(const char *object, const char *s); -EXTERN void sys_unixerror(const char *object); -EXTERN void sys_ouch(void); - -/* ------------ system interface routines ------------------- */ -EXTERN int sys_isreadablefile(const char *name); -EXTERN void sys_bashfilename(const char *from, char *to); -EXTERN void sys_unbashfilename(const char *from, char *to); -EXTERN int open_via_path(const char *name, const char *ext, const char *dir, - char *dirresult, char **nameresult, unsigned int size, int bin); -EXTERN int open_via_path2(const char *dir, const char *name, const char *ext, char **dirresult, char **nameresult, int bin); - -EXTERN int sched_geteventno(void); -EXTERN double sys_getrealtime(void); - - -/* ------------ threading ------------------- */ -/* T.Grill - see m_sched.c */ -EXTERN void sys_lock(void); -EXTERN void sys_unlock(void); -EXTERN int sys_trylock(void); -EXTERN int sys_timedlock(int microsec); -/* tb: to be called at idle time */ -EXTERN void sys_callback(t_int (*callback) (t_int* argv), t_int* argv, t_int argc); - -/* --------------- signals ----------------------------------- */ - -typedef float t_sample; -#define MAXLOGSIG 32 -#define MAXSIGSIZE (1 << MAXLOGSIG) - -/* this doesn't really have to do with C++, just with getting rid of prefixes */ -#ifdef PD_PLUSPLUS_FACE -struct t_signal { - int n; - t_sample *v; - float sr; - int refcount; - int isborrowed; - t_signal *borrowedfrom; - t_signal *nextfree; - t_signal *nextused; - int vecsize; -}; -#else -typedef struct _signal { - int s_n; /* number of points in the array */ - t_sample *s_vec; /* the array */ - float s_sr; /* sample rate */ - int s_refcount; /* number of times used */ - int s_isborrowed; /* whether we're going to borrow our array */ - struct _signal *s_borrowedfrom; /* signal to borrow it from */ - struct _signal *s_nextfree; /* next in freelist */ - struct _signal *s_nextused; /* next in used list */ - int s_vecsize; /* allocated size of array in points */ -} t_signal; -#endif - -typedef t_int *(*t_perfroutine)(t_int *args); - -/* tb: exporting basic arithmetic dsp functions { - * for (n % 8) != 0 */ -EXTERN t_int *zero_perform(t_int *args); -EXTERN t_int *copy_perform(t_int *args); -EXTERN t_int *plus_perform( t_int *args); EXTERN t_int *scalarplus_perform( t_int *args); -EXTERN t_int *minus_perform(t_int *args); EXTERN t_int *scalarminus_perform(t_int *args); -EXTERN t_int *times_perform(t_int *args); EXTERN t_int *scalartimes_perform(t_int *args); -EXTERN t_int *over_perform( t_int *args); EXTERN t_int *scalarover_perform( t_int *args); -EXTERN t_int *max_perform( t_int *args); EXTERN t_int *scalarmax_perform( t_int *args); -EXTERN t_int *min_perform( t_int *args); EXTERN t_int *scalarmin_perform( t_int *args); -EXTERN t_int *sig_tilde_perform(t_int *args); -EXTERN t_int *clip_perform(t_int *args); - -/* for (n % 8) == 0 */ -EXTERN t_int *zero_perf8(t_int *args); -EXTERN t_int *copy_perf8(t_int *args); -EXTERN t_int *plus_perf8( t_int *args); EXTERN t_int *scalarplus_perf8( t_int *args); -EXTERN t_int *minus_perf8(t_int *args); EXTERN t_int *scalarminus_perf8(t_int *args); -EXTERN t_int *times_perf8(t_int *args); EXTERN t_int *scalartimes_perf8(t_int *args); -EXTERN t_int *over_perf8( t_int *args); EXTERN t_int *scalarover_perf8( t_int *args); -EXTERN t_int *max_perf8( t_int *args); EXTERN t_int *scalarmax_perf8( t_int *args); -EXTERN t_int *min_perf8( t_int *args); EXTERN t_int *scalarmin_perf8( t_int *args); -EXTERN t_int *sqr_perf8(t_int *args); -EXTERN t_int *sig_tilde_perf8(t_int *args); - -/* for (n % 8) == 0 && aligned signal vectors - * check with simd_checkX functions !!! */ -EXTERN t_int *zero_perf_simd(t_int *args); -EXTERN t_int *copy_perf_simd(t_int *args); -EXTERN t_int *plus_perf_simd( t_int *args); EXTERN t_int *scalarplus_perf_simd( t_int *args); -EXTERN t_int *minus_perf_simd(t_int *args); EXTERN t_int *scalarminus_perf_simd(t_int *args); -EXTERN t_int *times_perf_simd(t_int *args); EXTERN t_int *scalartimes_perf_simd(t_int *args); -EXTERN t_int *over_perf_simd( t_int *args); EXTERN t_int *scalarover_perf_simd( t_int *args); -EXTERN t_int *max_perf_simd( t_int *args); EXTERN t_int *scalarmax_perf_simd( t_int *args); -EXTERN t_int *min_perf_simd( t_int *args); EXTERN t_int *scalarmin_perf_simd( t_int *args); -EXTERN t_int *sqr_perf_simd(t_int *args); -EXTERN t_int *sig_tilde_perf_simd(t_int *args); -EXTERN t_int *clip_perf_simd(t_int *args); -/* } tb */ - -EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n); -EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n); -EXTERN void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n); -EXTERN void dsp_add_zero(t_sample *out, int n); - -EXTERN int sys_getblksize(void); -EXTERN float sys_getsr(void); -EXTERN int sys_get_inchannels(void); -EXTERN int sys_get_outchannels(void); - -EXTERN void dsp_add(t_perfroutine f, int n, ...); -EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec); -EXTERN void pd_fft(float *buf, int npoints, int inverse); -EXTERN int ilog2(int n); - -EXTERN void mayer_fht(float *fz, int n); -EXTERN void mayer_fft(int n, float *real, float *imag); -EXTERN void mayer_ifft(int n, float *real, float *imag); -EXTERN void mayer_realfft(int n, float *real); -EXTERN void mayer_realifft(int n, float *real); - -EXTERN float *cos_table; -#define LOGCOSTABSIZE 9 -#define COSTABSIZE (1<<LOGCOSTABSIZE) - -EXTERN int canvas_suspend_dsp(void); -EXTERN void canvas_resume_dsp(int oldstate); -EXTERN void canvas_update_dsp(void); -EXTERN int canvas_dspstate; - -/* IOhannes { (up/downsampling) */ -/* use zero-padding to generate samples inbetween */ -#define RESAMPLE_ZERO 0 -/* use sample-and-hold to generate samples inbetween */ -#define RESAMPLE_HOLD 1 -/* use linear interpolation to generate samples inbetween */ -#define RESAMPLE_LINEAR 2 -/* not a real up/downsampling: - * upsampling: copy the original vector to the first part of the upsampled vector; the rest is zero - * downsampling: take the first part of the original vector as the downsampled vector - * WHAT FOR: we often want to process only the first half of an FFT-signal (the rest is redundant) - */ -#define RESAMPLE_BLOCK 3 - -#define RESAMPLE_DEFAULT RESAMPLE_ZERO - -typedef struct _resample { - int method; /* up/downsampling method ID */ - t_int downsample; /* downsampling factor */ - t_int upsample; /* upsampling factor */ -#ifdef PD_PLUSPLUS_FACE - t_float *v; /* here we hold the resampled data */ - int n; -#else - t_float *vec; - int s_n; -#endif - t_float *coeffs; /* coefficients for filtering... */ - int coefsize; - t_float *buffer; /* buffer for filtering */ - int bufsize; -} t_resample; - -EXTERN void resample_init(t_resample *x); -EXTERN void resample_free(t_resample *x); -EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method); -EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method); -EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method); -/* } IOhannes */ - -/* tb: exporting basic simd coded dsp functions { */ - -/* vectorized, not simd functions*/ -EXTERN void zerovec_8(t_float *dst,int n); -EXTERN void setvec_8(t_float *dst,t_float v,int n); -EXTERN void copyvec_8(t_float *dst,const t_float *src,int n); -EXTERN void addvec_8(t_float *dst,const t_float *src,int n); -EXTERN void testcopyvec_8(t_float *dst,const t_float *src,int n); -EXTERN void testaddvec_8(t_float *dst,const t_float *src,int n); -/* EXTERN float sumvec_8(t_float* in, t_int n); */ - -/* vectorized, simd functions * - * dst and src are assumed to be aligned */ -EXTERN void zerovec_simd(t_float *dst,int n); -EXTERN void setvec_simd(t_float *dst,t_float v,int n); -EXTERN void copyvec_simd(t_float *dst,const t_float *src,int n); -EXTERN void addvec_simd(t_float *dst,const t_float *src,int n); -EXTERN void testcopyvec_simd(t_float *dst,const t_float *src,int n); -EXTERN void testaddvec_simd(t_float *dst,const t_float *src,int n); -/* EXTERN float sumvec_simd(t_float* in, t_int n); */ -EXTERN void copyvec_simd_unalignedsrc(t_float *dst,const t_float *src,int n); - -/* not vectorized, not simd functions */ -EXTERN void copyvec(t_float *dst,const t_float *src,int n); -EXTERN void addvec(t_float *dst,const t_float *src,int n); -EXTERN void zerovec(t_float *dst, int n); - -EXTERN int simd_runtime_check(void); -EXTERN int simd_check1(t_int n, t_float* ptr1); -EXTERN int simd_check2(t_int n, t_float* ptr1, t_float* ptr2); -EXTERN int simd_check3(t_int n, t_float* ptr1, t_float* ptr2, t_float* ptr3); - -/* } tb */ - - -/* ----------------------- utility functions for signals -------------- */ -EXTERN float mtof(float); -EXTERN float ftom(float); -EXTERN float rmstodb(float); -EXTERN float powtodb(float); -EXTERN float dbtorms(float); -EXTERN float dbtopow(float); - -EXTERN float q8_sqrt(float); -EXTERN float q8_rsqrt(float); -#ifndef N32 -EXTERN float qsqrt(float); /* old names kept for extern compatibility */ -EXTERN float qrsqrt(float); -#endif -/* --------------------- data --------------------------------- */ - -/* graphical arrays */ -typedef struct _garray t_garray; - -EXTERN t_class *garray_class; -EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec); -EXTERN float garray_get(t_garray *x, t_symbol *s, t_int indx); -EXTERN void garray_redraw(t_garray *x); -EXTERN int garray_npoints(t_garray *x); -EXTERN char *garray_vec(t_garray *x); -EXTERN void garray_resize(t_garray *x, t_floatarg f); -EXTERN void garray_usedindsp(t_garray *x); -EXTERN void garray_setsaveit(t_garray *x, int saveit); -EXTERN double garray_updatetime(t_garray *x); - -EXTERN t_class *scalar_class; - -EXTERN t_float *value_get(t_symbol *s); -EXTERN void value_release(t_symbol *s); -EXTERN int value_getfloat(t_symbol *s, t_float *f); -EXTERN int value_setfloat(t_symbol *s, t_float f); - -/* ------- GUI interface - functions to send strings to TK --------- */ -EXTERN void sys_vgui(const char *fmt, ...); -EXTERN void sys_gui(const char *s); - -extern t_class *glob_pdobject; /* object to send "pd" messages */ - -/*------------- Max 0.26 compatibility --------------------*/ - -#define t_getbytes getbytes -#define t_freebytes freebytes -#define t_resizebytes resizebytes -#define typedmess pd_typedmess -#define vmess pd_vmess - -/* A definition to help gui objects straddle 0.34-0.35 changes. If this is -defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */ - -#define PD_USE_TE_XPIX - -#ifdef __i386__ -/* a test for NANs and denormals. Should only be necessary on i386. */ -#define PD_BADFLOAT(f) ((((*(unsigned int*)&(f))&0x7f800000)==0) || \ - (((*(unsigned int*)&(f))&0x7f800000)==0x7f800000)) -/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */ -#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \ - (((*(unsigned int*)&(f))&0x60000000)==0x60000000)) -#else -#define PD_BADFLOAT(f) 0 -#define PD_BIGORSMALL(f) 0 -#endif - -/* tb: wrapper for PD_BIGORSMALL macro */ -EXTERN void testcopyvec(t_float *dst,const t_float *src,int n); -EXTERN void testaddvec(t_float *dst,const t_float *src,int n); - -/* tb's fifos */ -typedef struct _fifo t_fifo; -/* function prototypes */ -EXTERN t_fifo * fifo_init(void); -EXTERN void fifo_destroy(t_fifo*); -/* fifo_put() and fifo_get are the only threadsafe functions!!! */ -EXTERN void fifo_put(t_fifo*, void*); -EXTERN void* fifo_get(t_fifo*); - -#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) -} -#endif - -#define __m_pd_h_ -#endif /* __m_pd_h_ */ - -/* removed functions: - sys_fontwidth, sys_fontheight, t_widgetbehavior, class_setproperties, - class_setwidget, class_setparentwidget, class_parentwidget, pd_getparentwidget, - sys_pretendguibytes, sys_queuegui, sys_unqueuegui, getzbytes, - gfxstub_new, gfxstub_deleteforkey - removed fields: te_width, te_type. - */ -/* externs that use g_next directly can't work with desiredata: gui/state, clone, dyn, dynext, toxy, cyclone */ diff --git a/desiredata/src/m_sched.c b/desiredata/src/m_sched.c deleted file mode 100644 index 50b71af9..00000000 --- a/desiredata/src/m_sched.c +++ /dev/null @@ -1,655 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* scheduling stuff */ - -#include "desire.h" -#include <stdlib.h> - -/* for timeval */ -#ifdef UNISTD -#include <sys/time.h> -#endif -#ifdef __CYGWIN__ -#include <sys/time.h> -#endif -#ifdef MSW -#include "winsock.h" -#endif - -#include "assert.h" - -/* LATER consider making this variable. It's now the LCM of all sample - rates we expect to see: 32000, 44100, 48000, 88200, 96000. */ -#define TIMEUNITPERSEC (32.*441000.) - -/* T.Grill - enable PD global thread locking - sys_lock, sys_unlock, sys_trylock functions */ -#define THREAD_LOCKING -#include "pthread.h" -#include "time.h" - -static int sys_quit; -double sys_time; -static double sys_time_per_msec = TIMEUNITPERSEC / 1000.; - -/* tb: { */ -int sys_keepsched = 1; /* if 0: change scheduler mode */ -int sys_callbackscheduler = 0; /* if 1: change scheduler to callback based dsp */ -static void run_idle_callbacks(int microsec); -t_fifo * callback_fifo = NULL; -/* tb: }*/ - -int sys_usecsincelastsleep (); -int sys_sleepgrain; - -typedef void (*t_clockmethod)(void *client); - -#ifdef UNISTD -#include <unistd.h> -#endif - -struct _clock { - double settime; - void *owner; - t_clockmethod fn; - struct _clock *next; -}; - -t_clock *clock_setlist; -t_clock *clock_new(void *owner, t_method fn) { - t_clock *x = (t_clock *)malloc(sizeof(*x)); - x->settime = -1; - x->owner = owner; - x->fn = (t_clockmethod)fn; - x->next = 0; - return x; -} - -void clock_unset(t_clock *x) { - if (x->settime >= 0) { - if (x == clock_setlist) clock_setlist = x->next; - else { - t_clock *x2 = clock_setlist; - while (x2->next != x) x2 = x2->next; - x2->next = x->next; - } - x->settime = -1; - } -} - -/* set the clock to call back at an absolute system time */ -void clock_set(t_clock *x, double setticks) { - if (setticks < sys_time) setticks = sys_time; - clock_unset(x); - x->settime = setticks; - if (clock_setlist && clock_setlist->settime <= setticks) { - t_clock *cbefore, *cafter; - for (cbefore = clock_setlist, cafter = clock_setlist->next; cbefore; cbefore = cafter, cafter = cbefore->next) { - if (!cafter || cafter->settime > setticks) { - cbefore->next = x; - x->next = cafter; - return; - } - } - } else x->next = clock_setlist, clock_setlist = x; -} - -/* set the clock to call back after a delay in msec */ -void clock_delay(t_clock *x, double delaytime) { - clock_set(x, sys_time + sys_time_per_msec * delaytime); -} - -/* get current logical time. We don't specify what units this is in; - use clock_gettimesince() to measure intervals from time of this call. - This was previously, incorrectly named "clock_getsystime"; the old - name is aliased to the new one in m_pd.h. */ -double clock_getlogicaltime () {return sys_time;} - -/* OBSOLETE NAME */ -double clock_getsystime () {return sys_time;} - -/* elapsed time in milliseconds since the given system time */ -double clock_gettimesince(double prevsystime) { - return (sys_time - prevsystime)/sys_time_per_msec; -} - -/* what value the system clock will have after a delay */ -double clock_getsystimeafter(double delaytime) { - return sys_time + sys_time_per_msec * delaytime; -} - -void clock_free(t_clock *x) { - clock_unset(x); - free(x); -} - -/* the following routines maintain a real-execution-time histogram of the -various phases of real-time execution. */ - -static int sys_bin[] = {0, 2, 5, 10, 20, 30, 50, 100, 1000}; -#define NBIN (sizeof(sys_bin)/sizeof(*sys_bin)) -#define NHIST 10 -static int sys_histogram[NHIST][NBIN]; -static double sys_histtime; -static int sched_diddsp, sched_didpoll, sched_didnothing; - -void sys_clearhist () { - unsigned i,j; - for (i=0; i<NHIST; i++) for (j=0; j<NBIN; j++) sys_histogram[i][j] = 0; - sys_histtime = sys_getrealtime(); - sched_diddsp = sched_didpoll = sched_didnothing = 0; -} - -void sys_printhist () { - for (int i=0; i<NHIST; i++) { - int doit = 0; - for (unsigned int j=0; j<NBIN; j++) if (sys_histogram[i][j]) doit = 1; - if (doit) { - post("%2d %8d %8d %8d %8d %8d %8d %8d %8d", i, - sys_histogram[i][0], sys_histogram[i][1], sys_histogram[i][2], sys_histogram[i][3], - sys_histogram[i][4], sys_histogram[i][5], sys_histogram[i][6], sys_histogram[i][7]); - } - } - post("dsp %d, pollgui %d, nothing %d", sched_diddsp, sched_didpoll, sched_didnothing); -} - -static int sys_histphase; - -int sys_addhist(int phase) { - int phasewas = sys_histphase; - double newtime = sys_getrealtime(); - int msec = int((newtime-sys_histtime)*1000.); - for (int j=NBIN-1; j >= 0; j--) { - if (msec >= sys_bin[j]) { - sys_histogram[phasewas][j]++; - break; - } - } - sys_histtime = newtime; - sys_histphase = phase; - return phasewas; -} - -#define NRESYNC 20 - -struct t_resync { - int ntick; - int error; -}; - -static int oss_resyncphase = 0; -static int oss_nresync = 0; -static t_resync oss_resync[NRESYNC]; - -static const char *(oss_errornames[]) = { -"unknown", -"ADC blocked", -"DAC blocked", -"A/D/A sync", -"data late", -"xrun", -"sys_lock timeout" -}; - -void glob_audiostatus (void *dummy) { - int nresync, nresyncphase, i; - nresync = oss_nresync >= NRESYNC ? NRESYNC : oss_nresync; - nresyncphase = oss_resyncphase - 1; - post("audio I/O error history:"); - post("seconds ago\terror type"); - for (i = 0; i < nresync; i++) { - int errtype; - if (nresyncphase < 0) nresyncphase += NRESYNC; - errtype = oss_resync[nresyncphase].error; - if (errtype < 0 || errtype > 4) errtype = 0; - post("%9.2f\t%s", (sched_diddsp - oss_resync[nresyncphase].ntick) - * ((double)sys_schedblocksize) / sys_dacsr, oss_errornames[errtype]); - nresyncphase--; - } -} - -static int sched_diored; -static int sched_dioredtime; -static int sched_meterson; - -void sys_log_error(int type) { - oss_resync[oss_resyncphase].ntick = sched_diddsp; - oss_resync[oss_resyncphase].error = type; - oss_nresync++; - if (++oss_resyncphase == NRESYNC) oss_resyncphase = 0; - if (type != ERR_NOTHING && !sched_diored && (sched_diddsp >= sched_dioredtime)) { - sys_vgui("pdtk_pd_dio 1\n"); - sched_diored = 1; - } - sched_dioredtime = sched_diddsp + (int)(sys_dacsr /(double)sys_schedblocksize); -} - -static int sched_lastinclip, sched_lastoutclip, sched_lastindb, sched_lastoutdb; - -static void sched_pollformeters () { - int inclip, outclip, indb, outdb; - static int sched_nextmeterpolltime; - /* if there's no GUI but we're running in "realtime", here is - where we arrange to ping the watchdog every 2 seconds. */ -#ifdef __linux__ - static int sched_nextpingtime; - if (sys_hipriority && (sched_diddsp - sched_nextpingtime > 0)) { - glob_watchdog(0); - /* ping every 2 seconds */ - sched_nextpingtime = sched_diddsp + 2*(int)(sys_dacsr /(double)sys_schedblocksize); - } -#endif - if (sched_diddsp - sched_nextmeterpolltime < 0) return; - if (sched_diored && sched_diddsp-sched_dioredtime > 0) { - sys_vgui("pdtk_pd_dio 0\n"); - sched_diored = 0; - } - if (sched_meterson) { - float inmax, outmax; - sys_getmeters(&inmax, &outmax); - indb = int(0.5 + rmstodb(inmax)); - outdb = int(0.5 + rmstodb(outmax)); - inclip = inmax > 0.999; - outclip = outmax >= 1.0; - } else { - indb = outdb = 0; - inclip = outclip = 0; - } - if (inclip != sched_lastinclip || outclip != sched_lastoutclip - || indb != sched_lastindb || outdb != sched_lastoutdb) { - sys_vgui("pdtk_pd_meters %d %d %d %d\n", indb, outdb, inclip, outclip); - sched_lastinclip = inclip; - sched_lastoutclip = outclip; - sched_lastindb = indb; - sched_lastoutdb = outdb; - } - sched_nextmeterpolltime = sched_diddsp + (int)(sys_dacsr /(double)sys_schedblocksize); -} - -void glob_meters(void *dummy, float f) { - if (f == 0) sys_getmeters(0, 0); - sched_meterson = (f != 0); - sched_lastinclip = sched_lastoutclip = sched_lastindb = sched_lastoutdb = -1; -} - -#if 0 -void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv) { - if (argc) sys_clearhist(); - else sys_printhist(); -} -#endif - -extern void dsp_tick (); - -static int sched_usedacs = 0; -static double sched_referencerealtime, sched_referencelogicaltime; -double sys_time_per_dsp_tick; - -void sched_set_using_dacs(int flag) { - sched_usedacs = flag; - if (!flag) { - sched_referencerealtime = sys_getrealtime(); - sched_referencelogicaltime = clock_getlogicaltime(); - } - sys_time_per_dsp_tick = (TIMEUNITPERSEC) * ((double)sys_schedblocksize) / sys_dacsr; -} - -static void run_clock_callbacks(double next_sys_time) { - if (clock_setlist && clock_setlist->settime <= next_sys_time) { - do { - t_clock *c = clock_setlist; - sys_time = c->settime; - clock_unset(c); /* the compiler should easily inline this */ - outlet_setstacklim(); - c->fn(c->owner); - } while (clock_setlist && clock_setlist->settime <= next_sys_time); - } -} - -/* take the scheduler forward one DSP tick, also handling clock timeouts */ -void sched_tick(double next_sys_time) { - run_clock_callbacks(next_sys_time); - sys_time = next_sys_time; - sched_diddsp++; /* rethink: how to get rid of this stupid histogram??? */ - dsp_tick(); - /* rethink: should we really do all this midi messaging in the realtime thread ? */ - sys_pollmidiqueue(); - sys_setmiditimediff(0, 1e-6 * sys_schedadvance); -} - - -/* -Here is Pd's "main loop." This routine dispatches clock timeouts and DSP -"ticks" deterministically, and polls for input from MIDI and the GUI. If -we're left idle we also poll for graphics updates; but these are considered -lower priority than the rest. - -The time source is normally the audio I/O subsystem via the "sys_send_dacs()" -call. This call returns true if samples were transferred; false means that -the audio I/O system is still busy with previous transfers. -*/ - -void sys_pollmidiqueue (); -void sys_initmidiqueue (); - -void canvas_stop_dsp (); - -int m_scheduler () { - int idlecount = 0; - sys_time_per_dsp_tick = (TIMEUNITPERSEC) * ((double)sys_schedblocksize) / sys_dacsr; - /* T.Grill - lock mutex */ - sys_lock(); - sys_clearhist(); - /* tb: adapt sleepgrain with advance */ - sys_update_sleepgrain(); - sched_set_using_dacs(0); /* tb: dsp is switched off */ - sys_initmidiqueue(); - while (!sys_quit) { - if (!sys_callbackscheduler || !sched_usedacs) - while (sys_keepsched) { - int didsomething = 0; - int timeforward; - waitfortick: - if (sched_usedacs) { - timeforward = sys_send_dacs(); - /* if dacs remain "idle" for 1 sec, they're hung up. */ - if (timeforward != 0) - idlecount = 0; - else { - idlecount++; - if (!(idlecount & 31)) { - static double idletime; - /* on 32nd idle, start a clock watch; every 32 ensuing idles, check it */ - if (idlecount == 32) idletime = sys_getrealtime(); - else if (sys_getrealtime() - idletime > 1.) { - post("audio I/O stuck... closing audio"); - sys_close_audio(); - sched_set_using_dacs(0); - canvas_stop_dsp(); /* added by matju 2007.06.30 */ - goto waitfortick; - } - } - } - } else { - if (1000. * (sys_getrealtime() - sched_referencerealtime) > clock_gettimesince(sched_referencelogicaltime)) - timeforward = SENDDACS_YES; - else timeforward = SENDDACS_NO; - } - sys_setmiditimediff(0, 1e-6 * sys_schedadvance); - if (timeforward != SENDDACS_NO) sched_tick(sys_time + sys_time_per_dsp_tick); - if (timeforward == SENDDACS_YES) didsomething = 1; - sys_pollmidiqueue(); - if (sys_pollgui()) didsomething = 1; - /* test for idle; if so, do graphics updates. */ - if (!didsomething) { - sched_pollformeters(); - /* tb: call idle callbacks */ - if (timeforward != SENDDACS_SLEPT) run_idle_callbacks(sys_sleepgrain); - } - } - else /* tb: scheduler for callback-based dsp scheduling */ - while(sys_keepsched) { - /* tb: allow the audio callback to run */ - sys_unlock(); - sys_microsleep(sys_sleepgrain); - sys_lock(); - sys_pollmidiqueue(); - sys_setmiditimediff(0, 1e-6 * sys_schedadvance); - if (sys_pollgui()) continue; - /* do graphics updates and run idle callbacks */ - sched_pollformeters(); - } - sys_keepsched = 1; - } - sys_close_audio(); - sys_unlock(); - return 0; -} - -/* ------------ thread locking ------------------- */ -/* added by Thomas Grill */ - -#ifdef THREAD_LOCKING -static pthread_mutex_t sys_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t sys_cond = PTHREAD_COND_INITIALIZER; - -void sys_lock () { - pthread_mutex_lock(&sys_mutex); -} -void sys_unlock () { - pthread_mutex_unlock(&sys_mutex); - pthread_cond_signal(&sys_cond); -} -int sys_trylock () { - return pthread_mutex_trylock(&sys_mutex); -} - -/* tb { */ -#include <errno.h> - -#ifdef MSW -/* gettimeofday isn't available on windoze ... */ -int gettimeofday (struct timeval *tv, void* tz) { - __int64 now; /* time since 1 Jan 1601 in 100ns */ - GetSystemTimeAsFileTime ((FILETIME*) &now); - tv->tv_usec = (long) ((now / 10LL) % 1000000LL); - tv->tv_sec = (long) ((now - 116444736000000000LL) / 10000000LL); - return 0; -} -#endif - -#if 0 -/* osx doesn't define a pthread_mutex_timedlock ... maybe someday - it will ... */ -int sys_timedlock(int microsec) { - struct timespec timeout; - struct timeval now; - /* timedlock seems to have a resolution of 1ms */ - if (microsec < 1000) microsec = 1000; - gettimeofday(&now,0); - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = (now.tv_usec + microsec) * 1000; - while (timeout.tv_nsec > 1e9) { - timeout.tv_sec += 1; - timeout.tv_nsec -= 1e9; - } - int ret = pthread_mutex_timedlock(&sys_mutex, &timeout); - if (ret) post("timeout, %d", ret); - return ret; -} -#else - -int sys_timedlock(int microsec) { - struct timespec timeout; - struct timeval now; - if (sys_trylock() == 0) return 0; - if (microsec < 1000) microsec = 1000; - gettimeofday(&now,0); - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = (now.tv_usec + microsec) * 1000; - while (timeout.tv_nsec > 1000000000) { - timeout.tv_sec += 1; - timeout.tv_nsec -= 1000000000; - } - /* in case the lock has been released during the system call, try - again before waiting for the signal */ - if (sys_trylock() == 0) return 0; - return pthread_cond_timedwait(&sys_cond, &sys_mutex, &timeout); -} -#endif -/* tb } */ - -#else -void sys_lock () {} -void sys_unlock () {} -int sys_trylock () { return 0; } -int sys_timedlock (int microsec) { return 0; } -#endif - -/* ------------ soft quit ------------------- */ -/* added by Thomas Grill - - just set the quit flag for the scheduler loop - this is useful for applications using the PD shared library to signal the scheduler to terminate -*/ - -void sys_exit () { - sys_keepsched = 0; - sys_quit = 1; -} - -/* tb: place callbacks in scheduler - * { */ -/* linked list of callbacks; callback will be freed after returning 0 */ -struct t_sched_callback { - struct t_sched_callback *next; /* next callback in ringbuffer / in fifo */ - t_int (*function)(t_int *argv); - t_int *argv; - t_int argc; -}; - -void sys_callback(t_int (*callback)(t_int* argv), t_int* argv, t_int argc) { - t_sched_callback* noo = (t_sched_callback *)malloc(sizeof(t_sched_callback)); - noo->function = callback; - if (argv && argc) { - noo->argv = (t_int*) copybytes (argv, argc * sizeof (t_int)); - noo->argc = argc; - } else { - noo->argc = 0; - noo->argv = 0; - } - noo->next = 0; - if (!callback_fifo) callback_fifo = fifo_init(); - fifo_put(callback_fifo, noo); -} - -void sys_init_idle_callbacks () { - callback_fifo = fifo_init(); /* tb: initialize fifo for idle callbacks */ -} - -static t_sched_callback *ringbuffer_head = NULL; - -void run_all_idle_callbacks () { - t_sched_callback *new_callback; - /* append idle callback to ringbuffer */ - while ((new_callback = (t_sched_callback*) fifo_get(callback_fifo))) { - t_sched_callback *next; - /* set the next field to 0 ... it might be set in the fifo */ - new_callback->next = 0; - if (!ringbuffer_head) { - ringbuffer_head = new_callback; - } else { - next = ringbuffer_head; - while (next->next) next = next->next; - next->next = new_callback; - } - } - if (ringbuffer_head) { - t_sched_callback *idle_callback = ringbuffer_head; - t_sched_callback *last = 0; - t_sched_callback *next; - do { - int status; - status = (idle_callback->function)(idle_callback->argv); - switch (status) { - /* callbacks returning 0 will be deleted */ - case 0: - next = idle_callback->next; - if (idle_callback->argv) free(idle_callback->argv); - free((void*)idle_callback); - if (!last) ringbuffer_head = next; else last->next = next; - idle_callback = next; - /* callbacks returning 1 will be run again */ - case 1: - break; - /* callbacks returning 2 will be run during the next idle callback */ - case 2: - last = idle_callback; - idle_callback = idle_callback->next; - } - } while (idle_callback); - } -} - -static void run_idle_callbacks(int microsec) { - t_sched_callback *new_callback; - double stop = sys_getrealtime()*1.e6 + (double)microsec; - /* append idle callback to ringbuffer */ - while ((new_callback = (t_sched_callback*) fifo_get(callback_fifo))) { - /* set the next field to NULL ... it might be set in the fifo */ - new_callback->next = 0; - if (!ringbuffer_head) { - ringbuffer_head = new_callback; - } else { - t_sched_callback *next = ringbuffer_head; - while (next->next != 0) - next = next->next; - next->next = new_callback; - } - } - if (ringbuffer_head) { - double remain = stop - sys_getrealtime() * 1.e6; - t_sched_callback *idle_callback = ringbuffer_head; - t_sched_callback *last = 0; - t_sched_callback *next; - do { -// sys_lock(); - int status = idle_callback->function(idle_callback->argv); -// sys_unlock(); - switch (status) { - /* callbacks returning 0 will be deleted */ - case 0: - next = idle_callback->next; - if (idle_callback->argc) free(idle_callback->argv); - free((void*)idle_callback); - if (!last) ringbuffer_head = next; else last->next = next; - idle_callback = next; - /* callbacks returning 1 will be run again */ - case 1: - break; - /* callbacks returning 2 will be run during the next idle callback */ - case 2: - last = idle_callback; - idle_callback = idle_callback->next; - } - remain = stop-sys_getrealtime()*1.e6; - } while (idle_callback && remain>0); - /* sleep for the rest of the time */ - if(remain > 0) { - sys_unlock(); - sys_microsleep(int(remain)); - sys_lock(); - } - } else { - sys_unlock(); - sys_microsleep(microsec); - sys_lock(); - } -} -/* } tb */ - -void sys_setscheduler(int scheduler) { - sys_keepsched = 0; - sys_callbackscheduler = scheduler; - return; -} - -int sys_getscheduler () {return sys_callbackscheduler;} - -static t_int sys_xrun_notification_callback(t_int *dummy) { - t_symbol *pd = gensym("pd"); - t_symbol *xrun = gensym("xrun"); - typedmess(pd->s_thing, xrun, 0, 0); - return 0; -} - -void sys_xrun_notification () {sys_callback(sys_xrun_notification_callback, 0, 0);} - -static t_int sys_lock_timeout_notification_callback(t_int *dummy) { - t_symbol *pd = gensym("pd"); - t_symbol *timeout = gensym("sys_lock_timeout"); - typedmess(pd->s_thing, timeout, 0, 0); - return 0; -} - -void sys_lock_timeout_notification () {sys_callback(sys_lock_timeout_notification_callback, 0, 0);} diff --git a/desiredata/src/m_simd.c b/desiredata/src/m_simd.c deleted file mode 100644 index 1c0cb021..00000000 --- a/desiredata/src/m_simd.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - Implementation of general vectorized functions - added by T.Grill -*/ - -#include "m_pd.h" -#include "m_simd.h" - -void zerovec_8(t_float *dst,int n) -{ - for(n >>= 3; n--; dst += 8) { - dst[0] = dst[1] = dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = dst[7] = 0; - } -} - -void setvec_8(t_float *dst,t_float v,int n) -{ - for(n >>= 3; n--; dst += 8) { - dst[0] = dst[1] = dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = dst[7] = v; - } -} - -void copyvec_8(t_float *dst,const t_float *src,int n) -{ - for(n >>= 3; n--; src += 8,dst += 8) { - dst[0] = src[0],dst[1] = src[1],dst[2] = src[2],dst[3] = src[3]; - dst[4] = src[4],dst[5] = src[5],dst[6] = src[6],dst[7] = src[7]; - } -} - -void addvec_8(t_float *dst,const t_float *src,int n) -{ - for(n >>= 3; n--; src += 8,dst += 8) { - dst[0] += src[0],dst[1] += src[1],dst[2] += src[2],dst[3] += src[3]; - dst[4] += src[4],dst[5] += src[5],dst[6] += src[6],dst[7] += src[7]; - } -} - -void copyvec(t_float *dst,const t_float *src,int n) -{ - while(n--) - *dst++ = *src++; -} - -void zerovec(t_float *dst, int n) -{ - while(n--) - *dst++ = 0; -} - - -void addvec(t_float *dst,const t_float *src,int n) -{ - while(n--) - *dst++ += *src++; -} - - -void testcopyvec_8(t_float *dst,const t_float *src,int n) -{ - while(n--) { - *(dst++) = (PD_BIGORSMALL(*src) ? 0 : *src); src++; - } -} - -void testcopyvec(t_float *dst,const t_float *src,int n) -{ - testcopyvec_8(dst, src, n); -} - -void testaddvec_8(t_float *dst,const t_float *src,int n) -{ - while(n--) { - *(dst++) += (PD_BIGORSMALL(*src) ? 0 : *src); src++; - } -} - -void testaddvec(t_float *dst,const t_float *src,int n) -{ - testaddvec_8(dst, src, n); -} - - -int simd_check1(t_int n, t_float* ptr1) -{ - return SIMD_CHECK1(n,ptr1); -} - -int simd_check2(t_int n, t_float* ptr1, t_float* ptr2) -{ - return SIMD_CHECK2(n,ptr1,ptr2); -} - -int simd_check3(t_int n, t_float* ptr1, t_float* ptr2, t_float* ptr3) -{ - return SIMD_CHECK3(n,ptr1,ptr2,ptr3); -} - - - -#ifdef DONTUSESIMD -int simd_runtime_check() -{ - return 0; -} - -/* tb: wrapper for simd functions */ -void zerovec_simd(t_float *dst,int n) -{ - zerovec_8(dst,n); -} - -void setvec_simd(t_float *dst,t_float v,int n) -{ - setvec_8(dst,v,n); -} - -void copyvec_simd(t_float *dst,const t_float *src,int n) -{ - copyvec_8(dst,src,n); -} - -void copyvec_simd_unalignedsrc(t_float *dst,const t_float *src,int n) -{ - copyvec_8(dst,src,n); -} - -void addvec_simd(t_float *dst,const t_float *src,int n) -{ - addvec_8(dst,src,n); -} - -void testcopyvec_simd(t_float *dst,const t_float *src,int n) -{ - testcopyvec_8(dst,src,n); -} - -void testaddvec_simd(t_float *dst,const t_float *src,int n) -{ - testaddvec_8(dst,src,n); -} - - -#endif /* DONTUSESIMD */ - diff --git a/desiredata/src/m_simd.h b/desiredata/src/m_simd.h deleted file mode 100644 index feeb78e0..00000000 --- a/desiredata/src/m_simd.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Definitions for SIMD functionality; added by T.Grill */ -#ifndef __M_SIMD_H -#define __M_SIMD_H - -/* general vector functions */ -void zerovec_8(t_float *dst,int n); -void setvec_8(t_float *dst,t_float v,int n); -void copyvec_8(t_float *dst,const t_float *src,int n); -void addvec_8(t_float *dst,const t_float *src,int n); -void testcopyvec_8(t_float *dst,const t_float *src,int n); -void testaddvec_8(t_float *dst,const t_float *src,int n); - -#define SIMD_BYTEALIGN (128/8) - -/* how many floats do we calculate in the loop of a SIMD codelet? */ -#define SIMD_BLOCK 16 /* must be a power of 2 */ - -//#if defined(__GNUC__) && (defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)) -#ifdef SIMD_SSE /* Intel SSE with GNU C */ /* ought to add this in configure.in */ -t_int *sigwrap_perf_simd(t_int *w); -void line_tilde_slope_simd(t_float* out, t_int n, t_float* value, t_float* slopes, t_float* slopestep); -float env_tilde_accum_simd(t_float* in, t_float* hp, t_int n); -t_int* sigsqrt_perf_simd(t_int *w); -t_int* sigrsqrt_perf_simd(t_int *w); -float peakvec_simd(t_float* vec, t_int n, t_float cur_max); -#endif - -//#if defined(__GNUC__) && defined(__POWERPC__) && defined(__ALTIVEC__) -#ifdef SIMD_ALTIVEC /* Altivec with GNU C ( -faltivec must be given as a compiler option! ) */ /* ought to add this in configure.in */ - #include "m_simd_ve_gcc.h" -#endif - -#ifdef DONTUSESIMD - /* This is used when there's no implementation of SIMD code for the current platform and/or compiler */ - /* These are the functions that can be coded for SIMD */ - #define zero_perf_simd zero_perf8 - #define copy_perf_simd copy_perf8 - #define sig_tilde_perf_simd sig_tilde_perf8 - #define sigwrap_perf_simd sigwrap_perform - #define line_tilde_slope_simd line_tilde_slope - #define env_tilde_accum_simd env_tilde_accum_8 /* it's a bad place to set that here since there's no public prototype */ - #define plus_perf_simd plus_perf8 - #define scalarplus_perf_simd scalarplus_perf8 - #define minus_perf_simd minus_perf8 - #define scalarminus_perf_simd scalarminus_perf8 - #define times_perf_simd times_perf8 - #define scalartimes_perf_simd scalartimes_perf8 - #define sqr_perf_simd sqr_perf8 - #define over_perf_simd over_perf8 - #define scalarover_perf_simd scalarover_perf8 - #define min_perf_simd min_perf8 - #define scalarmin_perf_simd scalarmin_perf8 - #define max_perf_simd max_perf8 - #define scalarmax_perf_simd scalarmax_perf8 - #define clip_perf_simd clip_perform /* SIMD not implemented */ - #define sigwrap_perf_simd sigwrap_perform /* SIMD not implemented */ - #define sigsqrt_perf_simd sigsqrt_perform /* SIMD not implemented */ - #define sigrsqrt_perf_simd sigrsqrt_perform /* SIMD not implemented */ - #define peakvec_simd peakvec - /* #define sum_vecsimd sumvec_8 */ -#endif - -/* check if n meets the requirements for SIMD codelets */ -#define SIMD_CHKCNT(n) ( ((n)&(SIMD_BLOCK-1)) == 0 ) -/* check if a pointer is correctly aligned for SIMD codelets */ -#define SIMD_CHKALIGN(ptr) ( ((size_t)(ptr) & (SIMD_BYTEALIGN-1)) == 0 ) -/* check n and 1 pointer at once */ -#define SIMD_CHECK1(n,ptr1) (SIMD_CHKCNT(n) && SIMD_CHKALIGN(ptr1) && simd_runtime_check()) -/* check n and 2 pointers at once */ -#define SIMD_CHECK2(n,ptr1,ptr2) (SIMD_CHKCNT(n) && SIMD_CHKALIGN(ptr1) && SIMD_CHKALIGN(ptr2) && simd_runtime_check()) -/* check n and 3 pointers at once */ -#define SIMD_CHECK3(n,ptr1,ptr2,ptr3) (SIMD_CHKCNT(n) && SIMD_CHKALIGN(ptr1) && SIMD_CHKALIGN(ptr2) && SIMD_CHKALIGN(ptr3) && simd_runtime_check()) - -/* T.Grill - bit alignment for signal vectors (must be a multiple of 8!) */ -/* if undefined no alignment occurs */ -#ifdef SIMD_BYTEALIGN - #define VECTORALIGNMENT (SIMD_BYTEALIGN*8) -#else - #define VECTORALIGNMENT 128 -#endif - -#endif /* __M_SIMD_H */ diff --git a/desiredata/src/m_simd_sse_gcc.c b/desiredata/src/m_simd_sse_gcc.c deleted file mode 100644 index 17182a59..00000000 --- a/desiredata/src/m_simd_sse_gcc.c +++ /dev/null @@ -1,1131 +0,0 @@ -/* - Implementation of SIMD functionality for Intel SSE with GCC compiler - added by T.Grill -*/ - -#include "m_pd.h" -#include "m_simd.h" - -#if defined(__GNUC__) && (defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__)) && !(defined DONTUSESIMD) - - -/* TB: adapted from thomas' vc routines */ - -/* dst is assumed to be aligned */ -void zerovec_simd(t_float *dst,int n) -{ - asm( - ".set T_FLOAT,4 \n" /* sizeof(t_float) */ - "xorps %%xmm0, %%xmm0 \n" /* zero value */ - "shr $4, %0 \n" - - /* should we do more loop unrolling? */ - /* *dst = 0 */ - "1: \n" - "movaps %%xmm0, (%1) \n" - "movaps %%xmm0, 4*T_FLOAT(%1) \n" - "movaps %%xmm0, 8*T_FLOAT(%1) \n" - "movaps %%xmm0, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT,%1 \n" - "loop 1b \n" - : - :"c"(n),"r"(dst) - :"%xmm0"); -} - -/* dst is assumed to be aligned */ -void setvec_simd(t_float *dst,t_float v,int n) -{ - asm( - ".set T_FLOAT,4 \n" /* sizeof(t_float) */ - "movss (%2),%%xmm0 \n" - "shufps $0,%%xmm0,%%xmm0 \n" /* load value */ - "shr $4,%0 \n" - - /* should we do more loop unrolling? */ - /* *dst = v */ - "1: \n" - "movaps %%xmm0, (%1) \n" - "movaps %%xmm0, 4*T_FLOAT(%1) \n" - "movaps %%xmm0, 8*T_FLOAT(%1) \n" - "movaps %%xmm0, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT,%1 \n" - "loop 1b \n" - : - :"c"(n),"r"(dst),"r"(&v) - :"%xmm0"); -} - - -/* dst and src are assumed to be aligned */ -void copyvec_simd(t_float *dst,const t_float *src,int n) -{ - asm( - ".set T_FLOAT,4 \n" /* sizeof(t_float) */ - "shr $4, %0 \n" - - /* loop: *dst = *src */ - "1: \n" - "movaps (%1), %%xmm0 \n" - "movaps 4*T_FLOAT(%1), %%xmm1 \n" - "movaps 8*T_FLOAT(%1), %%xmm2 \n" - "movaps 12*T_FLOAT(%1), %%xmm3 \n" - "movaps %%xmm0, (%2) \n" - "movaps %%xmm1, 4*T_FLOAT(%2) \n" - "movaps %%xmm2, 8*T_FLOAT(%2) \n" - "movaps %%xmm3, 12*T_FLOAT(%2) \n" - - - "addl $16*T_FLOAT,%1 \n" - "addl $16*T_FLOAT,%2 \n" - "loop 1b \n" - : - :"c"(n),"r"(src),"r"(dst) - :"%xmm0","%xmm1","%xmm2","%xmm3"); -} - -/* dst is assumed to be aligned */ -void copyvec_simd_unalignedsrc(t_float *dst,const t_float *src,int n) -{ - asm( - ".set T_FLOAT,4 \n" /* sizeof(t_float) */ - "shr $4, %0 \n" - - /* loop: *dst = *src */ - "1: \n" - "movups (%1), %%xmm0 \n" - "movups 4*T_FLOAT(%1), %%xmm1 \n" - "movups 8*T_FLOAT(%1), %%xmm2 \n" - "movups 12*T_FLOAT(%1), %%xmm3 \n" - "movaps %%xmm0, (%2) \n" - "movaps %%xmm1, 4*T_FLOAT(%2) \n" - "movaps %%xmm2, 8*T_FLOAT(%2) \n" - "movaps %%xmm3, 12*T_FLOAT(%2) \n" - - - "addl $16*T_FLOAT,%1 \n" - "addl $16*T_FLOAT,%2 \n" - "loop 1b \n" - : - :"c"(n),"r"(src),"r"(dst) - :"%xmm0","%xmm1","%xmm2","%xmm3"); -} - - -/* dst and src are assumed to be aligned */ -void addvec_simd(t_float *dst,const t_float *src,int n) -{ - asm( - ".set T_FLOAT,4 \n" /* sizeof(t_float) */ - "shr $4, %0 \n" - - /* loop: *dst += *src */ - "1: \n" - "movaps (%2,%3),%%xmm0 \n" - "movaps (%1,%3),%%xmm1 \n" - "addps %%xmm0,%%xmm1 \n" - "movaps %%xmm1,(%2,%3) \n" - - "movaps 4*T_FLOAT(%2,%3),%%xmm0 \n" - "movaps 4*T_FLOAT(%1,%3),%%xmm1 \n" - "addps %%xmm0,%%xmm1 \n" - "movaps %%xmm1,4*T_FLOAT(%2,%3) \n" - - "movaps 8*T_FLOAT(%2,%3),%%xmm0 \n" - "movaps 8*T_FLOAT(%1,%3),%%xmm1 \n" - "addps %%xmm0,%%xmm1 \n" - "movaps %%xmm1,8*T_FLOAT(%2,%3) \n" - - "movaps 12*T_FLOAT(%2,%3),%%xmm0 \n" - "movaps 12*T_FLOAT(%1,%3),%%xmm1 \n" - "addps %%xmm0,%%xmm1 \n" - "movaps %%xmm1,12*T_FLOAT(%2,%3) \n" - - "addl $16*T_FLOAT,%3 \n" - "loop 1b \n" - : - : "c"(n),"r"(src),"r"(dst),"r"(0) - : "%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7"); -} - - -void testcopyvec_simd(t_float *dst,const t_float *src,int n) -{ - - asm( - ".section .rodata \n" - ".align 16 \n" - "2: \n" - ".long 1610612736 \n" /* bitmask */ - ".long 1610612736 \n" /* 0x60000000 */ - ".long 1610612736 \n" - ".long 1610612736 \n" - - ".set T_FLOAT,4 \n" - ".text \n" - - "shr $4, %0 \n" - "movaps (2b), %%xmm0 \n" /* xmm0 = bitmask */ - "xorps %%xmm1, %%xmm1 \n" /* xmm1 = 0x0 */ - - - "1: \n" - "movaps (%1), %%xmm2 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, (%2) \n" - - "movaps 4*T_FLOAT(%1), %%xmm2 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%1), %%xmm2 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%1), %%xmm2 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 12*T_FLOAT(%2) \n" - - - "addl $16*T_FLOAT,%1 \n" - "addl $16*T_FLOAT,%2 \n" - "decl %0 \n" - "jne 1b \n" - : - :"c"(n),"r"(src),"r"(dst) - :"%xmm0","%xmm1","%xmm2","%xmm3", "%xmm4"); -} - - -void testaddvec_simd(t_float *dst,const t_float *src,int n) -{ - asm( - ".section .rodata \n" - ".align 16 \n" - "2: \n" - ".long 1610612736 \n" /* bitmask */ - ".long 1610612736 \n" /* 0x60000000 */ - ".long 1610612736 \n" - ".long 1610612736 \n" - - ".set T_FLOAT,4 \n" - ".text \n" - - "shr $4, %0 \n" - "movaps (2b), %%xmm0 \n" /* xmm0 = bitmask */ - "xorps %%xmm1, %%xmm1 \n" /* xmm1 = 0x0 */ - - - "1: \n" - "movaps (%1), %%xmm2 \n" - "movaps (%2), %%xmm5 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "addps %%xmm2, %%xmm5 \n" - "movaps %%xmm5, (%2) \n" - - "movaps 4*T_FLOAT(%1), %%xmm2 \n" - "movaps 4*T_FLOAT(%2), %%xmm5 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "addps %%xmm2, %%xmm5 \n" - "movaps %%xmm5, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%1), %%xmm2 \n" - "movaps 8*T_FLOAT(%2), %%xmm5 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "addps %%xmm2, %%xmm5 \n" - "movaps %%xmm5, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%1), %%xmm2 \n" - "movaps 12*T_FLOAT(%2), %%xmm5 \n" - "movaps %%xmm2, %%xmm3 \n" - "andps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, %%xmm4 \n" - "cmpneqps %%xmm0, %%xmm3 \n" - "cmpneqps %%xmm1, %%xmm4 \n" - "andps %%xmm4, %%xmm3 \n" - "andps %%xmm3, %%xmm2 \n" - "addps %%xmm2, %%xmm5 \n" - "movaps %%xmm5, 12*T_FLOAT(%2) \n" - - - "addl $16*T_FLOAT,%1 \n" - "addl $16*T_FLOAT,%2 \n" - "decl %0 \n" - "jne 1b \n" - : - :"c"(n),"r"(src),"r"(dst) - :"%xmm0","%xmm1","%xmm2","%xmm3", "%xmm4", "%xmm5"); -} - - -t_int *zero_perf_simd(t_int *w) -{ - zerovec_simd((t_float *)w[1],w[2]); - return w+3; -} - -t_int *copy_perf_simd(t_int *w) -{ - copyvec_simd((t_float *)w[2],(const t_float *)w[1],w[3]); - return w+4; -} - -t_int *sig_tilde_perf_simd(t_int *w) -{ - setvec_simd((t_float *)w[2],*(const t_float *)w[1],w[3]); - return w+4; -} - - -t_int *plus_perf_simd (t_int * w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in1 + *in2 */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "addps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "addps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "addps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "addps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - - -t_int *scalarplus_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in + value */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "addps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "addps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "addps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "addps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0", "%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - -t_int *minus_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in1 - *in2 */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "subps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "subps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "subps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "subps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - -t_int* scalarminus_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in - value */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "subps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "subps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "subps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "subps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - - -t_int *times_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in1 * *in2 */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "mulps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "mulps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "mulps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "mulps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - -t_int* scalartimes_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in * value */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "mulps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "mulps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "mulps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "mulps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - -t_int *sqr_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %2 \n" /* divide by 16 */ - - /* loop: *out = *in * *in */ - "1: \n" - "movaps (%0,%3), %%xmm0 \n" - "mulps %%xmm0, %%xmm0 \n" - "movaps %%xmm0, (%1) \n" - - "movaps 4*T_FLOAT(%0,%3), %%xmm1 \n" - "mulps %%xmm1, %%xmm1 \n" - "movaps %%xmm1, 4*T_FLOAT(%1) \n" - - "movaps 8*T_FLOAT(%0,%3), %%xmm2 \n" - "mulps %%xmm2, %%xmm2 \n" - "movaps %%xmm2, 8*T_FLOAT(%1) \n" - - "movaps 12*T_FLOAT(%0,%3), %%xmm3 \n" - "mulps %%xmm3, %%xmm3 \n" - "movaps %%xmm3, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT, %1 \n" - "addl $16*T_FLOAT, %3 \n" - "loop 1b \n" - : - /* in, out, n */ - :"r"(w[1]),"r"(w[2]),"c"(w[3]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3" - ); - return w+4; -} - - -t_int* over_perf_simd(t_int * w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in1 / *in2 */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "divps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "divps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "divps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "divps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - -t_int* scalarover_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = *in / value */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "divps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "divps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "divps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "divps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - - -t_int* min_perf_simd(t_int * w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = min (*in1, *in2) */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "minps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "minps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "minps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "minps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - - -t_int* scalarmin_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = min(*in, value) */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "minps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "minps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "minps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "minps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - - -t_int* max_perf_simd(t_int * w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = max (*in1, *in2) */ - "1: \n" - "movaps (%0,%4), %%xmm0 \n" - "movaps (%1,%4), %%xmm1 \n" - "maxps %%xmm1, %%xmm0 \n" - "movaps %%xmm0, (%2,%4) \n" - - "movaps 4*T_FLOAT(%0,%4), %%xmm2 \n" - "movaps 4*T_FLOAT(%1,%4), %%xmm3 \n" - "maxps %%xmm3, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2,%4) \n" - - "movaps 8*T_FLOAT(%0,%4), %%xmm4 \n" - "movaps 8*T_FLOAT(%1,%4), %%xmm5 \n" - "maxps %%xmm5, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%2,%4) \n" - - "movaps 12*T_FLOAT(%0,%4), %%xmm6 \n" - "movaps 12*T_FLOAT(%1,%4), %%xmm7 \n" - "maxps %%xmm7, %%xmm6 \n" - "movaps %%xmm6, 12*T_FLOAT(%2,%4) \n" - - "addl $16*T_FLOAT, %4 \n" - "loop 1b \n" - : - /* in1, in2, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]),"r"(0) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" - ); - return w+5; -} - - -t_int* scalarmax_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%1), %%xmm0 \n" - "shufps $0, %%xmm0, %%xmm0 \n" - "shrl $4, %3 \n" /* divide by 16 */ - - /* loop: *out = max(*in, value) */ - "1: \n" - "movaps (%0), %%xmm1 \n" - "maxps %%xmm0, %%xmm1 \n" - "movaps %%xmm1, (%2) \n" - - "movaps 4*T_FLOAT(%0), %%xmm2 \n" - "maxps %%xmm0, %%xmm2 \n" - "movaps %%xmm2, 4*T_FLOAT(%2) \n" - - "movaps 8*T_FLOAT(%0), %%xmm3 \n" - "maxps %%xmm0, %%xmm3 \n" - "movaps %%xmm3, 8*T_FLOAT(%2) \n" - - "movaps 12*T_FLOAT(%0), %%xmm4 \n" - "maxps %%xmm0, %%xmm4 \n" - "movaps %%xmm4, 12*T_FLOAT(%2) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %2 \n" - "loop 1b \n" - : - /* in, value, out, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"c"(w[4]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4" - ); - return w+5; -} - -t_int* clip_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "movss (%2), %%xmm0 \n" /* lo */ - "shufps $0, %%xmm0, %%xmm0 \n" - "movss (%3), %%xmm1 \n" /* hi */ - "shufps $0, %%xmm1, %%xmm1 \n" - - "shrl $4, %4 \n" /* divide by 16 */ - - /* loop: *out = min ( max (lo, *in), hi )*/ - "1: \n" - "movaps (%0), %%xmm2 \n" - "maxps %%xmm0, %%xmm2 \n" - "minps %%xmm1, %%xmm2 \n" - "movaps %%xmm2, (%1) \n" - - "movaps 4*T_FLOAT(%0), %%xmm3 \n" - "maxps %%xmm0, %%xmm3 \n" - "minps %%xmm1, %%xmm3 \n" - "movaps %%xmm3, 4*T_FLOAT(%1) \n" - - "movaps 8*T_FLOAT(%0), %%xmm4 \n" - "maxps %%xmm0, %%xmm4 \n" - "minps %%xmm1, %%xmm4 \n" - "movaps %%xmm4, 8*T_FLOAT(%1) \n" - - "movaps 12*T_FLOAT(%0), %%xmm5 \n" - "maxps %%xmm0, %%xmm5 \n" - "minps %%xmm1, %%xmm5 \n" - "movaps %%xmm5, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %1 \n" - "loop 1b \n" - : - /* in, out, lo, hi, n */ - :"r"(w[1]),"r"(w[2]),"r"(w[3]),"r"(w[4]),"c"(w[5]) - :"%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5" - ); - return w+6; -} - - -t_int* sigsqrt_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %2 \n" /* divide by 16 */ - - /* loop: *out = sqrt(*in) */ - "1: \n" - "movaps (%0), %%xmm0 \n" - "sqrtps %%xmm0, %%xmm0 \n" - "movaps %%xmm0, (%1) \n" - - "movaps 4*T_FLOAT(%0), %%xmm1 \n" - "sqrtps %%xmm1, %%xmm1 \n" - "movaps %%xmm1, 4*T_FLOAT(%1) \n" - - "movaps 8*T_FLOAT(%0), %%xmm2 \n" - "sqrtps %%xmm2, %%xmm2 \n" - "movaps %%xmm2, 8*T_FLOAT(%1) \n" - - "movaps 12*T_FLOAT(%0), %%xmm3 \n" - "sqrtps %%xmm3, %%xmm3 \n" - "movaps %%xmm3, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %1 \n" - "loop 1b \n" - : - /* in, out, n */ - :"r"(w[1]),"r"(w[2]),"c"(w[3]) - :"%xmm0","%xmm1","%xmm2","%xmm3" - ); - return w+4; -} - - -t_int* sigrsqrt_perf_simd(t_int *w) -{ - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %2 \n" /* divide by 16 */ - - /* loop: *out = sqrt(*in) */ - "1: \n" - "movaps (%0), %%xmm0 \n" - "rsqrtps %%xmm0, %%xmm0 \n" - "movaps %%xmm0, (%1) \n" - - "movaps 4*T_FLOAT(%0), %%xmm1 \n" - "rsqrtps %%xmm1, %%xmm1 \n" - "movaps %%xmm1, 4*T_FLOAT(%1) \n" - - "movaps 8*T_FLOAT(%0), %%xmm2 \n" - "rsqrtps %%xmm2, %%xmm2 \n" - "movaps %%xmm2, 8*T_FLOAT(%1) \n" - - "movaps 12*T_FLOAT(%0), %%xmm3 \n" - "rsqrtps %%xmm3, %%xmm3 \n" - "movaps %%xmm3, 12*T_FLOAT(%1) \n" - - "addl $16*T_FLOAT, %0 \n" - "addl $16*T_FLOAT, %1 \n" - "loop 1b \n" - : - /* in, out, n */ - :"r"(w[1]),"r"(w[2]),"c"(w[3]) - :"%xmm0","%xmm1","%xmm2","%xmm3" - ); - return w+4; -} - - -/* TB: runtime check */ -int simd_runtime_check() -{ - unsigned int eax, edx, ret; - __asm__("push %%ebx \n" /* ebx might be used as PIC register :-( */ - "cpuid \n" - "pop %%ebx \n" - : "=a"(eax),"=d"(edx) : "a" (1): "cx"); - ret = 0x2000000 & edx; - return (ret); -} - -float env_tilde_accum_simd(t_float* in, t_float* hp, t_int n) -{ - float ret; - asm( - ".set T_FLOAT,4 \n" - - "shrl $4, %2 \n" /* divide by 16 */ - "xorps %%xmm2, %%xmm2 \n" /* zero values */ - "xorps %%xmm3, %%xmm3 \n" - "xorps %%xmm4, %%xmm4 \n" - "xorps %%xmm5, %%xmm5 \n" - - - "1: \n" - "movaps -4*T_FLOAT(%1), %%xmm0 \n" - "movhlps %%xmm0, %%xmm1 \n" /* reversing xmm0 CHECK!!!*/ - "shufps $68, %%xmm1, %%xmm0 \n" - "movaps (%3), %%xmm1 \n" - "mulps %%xmm0, %%xmm0 \n" - "mulps %%xmm1, %%xmm0 \n" - "addps %%xmm0, %%xmm2 \n" - - "movaps -8*T_FLOAT(%1), %%xmm0 \n" - "movhlps %%xmm0, %%xmm1 \n" /* reversing xmm0 */ - "shufps $68, %%xmm1, %%xmm0 \n" - "movaps 4*T_FLOAT(%3), %%xmm1 \n" - "mulps %%xmm0, %%xmm0 \n" - "mulps %%xmm1, %%xmm0 \n" - "addps %%xmm0, %%xmm2 \n" - - "movaps -12*T_FLOAT(%1), %%xmm0 \n" - "movhlps %%xmm0, %%xmm1 \n" /* reversing xmm0 */ - "shufps $68, %%xmm1, %%xmm0 \n" - "movaps 8*T_FLOAT(%3), %%xmm1 \n" - "mulps %%xmm0, %%xmm0 \n" - "mulps %%xmm1, %%xmm0 \n" - "addps %%xmm0, %%xmm2 \n" - - "movaps -16*T_FLOAT(%1), %%xmm0 \n" - "movhlps %%xmm0, %%xmm1 \n" /* reversing xmm0 */ - "shufps $68, %%xmm1, %%xmm0 \n" - "movaps 12*T_FLOAT(%3), %%xmm1 \n" - "mulps %%xmm0, %%xmm0 \n" - "mulps %%xmm1, %%xmm0 \n" - "addps %%xmm0, %%xmm2 \n" - - "addl $-16*T_FLOAT,%1 \n" - "addl $16*T_FLOAT,%3 \n" - "loop 1b \n" - - "movhlps %%xmm2, %%xmm3 \n" /* unpack xmm0 */ - "movups %%xmm2, %%xmm4 \n" - "movups %%xmm3, %%xmm5 \n" - "shufps $81, %%xmm4, %%xmm4 \n" - "shufps $81, %%xmm5, %%xmm5 \n" - - "addss %%xmm2, %%xmm3 \n" - "addss %%xmm3, %%xmm4 \n" - "addss %%xmm4, %%xmm5 \n" - - "movss %%xmm5, (%0) \n" - - : - :"r"(&ret),"r"(in),"c"(n), "r"(hp) - :"%xmm0","%xmm1","%xmm2","%xmm3", "%xmm4", "%xmm5"); - return ret; -} - - -float peakvec_simd(t_float* vec, t_int n, t_float cur_max) -{ - asm( - ".section .rodata \n" - ".align 16 \n" - "2: \n" - ".long 2147483647 \n" /* bitmask for abs */ - ".long 2147483647 \n" /* 0x7fffffff */ - ".long 2147483647 \n" - ".long 2147483647 \n" - - ".set T_FLOAT,4 \n" - ".text \n" - - "shrl $4, %2 \n" /* divide by 16 */ - "movaps (2b), %%xmm0 \n" - - "movss (%0), %%xmm5 \n" /* cur_max */ - "shufps $0, %%xmm5, %%xmm5 \n" - - "1: \n" - "movaps (%1), %%xmm1 \n" - "andps %%xmm0, %%xmm1 \n" - "maxps %%xmm1, %%xmm5 \n" - - "movaps 4*T_FLOAT(%1), %%xmm1 \n" - "andps %%xmm0, %%xmm1 \n" - "maxps %%xmm1, %%xmm5 \n" - - "movaps 8*T_FLOAT(%1), %%xmm1 \n" - "andps %%xmm0, %%xmm1 \n" - "maxps %%xmm1, %%xmm5 \n" - - "movaps 12*T_FLOAT(%1), %%xmm1 \n" - "andps %%xmm0, %%xmm1 \n" - "maxps %%xmm1, %%xmm5 \n" - - "addl $16*T_FLOAT, %1 \n" - "loop 1b \n" - - "movhlps %%xmm5, %%xmm2 \n" - "movaps %%xmm5, %%xmm3 \n" - "movaps %%xmm2, %%xmm4 \n" - "shufps $81, %%xmm3, %%xmm3 \n" - "shufps $81, %%xmm4, %%xmm4 \n" - - "maxss %%xmm2, %%xmm3 \n" - "maxss %%xmm3, %%xmm4 \n" - "maxss %%xmm4, %%xmm5 \n" - - "movss %%xmm5, (%0) \n" - - : - :"r"(&cur_max), "r"(vec),"c"(n) - :"%xmm0","%xmm1","%xmm2","%xmm3", "%xmm4", "%xmm5"); - - return cur_max; -} - -void line_tilde_slope_simd(t_float* out, t_int n, t_float* value, - t_float* slopes, t_float* slopestep) -{ - asm( - ".set T_FLOAT,4 \n" - "movss (%2),%%xmm0 \n" /* value */ - "shufps $0, %%xmm0, %%xmm0 \n" - "movaps (%3), %%xmm1 \n" /* slopes */ - - "addps %%xmm1, %%xmm0 \n" /* compute first output */ - - "movss (%4), %%xmm2 \n" /* slopestep */ - "shufps $0, %%xmm2, %%xmm2 \n" - - "shrl $4, %1 \n" /* n>>4 */ - - "1: \n" - "movaps %%xmm0, (%0) \n" - "addps %%xmm2, %%xmm0 \n" - - "movaps %%xmm0, 4*T_FLOAT(%0) \n" - "addps %%xmm2, %%xmm0 \n" - - "movaps %%xmm0, 8*T_FLOAT(%0) \n" - "addps %%xmm2, %%xmm0 \n" - - "movaps %%xmm0, 12*T_FLOAT(%0) \n" - "addps %%xmm2, %%xmm0 \n" - - - "addl $16*T_FLOAT, %0 \n" - "loop 1b \n" - - - : - :"r"(out),"c"(n), "r"(value), "r"(slopes), - "r"(slopestep) - :"%xmm0", "%xmm1", "%xmm2"); - -} - -#endif - diff --git a/desiredata/src/m_simd_ve_gcc.c b/desiredata/src/m_simd_ve_gcc.c deleted file mode 100644 index 1f08d748..00000000 --- a/desiredata/src/m_simd_ve_gcc.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - Implementation of SIMD functionality for Apple Velocity Engine (AltiVec) with GCC compiler - added by T.Grill -*/ - -#include "m_pd.h" -#include "m_simd.h" - -#if defined(__GNUC__) && defined(__POWERPC__) && defined(__ALTIVEC__) - -//#define USEVECLIB - -#ifdef USEVECLIB -#include <vecLib/vDSP.h> -#include <vecLib/vfp.h> -#endif - -/* functions for unaligned vector data - taken from http://developer.apple.com/hardware/ve/alignment.html */ - -/* T.Grill - this first version _should_ work! but it doesn't... */ -#if 0 -#define LoadUnaligned(v) (vec_perm( vec_ld( 0, (const vector float *)(v) ), vec_ld( 16, (const vector float *)(v) ), vec_lvsl( 0, (float *) (v) ) )) -#else -/* instead take the slower second one */ -static vector float LoadUnaligned(const float *v) -{ - union tmpstruct { float f[4]; vector float vec; } tmp; - tmp.f[0] = *(float *)v; - return vec_splat(vec_ld(0,&tmp.vec),0); -} -#endif - - -#define IsVectorAligned(where) ((unsigned long)(where)&(sizeof(vector float)-1) == 0) -/* -#define LoadValue(where) (IsVectorAligned((void *)(where))?vec_splat(vec_ld(0,(vector float *)(where)),0):LoadUnaligned((vector float *)(where))) -*/ -/* always assume unaligned */ -#define LoadValue(where) LoadUnaligned((const float *)(where)) - -void zerovec_simd(t_float *dst,int n) -{ - const vector float zero = (vector float)(0); - for(n >>= 4; n--; dst += 16) { - vec_st(zero, 0,dst); - vec_st(zero,16,dst); - vec_st(zero,32,dst); - vec_st(zero,48,dst); - } -} - -void setvec_simd(t_float *dst,t_float v,int n) -{ - const vector float arg = LoadValue(&v); - for(n >>= 4; n--; dst += 16) { - vec_st(arg, 0,dst); - vec_st(arg,16,dst); - vec_st(arg,32,dst); - vec_st(arg,48,dst); - } -} - -void copyvec_simd(t_float *dst,const t_float *src,int n) -{ - for(n >>= 4; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -} - -void addvec_simd(t_float *dst,const t_float *src,int n) -{ -#ifdef USEVECLIB - vadd(dst,1,src,1,dst,1,n); -#else - for(n >>= 4; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,dst),b1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,dst),b2 = vec_ld(16,src); - vector float a3 = vec_ld(32,dst),b3 = vec_ld(32,src); - vector float a4 = vec_ld(48,dst),b4 = vec_ld(48,src); - - a1 = vec_add(a1,b1); - a2 = vec_add(a2,b2); - a3 = vec_add(a3,b3); - a4 = vec_add(a4,b4); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif -} - -/* no bad float testing for PPC! */ -void testcopyvec_simd(t_float *dst,const t_float *src,int n) -{ - copyvec_simd(dst,src,n); -} - -void testaddvec_simd(t_float *dst,const t_float *src,int n) -{ - addvec_simd(dst,src,n); -} - - -t_int *zero_perf_simd(t_int *w) -{ - zerovec_simd((t_float *)w[1],w[2]); - return w+3; -} - -t_int *copy_perf_simd(t_int *w) -{ - copyvec_simd((t_float *)w[2],(const t_float *)w[1],w[3]); - return w+4; -} - -t_int *sig_tilde_perf_simd(t_int *w) -{ - setvec_simd((t_float *)w[2],*(const t_float *)w[1],w[3]); - return w+4; -} - -t_int *plus_perf_simd(t_int *w) -{ -#ifdef USEVECLIB - vadd((const t_float *)w[1],1,(const t_float *)w[2],1,(t_float *)w[3],1,w[4]); -#else - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { - vector float a1 = vec_ld( 0,src1),b1 = vec_ld( 0,src2); - vector float a2 = vec_ld(16,src1),b2 = vec_ld(16,src2); - vector float a3 = vec_ld(32,src1),b3 = vec_ld(32,src2); - vector float a4 = vec_ld(48,src1),b4 = vec_ld(48,src2); - - a1 = vec_add(a1,b1); - a2 = vec_add(a2,b2); - a3 = vec_add(a3,b3); - a4 = vec_add(a4,b4); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - return w+5; -} - -t_int *scalarplus_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - const vector float arg = LoadValue(w[2]); - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_add(a1,arg); - a2 = vec_add(a2,arg); - a3 = vec_add(a3,arg); - a4 = vec_add(a4,arg); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *minus_perf_simd(t_int *w) -{ -#if 0 //def USEVECLIB - /* vsub is buggy for some OSX versions! */ - vsub((const t_float *)w[1],1,(const t_float *)w[2],1,(t_float *)w[3],1,w[4]); -#else - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { - vector float a1 = vec_ld( 0,src1),b1 = vec_ld( 0,src2); - vector float a2 = vec_ld(16,src1),b2 = vec_ld(16,src2); - vector float a3 = vec_ld(32,src1),b3 = vec_ld(32,src2); - vector float a4 = vec_ld(48,src1),b4 = vec_ld(48,src2); - - a1 = vec_sub(a1,b1); - a2 = vec_sub(a2,b2); - a3 = vec_sub(a3,b3); - a4 = vec_sub(a4,b4); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - return w+5; -} - -t_int *scalarminus_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - const vector float arg = LoadValue(w[2]); - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_sub(a1,arg); - a2 = vec_sub(a2,arg); - a3 = vec_sub(a3,arg); - a4 = vec_sub(a4,arg); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *times_perf_simd(t_int *w) -{ -#ifdef USEVECLIB - vmul((const t_float *)w[1],1,(const t_float *)w[2],1,(t_float *)w[3],1,w[4]); -#else - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - const vector float zero = (vector float)(0); - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { - vector float a1 = vec_ld( 0,src1),b1 = vec_ld( 0,src2); - vector float a2 = vec_ld(16,src1),b2 = vec_ld(16,src2); - vector float a3 = vec_ld(32,src1),b3 = vec_ld(32,src2); - vector float a4 = vec_ld(48,src1),b4 = vec_ld(48,src2); - - a1 = vec_madd(a1,b1,zero); - a2 = vec_madd(a2,b2,zero); - a3 = vec_madd(a3,b3,zero); - a4 = vec_madd(a4,b4,zero); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - return w+5; -} - -t_int *scalartimes_perf_simd(t_int *w) -{ -#ifdef USEVECLIB - vsmul((const t_float *)w[1],1,(t_float *)w[2],(t_float *)w[3],1,w[4]); -#else - const t_float *src = (const t_float *)w[1]; - const vector float arg = LoadValue(w[2]); - t_float *dst = (t_float *)w[3]; - const vector float zero = (vector float)(0); - int n = w[4]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_madd(a1,arg,zero); - a2 = vec_madd(a2,arg,zero); - a3 = vec_madd(a3,arg,zero); - a4 = vec_madd(a4,arg,zero); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - return w+5; -} - -t_int *sqr_perf_simd(t_int *w) -{ -#ifdef USEVECLIB - vsq((const t_float *)w[1],1,(t_float *)w[2],1,w[3]); -#else - const t_float *src = (const t_float *)w[1]; - t_float *dst = (t_float *)w[2]; - const vector float zero = (vector float)(0); - int n = w[3]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_madd(a1,a1,zero); - a2 = vec_madd(a2,a2,zero); - a3 = vec_madd(a3,a3,zero); - a4 = vec_madd(a4,a4,zero); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - return w+4; -} - -t_int *over_perf_simd(t_int *w) -{ - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - const vector float zero = (vector float)(0); - const vector float one = (vector float)(1); - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { -#ifdef USEVECLIB - /* no zero checking here */ - vec_st(vdivf(vec_ld( 0,src1),vec_ld( 0,src2)), 0,dst); - vec_st(vdivf(vec_ld(16,src1),vec_ld(16,src2)),16,dst); - vec_st(vdivf(vec_ld(32,src1),vec_ld(32,src2)),32,dst); - vec_st(vdivf(vec_ld(48,src1),vec_ld(48,src2)),48,dst); -#else - vector float data1 = vec_ld( 0,src2); - vector float data2 = vec_ld(16,src2); - vector float data3 = vec_ld(32,src2); - vector float data4 = vec_ld(48,src2); - - vector unsigned char mask1 = vec_nor((vector unsigned char)vec_cmpeq(data1,zero),(vector unsigned char)zero); /* bit mask... all 0 for data = 0., all 1 else */ - vector unsigned char mask2 = vec_nor((vector unsigned char)vec_cmpeq(data2,zero),(vector unsigned char)zero); /* bit mask... all 0 for data = 0., all 1 else */ - vector unsigned char mask3 = vec_nor((vector unsigned char)vec_cmpeq(data3,zero),(vector unsigned char)zero); /* bit mask... all 0 for data = 0., all 1 else */ - vector unsigned char mask4 = vec_nor((vector unsigned char)vec_cmpeq(data4,zero),(vector unsigned char)zero); /* bit mask... all 0 for data = 0., all 1 else */ - - /* make estimated reciprocal and zero out NANs */ - vector float tmp1 = vec_re(data1); - vector float tmp2 = vec_re(data2); - vector float tmp3 = vec_re(data3); - vector float tmp4 = vec_re(data4); - - tmp1 = (vector float)vec_and((vector unsigned char)tmp1,mask1); - tmp2 = (vector float)vec_and((vector unsigned char)tmp2,mask2); - tmp3 = (vector float)vec_and((vector unsigned char)tmp3,mask3); - tmp4 = (vector float)vec_and((vector unsigned char)tmp4,mask4); - - data1 = vec_madd( vec_nmsub( tmp1, data1, one ), tmp1, tmp1 ); - data2 = vec_madd( vec_nmsub( tmp2, data2, one ), tmp2, tmp2 ); - data3 = vec_madd( vec_nmsub( tmp3, data3, one ), tmp3, tmp3 ); - data4 = vec_madd( vec_nmsub( tmp4, data4, one ), tmp4, tmp4 ); - - tmp1 = vec_ld( 0,src1); - tmp2 = vec_ld(16,src1); - tmp3 = vec_ld(32,src1); - tmp4 = vec_ld(48,src1); - - data1 = vec_madd(tmp1,data1,zero); - data2 = vec_madd(tmp2,data2,zero); - data3 = vec_madd(tmp3,data3,zero); - data4 = vec_madd(tmp4,data4,zero); - - vec_st(data1, 0,dst); - vec_st(data2,16,dst); - vec_st(data3,32,dst); - vec_st(data4,48,dst); -#endif - } - return w+5; -} - -t_int *scalarover_perf_simd(t_int *w) -{ - t_float *dst = (t_float *)w[3]; - const vector float zero = (vector float)(0); - int n = w[4]>>4; - - if(*(t_float *)w[2]) { - const t_float *src = (const t_float *)w[1]; -#ifdef USEVECLIB - float arg = *(t_float *)w[2]?1./ *(t_float *)w[2]: 0; - vsmul(src,1,&arg,dst,1,w[4]); -#else - const vector float v = LoadValue(w[2]); - const vector float one = (vector float)(1); - - vector float estimate = vec_re(v); - vector float arg = vec_madd( vec_nmsub( estimate, v, one ), estimate, estimate ); - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_madd(a1,arg,zero); - a2 = vec_madd(a2,arg,zero); - a3 = vec_madd(a3,arg,zero); - a4 = vec_madd(a4,arg,zero); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } -#endif - } - else { - /* zero all output */ - for(; n--; dst += 16) { - vec_st(zero, 0,dst); - vec_st(zero,16,dst); - vec_st(zero,32,dst); - vec_st(zero,48,dst); - } - } - return w+5; -} - -t_int *min_perf_simd(t_int *w) -{ - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { - vector float a1 = vec_ld( 0,src1),b1 = vec_ld( 0,src2); - vector float a2 = vec_ld(16,src1),b2 = vec_ld(16,src2); - vector float a3 = vec_ld(32,src1),b3 = vec_ld(32,src2); - vector float a4 = vec_ld(48,src1),b4 = vec_ld(48,src2); - - a1 = vec_min(a1,b1); - a2 = vec_min(a2,b2); - a3 = vec_min(a3,b3); - a4 = vec_min(a4,b4); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *scalarmin_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - const vector float arg = LoadValue(w[2]); - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_min(a1,arg); - a2 = vec_min(a2,arg); - a3 = vec_min(a3,arg); - a4 = vec_min(a4,arg); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *max_perf_simd(t_int *w) -{ - const t_float *src1 = (const t_float *)w[1]; - const t_float *src2 = (const t_float *)w[2]; - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src1 += 16,src2 += 16,dst += 16) { - vector float a1 = vec_ld( 0,src1),b1 = vec_ld( 0,src2); - vector float a2 = vec_ld(16,src1),b2 = vec_ld(16,src2); - vector float a3 = vec_ld(32,src1),b3 = vec_ld(32,src2); - vector float a4 = vec_ld(48,src1),b4 = vec_ld(48,src2); - - a1 = vec_max(a1,b1); - a2 = vec_max(a2,b2); - a3 = vec_max(a3,b3); - a4 = vec_max(a4,b4); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *scalarmax_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - const vector float arg = LoadValue(w[2]); - t_float *dst = (t_float *)w[3]; - int n = w[4]>>4; - - for(; n--; src += 16,dst += 16) { - vector float a1 = vec_ld( 0,src); - vector float a2 = vec_ld(16,src); - vector float a3 = vec_ld(32,src); - vector float a4 = vec_ld(48,src); - - a1 = vec_max(a1,arg); - a2 = vec_max(a2,arg); - a3 = vec_max(a3,arg); - a4 = vec_max(a4,arg); - - vec_st(a1, 0,dst); - vec_st(a2,16,dst); - vec_st(a3,32,dst); - vec_st(a4,48,dst); - } - return w+5; -} - -t_int *clip_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - t_float *dst = (t_float *)w[2]; - const vector float lo = LoadValue(w[3]); - const vector float hi = LoadValue(w[4]); - int n = w[5]>>4; - - for(; n--; src += 16,dst += 16) { - vector float data1 = vec_ld( 0,src); - vector float data2 = vec_ld(16,src); - vector float data3 = vec_ld(32,src); - vector float data4 = vec_ld(48,src); - - vector unsigned char mlo1 = (vector unsigned char)vec_cmple(data1,lo); /* bit mask data <= lo */ - vector unsigned char mlo2 = (vector unsigned char)vec_cmple(data2,lo); /* bit mask data <= lo */ - vector unsigned char mlo3 = (vector unsigned char)vec_cmple(data3,lo); /* bit mask data <= lo */ - vector unsigned char mlo4 = (vector unsigned char)vec_cmple(data4,lo); /* bit mask data <= lo */ - - vector unsigned char mhi1 = (vector unsigned char)vec_cmpge(data1,hi); /* bit mask data >= hi */ - vector unsigned char mhi2 = (vector unsigned char)vec_cmpge(data2,hi); /* bit mask data >= hi */ - vector unsigned char mhi3 = (vector unsigned char)vec_cmpge(data3,hi); /* bit mask data >= hi */ - vector unsigned char mhi4 = (vector unsigned char)vec_cmpge(data4,hi); /* bit mask data >= hi */ - - data1 = (vector float)vec_and((vector unsigned char)data1,vec_nor(mlo1,mhi1)); - data2 = (vector float)vec_and((vector unsigned char)data2,vec_nor(mlo2,mhi2)); - data3 = (vector float)vec_and((vector unsigned char)data3,vec_nor(mlo3,mhi3)); - data4 = (vector float)vec_and((vector unsigned char)data4,vec_nor(mlo4,mhi4)); - - mlo1 = vec_and((vector unsigned char)lo,mlo1); - mlo2 = vec_and((vector unsigned char)lo,mlo2); - mlo3 = vec_and((vector unsigned char)lo,mlo3); - mlo4 = vec_and((vector unsigned char)lo,mlo4); - - mhi1 = vec_and((vector unsigned char)hi,mhi1); - mhi2 = vec_and((vector unsigned char)hi,mhi2); - mhi3 = vec_and((vector unsigned char)hi,mhi3); - mhi4 = vec_and((vector unsigned char)hi,mhi4); - - data1 = (vector float)vec_or(vec_or(mlo1,mhi1),(vector unsigned char)data1); - data2 = (vector float)vec_or(vec_or(mlo2,mhi2),(vector unsigned char)data2); - data3 = (vector float)vec_or(vec_or(mlo3,mhi3),(vector unsigned char)data3); - data4 = (vector float)vec_or(vec_or(mlo4,mhi4),(vector unsigned char)data4); - - vec_st(data1, 0,dst); - vec_st(data2,16,dst); - vec_st(data3,32,dst); - vec_st(data4,48,dst); - } - return w+6; -} - -t_int *sigwrap_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - t_float *dst = (t_float *)w[2]; - int n = w[3]>>4; - - for(; n--; src += 16,dst += 16) { - vector float data1 = vec_ld( 0,src); - vector float data2 = vec_ld(16,src); - vector float data3 = vec_ld(32,src); - vector float data4 = vec_ld(48,src); - - data1 = vec_sub(data1,vec_floor(data1)); - data2 = vec_sub(data2,vec_floor(data2)); - data3 = vec_sub(data3,vec_floor(data3)); - data4 = vec_sub(data4,vec_floor(data4)); - - vec_st(data1, 0,dst); - vec_st(data2,16,dst); - vec_st(data3,32,dst); - vec_st(data4,48,dst); - } - return w+4; -} - -t_int *sigsqrt_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - t_float *dst = (t_float *)w[2]; - int n = w[3]>>4; - - const vector float zero = (vector float)(0); - const vector float oneHalf = (vector float)(0.5); - const vector float one = (vector float)(1.0); - - for(; n--; src += 16,dst += 16) { - /* http://developer.apple.com/hardware/ve/algorithms.html - - Just as in Miller's scalar sigsqrt_perform, - first a rsqrt estimate is calculated which is then refined by one round of Newton-Raphson. - Here, to avoid branching a mask is generated which zeroes out eventual resulting NANs. - */ - -#ifdef USEVECLIB - /* no zero checking here */ - vec_st(vsqrtf(vec_ld( 0,src)), 0,dst); - vec_st(vsqrtf(vec_ld(16,src)),16,dst); - vec_st(vsqrtf(vec_ld(32,src)),32,dst); - vec_st(vsqrtf(vec_ld(48,src)),48,dst); -#else - vector float data1 = vec_ld( 0,src); - vector float data2 = vec_ld(16,src); - vector float data3 = vec_ld(32,src); - vector float data4 = vec_ld(48,src); - - const vector unsigned char mask1 = vec_nor((vector unsigned char)vec_cmple(data1,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask2 = vec_nor((vector unsigned char)vec_cmple(data2,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask3 = vec_nor((vector unsigned char)vec_cmple(data3,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask4 = vec_nor((vector unsigned char)vec_cmple(data4,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - - const vector float estimate1 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data1),mask1); - const vector float estimate2 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data2),mask2); - const vector float estimate3 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data3),mask3); - const vector float estimate4 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data4),mask4); - - /* this can still be improved.... */ - data1 = vec_madd(data1,vec_madd( vec_nmsub( data1, vec_madd( estimate1, estimate1, zero ), one ), vec_madd( estimate1, oneHalf, zero ), estimate1 ), zero); - data2 = vec_madd(data2,vec_madd( vec_nmsub( data2, vec_madd( estimate2, estimate2, zero ), one ), vec_madd( estimate2, oneHalf, zero ), estimate2 ), zero); - data3 = vec_madd(data3,vec_madd( vec_nmsub( data3, vec_madd( estimate3, estimate3, zero ), one ), vec_madd( estimate3, oneHalf, zero ), estimate3 ), zero); - data4 = vec_madd(data4,vec_madd( vec_nmsub( data4, vec_madd( estimate4, estimate4, zero ), one ), vec_madd( estimate4, oneHalf, zero ), estimate4 ), zero); - - vec_st(data1, 0,dst); - vec_st(data2,16,dst); - vec_st(data3,32,dst); - vec_st(data4,48,dst); -#endif - } - return w+4; -} - -/* Attention: there's a difference to sigsqrt_perform which delivers non-zero for a zero input... i don't think the latter is intended... */ -t_int *sigrsqrt_perf_simd(t_int *w) -{ - const t_float *src = (const t_float *)w[1]; - t_float *dst = (t_float *)w[2]; - int n = w[3]>>4; - - const vector float zero = (vector float)(0); - const vector float oneHalf = (vector float)(0.5); - const vector float one = (vector float)(1.0); - - for(; n--; src += 16,dst += 16) { - /* http://developer.apple.com/hardware/ve/algorithms.html - - Just as in Miller's scalar sigrsqrt_perform, - first a rsqrt estimate is calculated which is then refined by one round of Newton-Raphson. - Here, to avoid branching a mask is generated which zeroes out eventual resulting NANs. - */ - -#ifdef USEVECLIB - /* no zero checking here */ - vec_st(vrsqrtf(vec_ld( 0,src)), 0,dst); - vec_st(vrsqrtf(vec_ld(16,src)),16,dst); - vec_st(vrsqrtf(vec_ld(32,src)),32,dst); - vec_st(vrsqrtf(vec_ld(48,src)),48,dst); -#else - vector float data1 = vec_ld( 0,src); - vector float data2 = vec_ld(16,src); - vector float data3 = vec_ld(32,src); - vector float data4 = vec_ld(48,src); - - const vector unsigned char mask1 = vec_nor((vector unsigned char)vec_cmple(data1,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask2 = vec_nor((vector unsigned char)vec_cmple(data2,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask3 = vec_nor((vector unsigned char)vec_cmple(data3,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - const vector unsigned char mask4 = vec_nor((vector unsigned char)vec_cmple(data4,zero),(vector unsigned char)zero); /* bit mask... all 0 for data <= 0., all 1 else */ - - const vector float estimate1 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data1),mask1); - const vector float estimate2 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data2),mask2); - const vector float estimate3 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data3),mask3); - const vector float estimate4 = (vector float)vec_and((vector unsigned char)vec_rsqrte(data4),mask4); - - data1 = vec_nmsub( data1, vec_madd( estimate1, estimate1, zero ), one ); - data2 = vec_nmsub( data2, vec_madd( estimate2, estimate2, zero ), one ); - data3 = vec_nmsub( data3, vec_madd( estimate3, estimate3, zero ), one ); - data4 = vec_nmsub( data4, vec_madd( estimate4, estimate4, zero ), one ); - - data1 = vec_madd( data1, vec_madd( estimate1, oneHalf, zero ), estimate1 ); - data2 = vec_madd( data2, vec_madd( estimate2, oneHalf, zero ), estimate2 ); - data3 = vec_madd( data3, vec_madd( estimate3, oneHalf, zero ), estimate3 ); - data4 = vec_madd( data4, vec_madd( estimate4, oneHalf, zero ), estimate4 ); - - vec_st(data1, 0,dst); - vec_st(data2,16,dst); - vec_st(data3,32,dst); - vec_st(data4,48,dst); -#endif - } - return w+4; -} - -int simd_runtime_check() -{ - return 1; -} - - -#endif diff --git a/desiredata/src/m_simd_ve_gcc.h b/desiredata/src/m_simd_ve_gcc.h deleted file mode 100644 index f58ca42f..00000000 --- a/desiredata/src/m_simd_ve_gcc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SIMD functionality for Apple Velocity Engine (AltiVec) with GCC compiler; added by T.Grill */ -#ifndef __M_SIMD_VE_GCC_H -#define __M_SIMD_VE_GCC_H -#include "m_pd.h" - -/* SIMD functions for VE with GCC */ -t_int *sigwrap_perf_simd(t_int *w); -t_int *sigsqrt_perf_simd(t_int *w); -t_int *sigrsqrt_perf_simd(t_int *w); - -/* SIMD not implemented */ -#define env_tilde_accum_simd env_tilde_accum_8 -#define copyvec_simd_unalignedsrc copyvec_8 -/* #define sum_vecsimd sumvec_8 */ -#define line_tilde_slope_simd line_tilde_slope -#define peakvec_simd peakvec - -#endif /* __M_SIMD_VE_GCC_H */ diff --git a/desiredata/src/main.c b/desiredata/src/main.c deleted file mode 100644 index cf4a6593..00000000 --- a/desiredata/src/main.c +++ /dev/null @@ -1,17 +0,0 @@ -/* this file is separate because it is outside of libpd.so */ - -extern "C" int sys_main(int argc, char **argv); -#if _MSC_VER -#include <windows.h> -#include <stdio.h> -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - __try { - sys_main(__argc,__argv); - } __finally { - printf("caught an exception; stopping\n"); - } -} -#else /* not MSVC */ -int main(int argc, char **argv) {return sys_main(argc, argv);} -#endif - diff --git a/desiredata/src/makefile.in b/desiredata/src/makefile.in deleted file mode 100644 index 3ee8ce22..00000000 --- a/desiredata/src/makefile.in +++ /dev/null @@ -1,149 +0,0 @@ -cvs_root_dir = ../.. -pd_src = $(cvs_root_dir)/pd -INCLUDE = -I$(pd_src)/src -GFLAGS = -DINSTALL_PREFIX=\"$(prefix)\" - -EXT= @EXT@ -LIBSUFFIX = @LIBSUFFIX@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -mandir = @mandir@ -datarootdir = @datarootdir@ -datadir = @datadir@ - -# varibles to match packages/Makefile.buildlayout so that they can be easily -# overridden when building Pd-extended builds. <hans@at.or.at> -libpddir = $(libdir)/pd -pddocdir = $(libpddir)/doc -libpdbindir = $(libpddir)/bin - -MORECFLAGS = @MORECFLAGS@ -LDFLAGS = @LDFLAGS@ -LDSOFLAGS = @LDSOFLAGS@ -CPPFLAGS = -DDESIRE -DDONTUSESIMD -DPD @CPPFLAGS@ -CFLAGS = $(CPPFLAGS) @CFLAGS@ $(MORECFLAGS) -CFLAGS += -Wall -Wextra -Wno-unused-parameter -I. -CFLAGS += -DINSTALL_PREFIX=\"$(prefix)\" - -STRIP = @STRIP@ - -# --------------------- win32 --------------------------- -WATCHDOG = @WATCHDOG@ -WLIB = @WLIB@ -EXE = @EXE@ -# variables to build on mingw <colet.patrice@free.fr> -#----------------------------------------------------------- - -SRCXX = desire.c kernel.c builtins.c builtins_dsp.c s_path.c s_inter.c s_main.c \ - m_sched.c s_loader.c d_soundfile.c d_ugen.c s_audio.c s_midi.c \ - m_fifo.c m_simd.c d_mayer_fft.c d_fftroutine.c @AUDIOSRC@ @MIDISRC@ -OBJ = $(SRCXX:.c=.o) $(SRC:.c=.o) -SO = libpd$(LIBSUFFIX) - -# ------------------ targets ------------------------------------ - -.PHONY: bin externs all - -all:: bin externs - -bin:: pd$(EXE) $(WATCHDOG) pdsend$(EXE) pdreceive$(EXE) - -$(SRCXX:.c=.o): %.o: %.c config.log - $(CXX) $(CFLAGS) -xc++ -c -o $*.o $*.c - -$(SO): $(OBJ) config.log - $(CXX) $(LDSOFLAGS) $(LDFLAGS) $(DBG_CFLAGS) -I../src -o $(SO) $(OBJ) $(WLIB) - -pd$(EXE): $(OBJ) config.log $(SO) main.c - $(CXX) $(LDFLAGS) $(DBG_CFLAGS) $$PWD/$(SO) main.c -o pd$(EXE) - -pd-watchdog$(EXE): s_watchdog.c - $(CXX) $(CFLAGS) $(STRIPFLAG) -o pd-watchdog$(EXE) s_watchdog.c - -pd.com: main.c - $(CXX) $(LDFLAGS) $(DBG_CFLAGS) $(CFLAGS) -o pd.com main.c $(LIBS) -L../src -lpd - strip --strip-unneeded -R .note -R .comment pd.com - -# i should sort out the LDFLAGS thing so that pd,pdsend,pdreceive don't get linked to all libs that libpd.so is linked to. -# note that MinGW really wants LDFLAGS at the end of the line, not the middle, according to patco. - -pdsend$(EXE): u_pdsend.c config.log - $(CXX) $(CFLAGS) $(STRIPFLAG) -o pdsend$(EXE) u_pdsend.c $(LDFLAGS) - $(STRIP) pdsend$(EXE) - -pdreceive$(EXE): u_pdreceive.c config.log - $(CXX) $(CFLAGS) $(STRIPFLAG) -o pdreceive$(EXE) u_pdreceive.c $(LDFLAGS) - $(STRIP) pdreceive$(EXE) - -externs:: - cd ../extra; for ext in bonk~ choice expr~ fiddle~ loop~ lrshift~ pique sigmund~; do \ - cd $$ext; make @EXTERNTARGET@ || break; cd ..; done - -# note: will not install symlinks. you'd need another -o -type. -FINDFLAGS = -name .svn -prune -o -type f - -install:: all - install -d $(DESTDIR)$(bindir) - install -d $(DESTDIR)$(libpdbindir) - for file in defaults.ddrc pkgIndex.tcl poe.tcl bgerror.tcl; do \ - install $$file $(DESTDIR)$(libpdbindir)/$$file; done - install $(BINARYMODE) $(SO) $(DESTDIR)$(libdir)/$(SO) - $(CXX) $(LDFLAGS) $(DBG_CFLAGS) main.c -L $(DESTDIR)$(libdir) -lpd -o $(DESTDIR)$(bindir)/pd$(EXE) $(WSTRIP) - install -m755 desire.tk $(DESTDIR)$(bindir)/desire.tk - install -m755 desire $(DESTDIR)$(bindir)/desire - install -m755 pdsend$(EXE) $(DESTDIR)$(bindir)/pdsend$(EXE) - install -m755 pdreceive$(EXE) $(DESTDIR)$(bindir)/pdreceive$(EXE) - install -m755 $(WATCHDOG) $(DESTDIR)$(libpdbindir)/$(WATCHDOG) - find locale $(FINDFLAGS) -exec install -D -m644 '{}' $(DESTDIR)$(libpdbindir)/'{}' ';' - find icons $(FINDFLAGS) -exec install -D -m644 '{}' $(DESTDIR)$(libpddir)/'{}' ';' - find ../doc $(FINDFLAGS) -exec install -D -m644 '{}' $(DESTDIR)$(pddocdir)/'{}' ';' - find ../extra $(FINDFLAGS) -exec install -D -m644 '{}' $(DESTDIR)$(libpddir)/'{}' ';' - install -d $(DESTDIR)$(includedir) - for file in m_pd.h desire.h; do install -m644 $$file $(DESTDIR)$(includedir)/$$file; done - install -d $(DESTDIR)$(mandir)/man1 - for page in pd.1 pdsend.1 pdreceive.1; do \ - gzip < ../man/$$page > $(DESTDIR)$(mandir)/man1/$$page.gz; chmod 644 $(DESTDIR)$(mandir)/man1/$$page.gz; done - -local-clean:: - -rm -f *.o pd$(EXE) pdsend$(EXE) pdreceive$(EXE) $(WATCHDOG) m_stamp.c - -rm -f *~ - -(cd ../doc/6.externs; rm -f *.$(EXT)) - -rm -f makefile.deps - touch makefile.deps - #chmod 666 makefile.deps # what was this for?? - -extra-clean:: - -rm -f `find ../extra/ -name "*.pd_*"` - -rm -f tags - -clean:: extra-clean local-clean - -distclean:: clean - -rm -f config.cache config.log config.status makefile tags \ - autom4te.cache/output.* autom4te.cache/traces.* autom4te.cache/requests - -rmdir autom4te.cache - -rm -rf autom4te-*.cache - -tags:: $(SRC) $(GSRC); ctags *.[ch] - -depend:: makefile.deps - -makefile.deps: makefile - $(CXX) $(CPPFLAGS) -MM $(SRC) $(SRCXX) > makefile.deps - -uninstall:: - rm -f -r $(DESTDIR)$(libpddir) - rm -f $(DESTDIR)$(libdir)/libpd* - cd $(DESTDIR)$(bindir); rm pd$(EXE) pdsend$(EXE) pdreceive$(EXE) - cd $(DESTDIR)$(includedir); rm m_pd.h desire.h - cd $(DESTDIR)$(mandir)/man1; rm pd.1.gz pdsend.1.gz pdreceive.1.gz - -test:: all - cd ../extra/pureunity && make test - -include makefile.deps - -# echo $$LD_LIBRARY_PATH | sed 's/:/\n/g' | grep -q '^$(DESTDIR)$(libdir)$$' diff --git a/desiredata/src/notes.txt b/desiredata/src/notes.txt deleted file mode 100644 index 26393dfb..00000000 --- a/desiredata/src/notes.txt +++ /dev/null @@ -1,300 +0,0 @@ ----------------- dolist -------------------- -done: -plug-in support -atan2 inlets switched -queued graphics updates for tables, number boxes -cut/paste text (needs more testing) -add standard bindings (ctl-o, etc) to dialogs -separate audio on/off from nchans -setuid flag in configure script -settings saver (registry in Windows; .pdrc in linux; defaults system in OSX?) - audio API - MIDI -- fix to read MIDI on startup (rest works?) - path - startup flags - libs -better params: - extra flag for path - startup flags - startup libraries -printout to pd window -startup from GUI -%x to %lx in all "tags" to make 64-bit safe -portaudio_pd files into src -t_int to int in binbuf_addv -64-bit fix to externs makefiles -new filter objects: cpole~, fpole~, etc. -put in Wini's RME ALSA code; there are still bugs... -portaudio fixed for inchans != outchans, e.g., emi emagic (2/6) -sprout inlets/outlets on objects whose creation failed. -uploaded to CVS -bug fix: click on minaturized subpatch fails to "vis" it -bug fix: CK on Oct. 4 (crash changing font size) -sched_idle hook -fixed startup flags, path, etc. so that spaces, "," chars, etc., are allowed -configure script fixed to handle enable- and disable- correctly -fixed spaces in "startup" dialog - -doc: -document env~ second argument (and why is it no less than 1/10 of first???) -vibrato example - -problems: -'[' in numbox label breaks it (Yury Sept. 3) -soundfiles with 3-byte samples buzz for the first readsf buffer (bug/x.pd) -read xx.txt in "bad" gives warnings -writesf -- "open" without "0" misses closing the previous file. -Also writesf~ acts differently if DSP is off when "open" is sent? -qlist - 'next 1' seems not to work -Krzysztof's qlist_next reentrancy bug -don't draw in/outlets on gui objects in graph-on-parent -font size should depend on subpatch/abstraction -moving a bang toward top of window creates problem -check what happens when going back and forth between graph-on-parent -get rid of messages causing renaming; try to prevent patches closing themselves. -dac~/ adc~/ block~ incompatibility -scofo reports error on reading score1.txt -rfft~ loses nyquist bin -- see "to hell with it" comment in d_fft.c -open_via_path() followed by close() fails in windows? [can't reproduce] -loading e-mailed patches without removing headers crashes pd -pd $1 bug ($1 is saved as it was evaluated, not as '$1') -data copy/paste doesn't check templates aren't changed -figure out why Pd sometimes crashes when you close example after adding fields -check if _vsnprintf with zero argument in windows works any better... - -next release: -update portmusic to latest -IEM guis to use queued updates -pixel font sizes -pd to find running ones (pd -new to defeat) -"enter" into object box to create new one (also, changing borders? forking?) -tab to jump to a connected object (first one?) (shift-tab to back up?) -tables: - if there's just one array, don't do stringent hit check. - array click protection (Krzysztof's suggestion) - make graph labels persistent and add to dialog - object to get/set table size; random; quantile - flag to hide array names -queued graphics updates for IEMGUIs and scalars -document tabwrite~_start -think of a way to embed abstractions in a patch -make watchdog work for MACOSX -GOP bounding box object -IEMGUIs better default font size -search path to include both calling patch and abstraction, if different -abstraction reload shouldn't have to vis everyone -addcomma message to message -pasting should look at current mouse location -delete-in-rectangle message to Pds -put serial object in main dist (see rat@telecoma, Apr. 25; winfried May 22) -open/save panel to take messages to init directory, and to set extent list -flags to defeat pre-loading specified classes -expr to parse exponential notation - - -data: -arrays of non-existent templates crash -vget, vset traversal objects -cursor to show (x, y) location -better hit detection (getrect is too greedy; try tk's "current" tag for canvas) -click on points of plot -typing & dragging drawnumbers -fix templates to be loaded on demand and belong to a globally known patch -test and debug list elements of templates -sublists should display on parent if desired? -sublists seem not to handle canvas allocation right (get.pd->pointer.pd bug) -scalar hook to catch the mouse -protect against "plots" going away while you drag on them - -more features: - --Wno-unused to -Wno-unused-paramter and clean up unused automatic variables -security module system in 2.6 - see the kernel module replacing jackstart -signal inlets to sense signals; fix +~ etc, vcf~, biquad~, other filters -mess with RME ALSA some more; ALSA readn doesn't work yet; use mmap? -try to reduce startup time -investigate gcc 3.3 warnings; try to reinstate -fstrict-aliasing -message dialog not to disappear -why does changing the name of an explode in jupiter patch take so long? -close-subwindows menu item -show results of opening audio and MIDI on dialogs -windows escape from control-C -settable netsend and netreceive port numbers -new: abs~, nexttick~, extend threshold~ and snapshot~ (vthreshold~ etc) -incorporate pddp doc -try again to fix the font scene -look at prctl(2) for FP exception handling -??? have a way to disambiguate externs from different libs??? -netsend separate thread -netreceive (and netsend?) message to set port number -think about x and y scale preservation when changing between graph and object -show outlines of objects even when graph is "open" -graph_vis() to decorate graphs when they're toplevel (parent_glist == 0) -get graphs to expand to hold their contents -suita.chopin.edu.pl/~czaja/miXed/externs/xeq.html -- MIDI file reader -in glist_delete, consider why this can't be just "vis 0" -- why do we need it? -closebang -check that -blocksize really reflects in audiobuf calc for Hammerfall -makefile to have make install depend on make local. -Float method for random -figure out list, message objects -separate control over alsaindev and alsaoutdev -put in something for tilde order forcing -extensible "toolbar" so people can add external GUI objects -allow spaces in paths -variable send and receive -- check how max/MSP does it? -number boxes to darken for typing and/or received messages -dialog to change lib flag and path -pique~ and fiddle~ unification (notice pique filtering is different!) -new message box look -figure out what to do when "pd sym" conflicts with window title as in Pluton? - -MAX compatibilty: -trigger 1 (on Pd, outputs 0; on Max?) - -LATER -bonk~ file path handling -unify arrays and garrays -dialog to give values of $1, ... for the canvas -bang at end of line~, tabwrite~, etc. -recording to part of a table -printout to main window -should sys_bail kill all "threads" on the way out? -check a_valid usage -allow backslashes (or else really disallow them) -icon & desktop integration -vreadsf~ -benchmarking -flash menu when accelerator hits? -fix edit mode menu item -fancier text editing -tools (reassigns meaning of primary click) -get gui to notice early EOF -rewrite t_getbytes properly -obj_new should do a longjmp on out-of-memory - ---------------------- source notes -------------------------- - -0. structure definition roadmap. First, the containment tree of things -that can be sent messages ("pure data"). (note that t_object and t_text, -and t_graph and t_canvas, should be unified...) - ------------- BFFORE 0.35: --------- -m_pd.h t_pd anything with a class - t_gobj "graphic object" - t_text text object -g_canvas.h - t_glist list of graphic objects -g_canvas.c t_canvas Pd "document" - ------------- AFTER 0.35: --------- -m_pd.h t_pd anything with a class - t_gobj "graphic object" - t_text patchable object, AKA t_object -g_canvas.h t_glist list of graphic objects, AKA t_canvas - -... and other structures: -g_canvas.h t_selection -- linked list of gobjs - t_editor -- editor state, allocated for visible glists -m_imp.h t_methodentry -- method handler - t_widgetbehavior -- class-dependent editing behavior for gobjs - t_parentwidgetbehavior -- objects' behavior on parent window - t_class -- method definitions, instance size, flags, etc. - - -1. C coding style. The source should pass most "warnings" of C compilers -(-Wall on linux, for instance; see the makefile.) Some informalities -are intentional, for instance the loose use of function prototypes (see -below) and uncast conversions from longer to shorter numerical formats. -The code doesn't respect "const" yet. - -1.1. Prefixes in structure elements. The names of structure elements always -have a K&R-style prefix, as in ((t_atom)x)->a_type, where the "a_" prefix -indicates "atom." This is intended to enhance readability (although the -convention arose from a limitation of early C compilers.) Common prefixes are -"w_" (word), "a_" (atom), "s_" (symbol), "ob_" (object), "te_" (text object), -"g_" (graphical object), and "gl_" (glist, a list of graphical objects). Also, -global symbols sometimes get prefixes, as in "s_float" (the symbol whose string -is "float). Typedefs are prefixed by "t_". Most _private_ structures, i.e., -structures whose definitions appear in a ".c" file, are prefixed by "x_". - -1.2. Function arguments. Many functions take as their first -argument a pointer named "x", which is a pointer to a structure suggested -by the function prefix; e.g., canvas_dirty(x, n) where "x" points to a canvas -(t_canvas *x). - -1.3. Function Prototypes. Functions which are used in at least two different -files (besides where they originate) are prototyped in the appropriate include -file. Functions which are provided in one file and used in one other are -prototyped right where they are used. This is just to keep the size of the -".h" files down for readability's sake. - -1.4. Whacko private terminology. Some terms are lifted from other historically -relevant programs, notably "ugen" (which is just a tilde object; see d_ugen.c.) - -1.5. Spacing. Tabs are 8 spaces; indentation is 4 spaces. Indenting -curly brackets are by themselves on their own lines, as in: - - if (x) - { - x = 0; - } - -Lines should fit within 80 spaces. - -2. Max patch-level compatibility. "Import" and "Export" functions are -provided which aspire to strict compatibility with 0.26 patches (ISPW version), -but which don't get anywhere close to that yet. Where possible, features -appearing on the Mac will comeday also be provided; for instance, the connect -message on the Mac offers segmented patch cords; these will devolve into -straight lines in Pd. Many, many UI objects in Opcode Max will not appear in -Pd, at least at first. - -3. Compatibility with Max 0.26 "externs", i.e., source-level compatibility. Pd -objects follow the style of 0.26 objects as closely as possible, making -exceptions in cases where the 0.26 model is clearly deficient. These are: - -3.1. Anything involving the MacIntosh "Handle" data type is changed to use -char * or void * instead. - -3.2. Pd passes true single-precision floating-point arguments to methods; -Max uses double. -Typedefs are provided: - t_floatarg, t_intarg for arguments passed by the message system - t_float, t_int for the "word" union (in atoms, for example.) - -3.3. Badly-named entities got name changes: - - w_long --> w_int (in the "union word" structure) - -3.4. Many library functions are renamed and have different arguments; -I hope to provide an include file to alias them when compiling Max externs. - -4. Function name prefixes. -Many function names have prefixes which indicate what "package" they belong -to. The exceptions are: - typedmess, vmess, getfn, gensym (m_class.c) - getbytes, freebytes, resizebytes (m_memory.c) - post, error, bug (s_print.c) -which are all frequently called and which don't fit into simple categories. -Important packages are: -(pd-gui:) pdgui -- everything -(pd:) pd -- functions common to all "pd" objects - obj -- fuctions common to all "patchable" objects ala Max - sys -- "system" level functions - binbuf -- functions manipulating binbufs - class -- functions manipulating classes - (other) -- functions common to the named Pd class - -5. Source file prefixes. -PD: -s system interface -m message system -g graphics stuff -d DSP objects -x control objects -z other - -PD-GUI: -t TK front end - diff --git a/desiredata/src/pkgIndex.tcl b/desiredata/src/pkgIndex.tcl deleted file mode 100644 index 40115eba..00000000 --- a/desiredata/src/pkgIndex.tcl +++ /dev/null @@ -1,15 +0,0 @@ -# Tcl package index file, version 1.1 -# This file is generated by the "pkg_mkIndex" command -# and sourced either when an application starts up or -# by a "package unknown" script. It invokes the -# "package ifneeded" command to set up package-related -# information so that packages will be loaded automatically -# in response to "package require" commands. When this -# script is sourced, the variable $dir must contain the -# full path name of this file's directory. - -package ifneeded kb-mode 0.1 [list source [file join $dir kb-mode.tcl]] -package ifneeded poe 0.1 [list source [file join $dir poe.tcl]] -package ifneeded pre8.5 8.4 [list source [file join $dir pre8.5.tcl]] -package ifneeded bgerror 8.4 [list source [file join $dir bgerror.tcl]] -package ifneeded dzinc 0.1 [list source [file join $dir dzinc.tcl]] diff --git a/desiredata/src/plusminus b/desiredata/src/plusminus deleted file mode 100755 index 553f84fa..00000000 --- a/desiredata/src/plusminus +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env ruby -# plusminus, Copyright © 2004 by Mathieu Bouchard -# this program makes stats about a unified diff (diff -u) output. -# for example, run this command: cvs diff -u | ./plusminus -# NOTE: the -u option is required! (you can put it in ~/.cvsrc) - -puts "-"*64 - -$plustot=0 -$minustot=0 - -def show - printf "%20s %+5d %+5d (net %+5d)\n", $file, $plus, -$minus, $plus-$minus -end - -loop{ - line = gets - break if not line - if /^diff/.match line then - x = line.split(/\s+/) - $plustot+=$plus if $plus - $minustot+=$minus if $minus - show if $file - $file = x[-1] - $on=false - $plus=0 - $minus=0 - elsif /^\@\@/ =~ line then $on=true - elsif $on and /^\+/ =~ line then $plus+=1 - elsif $on and /^\-/ =~ line then $minus+=1 - end -} - -$plustot+=$plus if $plus -$minustot+=$minus if $minus -show if $file - -$file="total" -$plus=$plustot -$minus=$minustot -puts "-"*64 -show diff --git a/desiredata/src/poe.tcl b/desiredata/src/poe.tcl deleted file mode 100644 index 22c72d3f..00000000 --- a/desiredata/src/poe.tcl +++ /dev/null @@ -1,285 +0,0 @@ -# $Id: poe.tcl,v 1.1.2.2.2.27 2007-10-15 15:58:13 chunlee Exp $ -#----------------------------------------------------------------# -# POETCL -# -# Copyright (c) 2005,2006,2007,2008 by Mathieu Bouchard -# -# 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. -# -# See file ../COPYING.desire-client.txt for further informations on licensing terms. -# -# 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. -# -# Note that this is not under the same license as the rest of PureData. -# Even the DesireData server-side modifications stay on the same license -# as the rest of PureData. -# -#-----------------------------------------------------------------------------------# - -# (please distinguish between what this is and what dataflow is) -# note, the toplevel class is called "thing". - -package provide poe 0.1 - -set nextid 0 -set _(Class:_class) Class -set _(Class:_super) {Thing} -set have_expand [expr ![catch {set a {foo bar}; list {expand}$a}]] - -proc correct_splat {code} { - if {!$::have_expand} {return $code} - regsub {{*}} $code {{expand}} -} - -proc proc* {name args body} { - set argl {} - foreach arg $args {set arg [lindex $arg 0]; lappend argl "$arg=\$$arg"} - if {[regexp {_unknown$} $name]} { - proc $name $args "upvar 1 selector ___; puts \"\[VTgreen\]CALL TO PROC $name selector=\$___ [join $argl " "]\[VTgrey\]\"; $body" - } else { - if {![regexp "return" $body]} { - set body "time {$body}" - proc $name $args "puts \"\[VTgreen\]CALL TO PROC $name [join $argl " "], \[VTred\]\[lrange \[split \[$body\] \] 0 1\] \[VTgrey\]\"" - } { - proc $name $args "puts \"\[VTgreen\]CALL TO PROC $name [join $argl " "]\[VTgrey\]\"; $body" - } - } -} - -#proc Class_def {self selector args body} { -# global _; if {![info exists _($self:_class)]} {error "unknown class '$self'"} -# proc ${self}_$selector "self $args" "global _; [regsub -all @(\[\\w\\?\]+) $body _(\$self:\\1)]" -#} -#proc def {class selector args body} {$class def $selector $args $body} - -proc expand_macros {body} { - return [regsub -all @(\\\$?\[\\w\\?\]+) $body _(\$self:\\1)] -} - -proc def {self selector argnames body} { - global _ __trace __args - if {![info exists _($self:_class)]} {error "unknown class '$self'"} - set name ${self}_$selector - set argnames [concat [list self] $argnames] - if {([info exists __trace($self:$selector)] || [info exists __trace(*:$selector)] - || [info exists __trace($self:*)] || [info exists __trace(*:*)]) - && ![info exists __trace($self:!$selector)] - && ![info exists __trace(*:!$selector)] - } { - proc* $name $argnames "global _; [expand_macros $body]" - } { - proc $name $argnames "global _; [expand_macros $body]" - } - set __args($name) $argnames - #trace add execution ${self}_$selector enter dedebug -} - -proc class_new {self {super {Thing}}} { - global _ - set _($self:_class) Class - set _($self:_super) $super - set _($self:subclasses) {} - foreach sup $super {lappend _($sup:subclasses) $self} - proc ${self}_new {args} "global _ - set self \[format o%07x \$::nextid\] - incr ::nextid - set _(\$self:_class) $self - setup_dispatcher \$self - eval [concat \[list \$self init\] \$args] - return \$self - " - proc ${self}_new_as {self args} "global _ - if {\[info exists _(\$self:_class)\]} {error \"object '\\$self' already exists\" } - set _(\$self:_class) $self - setup_dispatcher \$self - eval [concat \[list \$self init\] \$args] - return \$self - " - setup_dispatcher $self -} - -# TODO: remove duplicates in lookup -proc lookup_method {class selector methodsv ancestorsv} { - global _ - upvar $methodsv methods - upvar $ancestorsv ancestors - set name ${class}_$selector - if {[llength [info procs $name]]} {lappend methods $name} - lappend ancestors $class - foreach super $_($class:_super) {lookup_method $super $selector methods ancestors} -} - -proc cache_method {class selector} { - global _ __ - set methods {}; set ancestors {} - lookup_method $class $selector methods ancestors - if {![llength $methods]} {set methods [cache_method $class unknown]} - set __($class:$selector) $methods - return $methods -} - -if {$have_expand} { - set dispatch { - set i 0; set class $::_($self:_class) - if {[catch {set methods $::__($class:$selector)}]} {set methods [cache_method $class $selector]} - [lindex $methods 0] $self {expand}$args - } -} else { - set dispatch { - set i 0; set class $::_($self:_class) - if {[catch {set methods $::__($class:$selector)}]} {set methods [cache_method $class $selector]} - [lindex $methods 0] $self {*}$args - } -} -proc setup_dispatcher {self} { - if {[llength [info commands $self]]} {rename $self old_$self} - proc $self {selector args} [regsub -all {\$self} $::dispatch $self] -} - -set super { - upvar 1 self self - upvar 2 methods methods i oi - set i [expr {1+$oi}] - if {[llength $methods] < $i} {error "no more supermethods"} -} -if {$have_expand} { - append super {[lindex $methods $i] $self {expand}$args} -} else { - append super {eval [concat [list [lindex $methods $i] $self] $args]} -} -proc super {args} $super - -class_new Thing {} -#set _(Thing:_super) {} -def Thing init {} {} -def Thing == {other} {return [expr ![string compare $self $other]]} - -# virtual destructor -def Thing delete {} { - foreach elem [array names _ $self:*] {array unset _ $elem} - rename $self "" -} - -def Thing vars {} { - set n [string length $self:] - set ks [list] - foreach k [array names _] { - if {0==[string compare -length $n $self: $k]} {lappend ks [string range $k $n end]} - } - return $ks -} - -def Thing inspect {} { - set t [list "#<$self: "] - foreach k [lsort [$self vars]] {lappend t "$k=[list $@$k] "} - lappend t ">" - return [join $t ""] -} - -def Thing class {} {return $@_class} - -def Thing unknown {args} { - upvar 1 selector selector class class - error "no such method '$selector' for object '$self'\nwith ancestors {[Class_ancestors $class]}" -} - -class_new Class - -# those return only the direct neighbours in the hierarchy -def Class superclasses {} {return $@_super} -def Class subclasses {} {return $@subclasses} - -# those look recursively. -def Class ancestors {} { - #if {[info exists @ancestors]} {} - set r [list $self] - foreach super $@_super {eval [concat [list lappend r] [$super ancestors]]} - return $r -} -def Class <= {class} {return [expr [lsearch [$self ancestors] $class]>=0]} - -# note: [luniq] is actually defined in desire.tk -def Class methods {} { - set methods {} - set anc [$self ancestors] - foreach class $anc { - foreach name [info procs ${class}_*] { - lappend methods [join [lrange [split $name _] 1 end] _] - } - } - return [luniq [lsort $methods]] -} - -# those are static methods, and poe.tcl doesn't distinguish them yet. -def Class new { args} {eval [concat [list ${self}_new ] $args]} -def Class new_as {id args} {eval [concat [list ${self}_new_as $id] $args]} - -#-----------------------------------------------------------------------------------# - -# this makes me think of Maximus-CBCS... -proc VTgrey {} {return "\x1b\[0m"} -proc VTred {} {return "\x1b\[0;1;31m"} -proc VTgreen {} {return "\x1b\[0;1;32m"} -proc VTyellow {} {return "\x1b\[0;1;33m"} -proc VTblue {} {return "\x1b\[0;1;34m"} -proc VTmagenta {} {return "\x1b\[0;1;35m"} -proc VTcyan {} {return "\x1b\[0;1;36m"} -proc VTwhite {} {return "\x1b\[0;1;37m"} - -proc error_text {} { - set e $::errorInfo - regsub -all " invoked from within\n" $e "" e - regsub -all "\n \\(" $e " (" e - regsub -all {\n[^\n]*procedure \"(::unknown|super)\"[^\n]*\n} $e "\n" e - regsub -all {\n\"\[lindex \$methods 0\][^\n]*\n} $e "\n" e - regsub -all {\s*while executing\s*\n} $e "\n" e - #regsub {\n$} $e "" e - return $e -} -set suicidal 0 -proc error_dump {} { - puts "[VTred]Exception:[VTgrey] [error_text]" - if {$::suicidal} {exit 1} -} - -proc tracedef {class method {when enter}} { - global __trace - set __trace($class:$method) $when -} - -proc yell {var key args} { - global $key - puts "[VTyellow]HEY! at [info level -1] set $key [list $::_($key)][VTgrey]" -} - -proc object_table {} { - set n 0 - puts "poe.tcl object_table: {" - foreach o [lsort [array names ::_ *:_class]] { - set oo [lindex [split $o :] 0] - set class $::_($o) - incr by_class($class) - puts " $oo is a $class" - incr n - } - puts "} ($n objects)" - set n 0 - puts "poe.tcl class_stats: {" - foreach o [array names by_class] { - puts " class $o has $by_class($o) objects" - incr n - } - puts "} ($n classes)" -} - -proc object_exists {self} {info exists ::_($self:_class)} diff --git a/desiredata/src/profile_dd.tcl b/desiredata/src/profile_dd.tcl deleted file mode 100644 index c5f22827..00000000 --- a/desiredata/src/profile_dd.tcl +++ /dev/null @@ -1,19 +0,0 @@ - -if 1 { - puts "profiler version [package require profiler]" - profiler::init - # try just: prof - # or try: prof calls - proc prof {{arg totalRuntime}} { - set dump [profiler::dump] - #foreach {a b} $dump {foreach {c d} $b {set prof($a:$c) $d}} - set top [profiler::sortFunctions $arg] - foreach entry $top { - mset {k v} $entry - if {!$v} {continue} - puts [format "%8d %s" $v $k] - } - } -} else { - load matjuprofiler/matjuprofiler.so -} diff --git a/desiredata/src/rules.txt b/desiredata/src/rules.txt deleted file mode 100644 index ec6c56b3..00000000 --- a/desiredata/src/rules.txt +++ /dev/null @@ -1,42 +0,0 @@ -Those rules are in no particular order. -Written by matju, on 2007.07.11 - ... - -#000: Tk-specific Tcl code goes in *.tk files; Tk-independent Tcl code is allowed to go in *.tcl files. - Exceptions: debug.tcl ... - -#001: Long source files are usually better than short files because they are easier to search in, with most editors. - -#002: It's better to make classes/procs/defs smaller but not to the extent that there are too many of them. - -#003: Accessing an object's privates directly, is likely to cause trouble in the future. All @variables are private, but - methods may also be marked as private or protected, by a visible comment where the definition is. (C++ variables are - not necessarily like that, mostly because of compatibility with classic pd) - -#004: Indentation is whatever you like as long as it's locally consistent. Tab stops (of the tab key) are at multiples of 8, - but indentation could be 2, 4, 8. (It's a bad idea to use less than 2 or more than 8). Open-braces don't deserve their - own line, but close-braces do, at least because of how the diff program works. - -#005: Screen width is assumed to be about 125 characters, not 80. This is especially useful for cutting down the need - to wrap lines. Newlines that have to do with linewrap get confused with meaningful newlines. Blank lines should be - used sparsely: the more there are blank lines, the less meaningful they are. If you want blank lines everywhere, - change the spacing of your font. - -#006: Short pieces of code that are quite repetitive but not completely, should be put on one line each and organised into - alternating columns of recurrent and non-recurrent material. This highlights patterns in code. e.g.: - for (int i=0; i<ninlets ; i++) x->inlets [i]->name = gensprintf( "inlet #%d",i); - for (int i=0; i<noutlets; i++) x->outlets[i]->name = gensprintf("outlet #%d",i); - -#007(Tcl): an attribute is a reader method named like "some_noun", which has no args and returns a value and/or a writer - method named like "some_noun=", which takes one arg (or more?) and returns no value. Together they are seen as - manipulating a variable. If the variable directly exists in the object, it should be called "@some_noun". The "=" - suffix should be only used for that purpose. (we should think about whether to accept multiple args, because other - languages with a similar concept only allow one arg in the writer) - -#008(Tcl): Nouns like "visibility" that are simpler as adjectives and whose main purpose is to return a yes/no value, can - be named like "visible?" and are declined in the same way, e.g. "visible?=" and "@visible?". The "?" suffix should be - only used for that purpose. - -#009(Tcl): use :: instead of proc global. - -#010: make variables as local as it makes sense: don't make them global if they'd fit well in an object; don't put them in - an object if they belong inside of a def or proc (fully local). diff --git a/desiredata/src/s_audio.c b/desiredata/src/s_audio.c deleted file mode 100644 index ffc2f9f9..00000000 --- a/desiredata/src/s_audio.c +++ /dev/null @@ -1,586 +0,0 @@ -/* Copyright (c) 2003, Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* machine-independent (well, mostly!) audio layer. Stores and recalls - audio settings from argparse routine and from dialog window. -*/ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include "m_simd.h" -#include <stdio.h> -#ifdef UNISTD -#include <unistd.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sstream> -#define max std::max /* resolve "ambiguous" shit. */ -#define SYS_DEFAULTCH 2 -#define SYS_MAXCH 100 -typedef long t_pa_sample; -#define SYS_SAMPLEWIDTH sizeof(t_pa_sample) -#define SYS_BYTESPERCHAN (sys_dacblocksize * SYS_SAMPLEWIDTH) -#define SYS_XFERSAMPS (SYS_DEFAULTCH*sys_dacblocksize) -#define SYS_XFERSIZE (SYS_SAMPLEWIDTH * SYS_XFERSAMPS) -#define MAXNDEV 100 -#define DEVDESCSIZE 80 -#define INTARG(i) atom_getintarg(i,argc,argv) - -extern t_audioapi pa_api, jack_api, oss_api, alsa_api, sgi_api, mmio_api, asio_api; - -t_sample *sys_soundin; -t_sample *sys_soundout; -float sys_dacsr; - -using namespace std; - -static t_audioapi *sys_audio() { -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) return &pa_api; -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) return &jack_api; -#endif -#ifdef USEAPI_OSS - if (sys_audioapi == API_OSS) return &oss_api; -#endif -#ifdef USEAPI_ALSA - if (sys_audioapi == API_ALSA) return &alsa_api; -#endif -#ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) return &mmio_api; -#endif -#ifdef USEAPI_ASIO - if (sys_audioapi == API_ASIO) return &asio_api; -#endif - post("sys_close_audio: unknown API %d", sys_audioapi); - sys_inchannels = sys_outchannels = 0; - sched_set_using_dacs(0); /* tb: dsp is switched off */ - return 0; -} - -static void audio_getdevs(char *idevlist, int *nidev, char *odevlist, int *nodev, int *canmulti, int maxndev, int devdescsize); - -/* these are set in this file when opening audio, but then may be reduced, - even to zero, in the system dependent open_audio routines. */ -int sys_inchannels; -int sys_outchannels; -int sys_advance_samples; /* scheduler advance in samples */ -int sys_blocksize = 0; /* audio I/O block size in sample frames */ -#ifndef API_DEFAULT -#define API_DEFAULT 0 -#endif -int sys_audioapi = API_DEFAULT; -int sys_dacblocksize; -int sys_schedblocksize; -int sys_meters; /* true if we're metering */ -static float sys_inmax; /* max input amplitude */ -static float sys_outmax; /* max output amplitude */ -int sys_schedadvance; /* scheduler advance in microseconds */ - -/* the "state" is normally one if we're open and zero otherwise; but if the state is one, - we still haven't necessarily opened the audio hardware; see audio_isopen() below. */ -static int audio_state; - -/* last requested parameters */ -static t_audiodevs audi; -static t_audiodevs audo; -static int audio_rate; -static int audio_dacblocksize; -static int audio_advance; -static int audio_scheduler; - -extern int sys_callbackscheduler; - -float peakvec(t_float* vec, t_int n, t_float cur_max); -static float (*peak_fp)(t_float*, t_int, t_float) = peakvec; - -static int audio_isopen() {return audio_state && ((audi.ndev > 0 && audi.chdev[0] > 0) || (audo.ndev > 0 && audo.chdev[0] > 0));} - -extern "C" void sys_get_audio_params(t_audiodevs *ai, t_audiodevs *ao, int *prate, int *pdacblocksize, int *padvance, int *pscheduler) { - ai->ndev=audi.ndev; for (int i=0; i< MAXAUDIOINDEV; i++) {ai->dev[i]=audi.dev[i]; ai->chdev[i]=audi.chdev[i];} - ao->ndev=audo.ndev; for (int i=0; i<MAXAUDIOOUTDEV; i++) {ao->dev[i]=audo.dev[i]; ao->chdev[i]=audo.chdev[i];} - *prate = audio_rate; - *pdacblocksize = audio_dacblocksize; - *padvance = audio_advance; - *pscheduler = audio_scheduler; -} - -void sys_save_audio_params( -int nidev, int *idev, int *ichdev, -int nodev, int *odev, int *ochdev, int rate, int dacblocksize, int advance, int scheduler) { - audi.ndev = nidev; - audo.ndev = nodev; - for (int i=0; i<MAXAUDIOINDEV; i++) {audi.dev[i]=idev[i]; audi.chdev[i]=ichdev[i];} - for (int i=0; i<MAXAUDIOOUTDEV; i++) {audo.dev[i]=odev[i]; audo.chdev[i]=ochdev[i];} - audio_rate = rate; - audio_dacblocksize = dacblocksize; - audio_advance = advance; - audio_scheduler = scheduler; -} - -extern "C" void sys_open_audio2(t_audiodevs *ai, t_audiodevs *ao, int rate, int dacblocksize, int advance, int scheduler) { - sys_open_audio(ai->ndev,ai->dev,ai->ndev,ai->chdev,ao->ndev,ao->dev,ao->ndev,ao->chdev,rate,dacblocksize,advance,scheduler,1); -} - -/* init routines for any API which needs to set stuff up before any other API gets used. This is only true of OSS so far. */ -#ifdef USEAPI_OSS -void oss_init(); -#endif - -static void audio_init() { - static int initted = 0; - if (initted) return; - initted = 1; -#ifdef USEAPI_OSS - oss_init(); -#endif -} - -/* set channels and sample rate. */ -void sys_setchsr(int chin, int chout, int sr, int dacblocksize) { - int inbytes = (chin ? chin : 2) * (sys_dacblocksize*sizeof(float)); - int outbytes = (chout ? chout : 2) * (sys_dacblocksize*sizeof(float)); - if (dacblocksize != (1<<ilog2(dacblocksize))) { - dacblocksize = 1<<ilog2(dacblocksize); - post("warning: adjusting dac~blocksize to power of 2: %d", dacblocksize); - } - sys_dacblocksize = dacblocksize; - sys_schedblocksize = dacblocksize; - sys_inchannels = chin; - sys_outchannels = chout; - sys_dacsr = double(sr); - sys_advance_samples = max(int(sys_schedadvance*sys_dacsr/1000000.),sys_dacblocksize); - if (sys_soundin) freealignedbytes(sys_soundin,inbytes); - sys_soundin = (t_float *)getalignedbytes(inbytes); - memset(sys_soundin, 0, inbytes); - if (sys_soundout) freealignedbytes(sys_soundout,outbytes); - sys_soundout = (t_float *)getalignedbytes(outbytes); - memset(sys_soundout, 0, outbytes); - /* tb: modification for simd-optimized peak finding */ - if (SIMD_CHKCNT(sys_inchannels * sys_dacblocksize) && - SIMD_CHKCNT(sys_outchannels * sys_dacblocksize)) - peak_fp = peakvec_simd; - else peak_fp = peakvec; - if (sys_verbose) post("input channels = %d, output channels = %d", sys_inchannels, sys_outchannels); - canvas_resume_dsp(canvas_suspend_dsp()); -} - -/* ----------------------- public routines ----------------------- */ - -/* open audio devices (after cleaning up the specified device and channel vectors). The audio devices are "zero based" - (i.e. "0" means the first one.) We also save the cleaned-up device specification so that we - can later re-open audio and/or show the settings on a dialog window. */ -void sys_open_audio( - int nidev, int *idev, int nichdev, int *ichdev, - int nodev, int *odev, int nochdev, int *ochdev, int rate, int dacblocksize, int advance, int schedmode, int enable) { - int defaultchannels = SYS_DEFAULTCH; - int realich[MAXAUDIOINDEV]; char idevlist[MAXNDEV*DEVDESCSIZE]; - int realoch[MAXAUDIOOUTDEV]; char odevlist[MAXNDEV*DEVDESCSIZE]; - int indevs = 0, outdevs = 0, canmulti = 0; - audio_getdevs(idevlist, &indevs, odevlist, &outdevs, &canmulti, MAXNDEV, DEVDESCSIZE); - if (sys_externalschedlib) return; - if (sys_inchannels || sys_outchannels) sys_close_audio(); - if (rate < 1) rate = DEFAULTSRATE; - if (dacblocksize < 1) dacblocksize = DEFDACBLKSIZE; - if (advance <= 0) advance = DEFAULTADVANCE; - audio_init(); - /* Since the channel vector might be longer than the audio device vector, or vice versa, we fill the shorter one - in to match the longer one. Also, if both are empty, we fill in one device (the default) and two channels. */ - if (nidev == -1) { /* no input audio devices specified */ - if (nichdev == -1) { - if (indevs >= 1) {nidev=nichdev=1; ichdev[0]=defaultchannels; idev[0]=DEFAULTAUDIODEV;} else nidev = nichdev=0; - } else for (int i=0; i<MAXAUDIOINDEV; i++) idev[i] = i; - } else { - if (nichdev == -1) {nichdev = nidev; for (int i=0; i<nidev; i++) ichdev[i] = defaultchannels; - } else if (nichdev > nidev) {for (int i=nidev; i<nichdev; i++) if (i==0) idev[i]=DEFAULTAUDIODEV; else idev[i]=idev[i-1]+1; - } else if (nichdev < nidev) {for (int i=nichdev; i<nidev; i++) if (i==0) ichdev[i]=defaultchannels; else ichdev[i]=ichdev[i-1];} - } - nidev = nichdev; - if (nodev == -1) { /* not set */ - if (nochdev == -1) { - if (outdevs >= 1) {nodev=nochdev=1; ochdev[0]=defaultchannels; odev[0]=DEFAULTAUDIODEV;} else nodev = nochdev=0; - } else for (int i=0; i<MAXAUDIOOUTDEV; i++) odev[i] = i; - } else { - if (nochdev == -1) {nochdev = nodev; for (int i=0; i<nodev; i++) ochdev[i] = defaultchannels; - } else if (nochdev > nodev) {for (int i=nodev; i<nochdev; i++) if (i==0) odev[0]=DEFAULTAUDIODEV; else odev[i]=odev[i-1]+1; - } else if (nochdev < nodev) {for (int i=nochdev; i<nodev; i++) if (i==0) ochdev[0]=defaultchannels; else ochdev[i]=ochdev[i-1];} - } - nodev = nochdev; - /* count total number of input and output channels */ - int inchans=0, outchans=0; - for (int i=0; i<nidev; i++) inchans += (realich[i] = (ichdev[i] > 0 ? ichdev[i] : 0)); - for (int i=0; i<nodev; i++) outchans += (realoch[i] = (ochdev[i] > 0 ? ochdev[i] : 0)); - /* if no input or output devices seem to have been specified, this really means just disable audio, which we now do. */ - if (!inchans && !outchans) enable = 0; - sys_schedadvance = advance * 1000; - sys_setchsr(inchans, outchans, rate, dacblocksize); - sys_log_error(ERR_NOTHING); - if (enable) { - /* for alsa, only one device is supported; it may be open for both input and output. */ -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - pa_open_audio(inchans, outchans, rate, advance, (nodev>0?idev[0]:0), (nodev>0?odev[0]:0), schedmode); - else -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) - jack_open_audio((nidev>0?realich[0]:0), (nodev>0?realoch[0]:0), rate, schedmode); - else -#endif - if (sys_audioapi == API_OSS || sys_audioapi == API_ALSA || sys_audioapi == API_MMIO) - sys_audio()->open_audio(nidev, idev, nichdev, realich, nodev, odev, nochdev, realoch, rate, -42); - else if (sys_audioapi == API_ASIO) - sys_audio()->open_audio(nidev, idev, nichdev, ichdev, nodev, odev, nochdev, ochdev, rate, schedmode); - else post("unknown audio API specified"); - } - sys_save_audio_params(nidev, idev, ichdev, nodev, odev, ochdev, int(sys_dacsr), sys_dacblocksize, advance, schedmode); - if (sys_inchannels == 0 && sys_outchannels == 0) enable = 0; - audio_state = enable; - sys_vgui("set pd_whichapi %d\n", audio_isopen() ? sys_audioapi : 0); - sched_set_using_dacs(enable); - sys_update_sleepgrain(); - if (enable) { - t_atom argv[1]; - t_symbol *selector = gensym("audio_started"); - t_symbol *pd = gensym("pd"); - SETFLOAT(argv, 1.); - typedmess(pd->s_thing, selector, 1, argv); - } -} - -void sys_close_audio() { - /* jsarlo { (*/ - if (sys_externalschedlib) return; - /* } jsarlo */ - if (!audio_isopen()) return; - if (sys_audio()) sys_audio()->close_audio(); - else post("sys_close_audio: unknown API %d", sys_audioapi); - sys_inchannels = sys_outchannels = 0; - sched_set_using_dacs(0); /* tb: dsp is switched off */ -} - -/* open audio using whatever parameters were last used */ -void sys_reopen_audio() { - t_audiodevs ai,ao; - int rate, dacblocksize, advance, scheduler; - sys_close_audio(); - sys_get_audio_params(&ai,&ao,&rate,&dacblocksize,&advance,&scheduler); - sys_open_audio2( &ai,&ao, rate, dacblocksize, advance, scheduler); -} - -/* tb: default value of peak_fp {*/ -float peakvec(t_float* vec, t_int n, t_float cur_max) { - for (int i=0; i<n; i++) { - float f = *vec++; - if (+f > cur_max) cur_max = +f; - else if (-f > cur_max) cur_max = -f; - } - return cur_max; -} -/* } */ - -void sys_peakmeters() { - if (sys_inchannels) sys_inmax = peak_fp(sys_soundin, sys_inchannels * sys_dacblocksize, sys_inmax); - if (sys_outchannels) sys_outmax = peak_fp(sys_soundout,sys_outchannels * sys_dacblocksize, sys_outmax); -} - -int sys_send_dacs() { - if (sys_meters) sys_peakmeters(); - if (sys_audio()) return sys_audio()->send_dacs(); - post("unknown API"); - return 0; -} - -float sys_getsr() {return sys_dacsr;} -int sys_get_outchannels() {return sys_outchannels;} -int sys_get_inchannels() {return sys_inchannels;} - -void sys_getmeters(float *inmax, float *outmax) { - if (inmax) { - sys_meters = 1; - *inmax = sys_inmax; - *outmax = sys_outmax; - } else sys_meters = 0; - sys_inmax = sys_outmax = 0; -} - -static void audio_getdevs(char *idevlist, int *nidev, char *odevlist, int *nodev, int *canmulti, int maxndev, int devdescsize) { - audio_init(); - if (sys_audio()) sys_audio()->getdevs(idevlist, nidev, odevlist, nodev, canmulti, maxndev, devdescsize); - else {*nidev = *nodev = 0;} -} - -void sys_listdevs() { -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) return jack_listdevs(); -#endif - char idevlist[MAXNDEV*DEVDESCSIZE], odevlist[MAXNDEV*DEVDESCSIZE]; - int nidev = 0, nodev = 0, canmulti = 0; - audio_getdevs(idevlist, &nidev, odevlist, &nodev, &canmulti, MAXNDEV, DEVDESCSIZE); - /* To agree with command line flags, normally start at 1; but microsoft "MMIO" device list starts at 0 (the "mapper"). */ - /* (see also sys_mmio variable in s_main.c) */ - if (!nidev) post("no audio input devices found"); else post("audio input devices:"); - for (int i=0; i<nidev; i++) post("%d. %s", i + (sys_audioapi != API_MMIO), idevlist + i*DEVDESCSIZE); - if (!nodev) post("no audio output devices found"); else post("audio output devices:"); - for (int i=0; i<nodev; i++) post("%d. %s", i + (sys_audioapi != API_MMIO), odevlist + i*DEVDESCSIZE); - post("API number %d", sys_audioapi); - sys_listmididevs(); -} - -/* start an audio settings dialog window */ -void glob_audio_properties(t_pd *, t_floatarg flongform) { - /* these are the devices you're using: */ - t_audiodevs ai,ao; - int rate, dacblocksize, advance, scheduler; - /* these are all the devices on your system: */ - char idevlist[MAXNDEV*DEVDESCSIZE], odevlist[MAXNDEV*DEVDESCSIZE]; - int nidev = 0, nodev = 0, canmulti = 0; - audio_getdevs(idevlist, &nidev, odevlist, &nodev, &canmulti, MAXNDEV, DEVDESCSIZE); - ostringstream idevliststring; for (int i=0; i<nidev; i++) idevliststring << " {" << (idevlist + i*DEVDESCSIZE) << "}"; - ostringstream odevliststring; for (int i=0; i<nodev; i++) odevliststring << " {" << (odevlist + i*DEVDESCSIZE) << "}"; - sys_get_audio_params(&ai,&ao,&rate,&dacblocksize,&advance,&scheduler); - if (ai.ndev > 1 || ao.ndev > 1) flongform = 1; - ostringstream idevs; for (int i=0; i<ai.ndev; i++) idevs << " " << ai. dev[i]; - ostringstream odevs; for (int i=0; i<ao.ndev; i++) odevs << " " << ao. dev[i]; - ostringstream ichans; for (int i=0; i<ai.ndev; i++) ichans << " " << ai.chdev[i]; - ostringstream ochans; for (int i=0; i<ao.ndev; i++) ochans << " " << ao.chdev[i]; - sys_vgui("pdtk_audio_dialog {%s} {%s} {%s} {%s} {%s} {%s} %d %d %d %d %d\n", - idevliststring.str().data()+1, idevs.str().data()+1, ichans.str().data()+1, - odevliststring.str().data()+1, odevs.str().data()+1, ochans.str().data()+1, - rate, dacblocksize, advance, canmulti, flongform!=0); -} - -/* new values from dialog window */ -void glob_audio_dialog(t_pd *, t_symbol *s, int argc, t_atom *argv) { - int nidev=0, nodev=0; - t_audiodevs ai,ao; - for (int i=0; i<4; i++) { - ai.dev [i] = INTARG(i ); - ai.chdev[i] = INTARG(i+4 ); - ao.dev [i] = INTARG(i+8 ); - ao.chdev[i] = INTARG(i+12); - } - for (int i=0; i<4; i++) if (ai.chdev[i]) {ai.dev[nidev] = ai.dev[i]; ai.chdev[nidev] = ai.chdev[i]; nidev++;} - for (int i=0; i<4; i++) if (ao.chdev[i]) {ao.dev[nodev] = ao.dev[i]; ao.chdev[nodev] = ao.chdev[i]; nodev++;} - sys_close_audio(); - sys_open_audio(nidev, ai.dev, nidev, ai.chdev, - nodev, ao.dev, nodev, ao.chdev, INTARG(16),INTARG(17),INTARG(18),INTARG(19), 1); -} - -void sys_setblocksize(int n) { - if (n < 1) n = 1; - if (n != (1 << ilog2(n))) post("warning: adjusting blocksize to power of 2: %d", (n = (1 << ilog2(n)))); - sys_blocksize = n; -} - -void sys_set_audio_api(int which) { - sys_audioapi = which; - if (sys_verbose) post("sys_audioapi %d", sys_audioapi); -} - -void glob_audio_setapi(t_pd *, t_floatarg f) { - int newapi = int(f); - if (newapi != sys_audioapi) { - if (newapi != sys_audioapi) { - sys_close_audio(); - sys_audioapi = newapi; - /* bash device params back to default */ - audi.ndev = audo.ndev = 1; - audi.dev[0] = audo.dev[0] = DEFAULTAUDIODEV; - audi.chdev[0] = audo.chdev[0] = SYS_DEFAULTCH; - } - sched_set_using_dacs(0); -/* glob_audio_properties(0, 0); */ - } -} - -/* start or stop the audio hardware */ -void sys_set_audio_state(int onoff) { - if (onoff) {if (!audio_isopen()) sys_reopen_audio();} - else {if ( audio_isopen()) sys_close_audio();} - sched_set_using_dacs(onoff); - sys_setscheduler(sys_getscheduler()); /* tb: reset scheduler */ - audio_state = onoff; -} - -void sys_get_audio_apis(char *buf) { - int n = 0; - strcpy(buf, "{ "); -#ifdef USEAPI_OSS - sprintf(buf + strlen(buf), "{OSS %d} ", API_OSS); n++; -#endif -#ifdef USEAPI_ASIO - sprintf(buf + strlen(buf), "{ASIO %d} ", API_ASIO); n++; -#endif -#ifdef USEAPI_MMIO - sprintf(buf + strlen(buf), "{\"standard (MMIO)\" %d} ", API_MMIO); n++; -#endif -#ifdef USEAPI_ALSA - sprintf(buf + strlen(buf), "{ALSA %d} ", API_ALSA); n++; -#endif -#ifdef USEAPI_PORTAUDIO -#ifdef __APPLE__ - sprintf(buf + strlen(buf), "{\"standard (portaudio)\" %d} ", API_PORTAUDIO); n++; -#else - sprintf(buf + strlen(buf), "{portaudio %d} ", API_PORTAUDIO); n++; -#endif -#endif -#ifdef USEAPI_JACK - sprintf(buf + strlen(buf), "{jack %d} ", API_JACK); n++; -#endif - strcat(buf, "}"); -} - -#ifdef USEAPI_ALSA -void alsa_putzeros(int iodev, int n); -void alsa_getzeros(int iodev, int n); -void alsa_printstate(); -#endif - -/* debugging */ -void glob_foo(void *, t_symbol *s, int argc, t_atom *argv) { - t_symbol *arg = atom_getsymbolarg(0, argc, argv); - if (arg == gensym("restart")) sys_reopen_audio(); -#ifdef USEAPI_ALSA - /* what's the matter here? what should be the value of iodev??? */ - else if (arg == gensym("alsawrite")) alsa_putzeros(0, INTARG(1)); - else if (arg == gensym("alsaread")) alsa_getzeros(0, INTARG(1)); - else if (arg == gensym("print")) alsa_printstate(); -#endif -} - -/* tb: message-based audio configuration */ -void glob_audio_api(t_pd *, t_float f) { - int newapi = (int)f; - sys_close_audio(); - sys_audioapi = newapi; -} -void glob_audio_samplerate( t_pd *, t_float f) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; if (f == sys_getsr()) return; - sys_get_audio_params(&ai,&ao,&rate, &dacblocksize, &advance, &scheduler); - sys_close_audio(); sys_open_audio2(&ai,&ao,(int)f, dacblocksize, advance, scheduler); -} -void glob_audio_delay( t_pd *, t_float f) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; if (int(f) == audio_advance) return; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - sys_close_audio(); sys_open_audio2(&ai,&ao,rate,dacblocksize,int(f),scheduler); -} -void glob_audio_dacblocksize(t_pd *, t_float f) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; if (int(f) == audio_dacblocksize) return; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - sys_close_audio(); sys_open_audio2(&ai,&ao,rate,(int)f,advance,scheduler); -} -void glob_audio_scheduler(t_pd *, t_float f) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; if (int(f) == sys_callbackscheduler) return; - scheduler = f!=0; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - sys_close_audio(); - sys_open_audio2(&ai,&ao, rate, dacblocksize, advance, scheduler); - if (scheduler != sys_callbackscheduler) { - if (scheduler == 1) post("switched to callback-based scheduler"); - else post("switched to traditional scheduler"); - } else post("couldn't change scheduler"); -} - -void glob_audio_device(t_pd *, t_symbol *s, int argc, t_atom *argv) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - ao.ndev = ai.ndev = INTARG(0); - for (int i=0; i<MAXAUDIOINDEV; i++) { - ao.dev [i] = ai.dev [i] = INTARG(i*2+1); - ao.chdev[i] = ai.chdev[i] = INTARG(i*2+2); - } - sys_close_audio(); sys_open_audio2(&ai,&ao, rate, dacblocksize, advance, scheduler); -} - -void glob_audio_device_in( t_pd *, t_symbol *s, int argc, t_atom *argv) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - ai.ndev = INTARG(0); - for (int i=0; i<MAXAUDIOINDEV; i+=2) {ai.dev[i] = INTARG(i+1); ai.chdev[i] = INTARG(i+2);} - sys_close_audio(); sys_open_audio2(&ai,&ao,rate, dacblocksize, advance, scheduler); -} -void glob_audio_device_out(t_pd *, t_symbol *s, int argc, t_atom *argv) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - ao.ndev = INTARG(0); - for (int i=0; i<MAXAUDIOOUTDEV; i+=2) {ao.dev[i] = INTARG(i+1); ao.chdev[i] = INTARG(i+2);} - sys_close_audio(); sys_open_audio2(&ai,&ao, rate, dacblocksize, advance, scheduler); -} - -/* some general helper functions */ -void sys_update_sleepgrain() {sys_sleepgrain = clip(sys_schedadvance/4,1000,5000);} - -/* t_audiodevs are the ones you're using; char[] are all the devices available. */ -void glob_audio_getaudioindevices(t_pd *, t_symbol *s, int ac, t_atom *av) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; - int nidev=0, nodev=0, canmulti=0; t_atom argv[MAXNDEV]; int f = ac ? atom_getintarg(0,ac,av) : -1; - t_symbol *selector = gensym("audioindev"), *pd = gensym("pd"); - char idevlist[MAXNDEV*DEVDESCSIZE], odevlist[MAXNDEV*DEVDESCSIZE]; - audio_getdevs(idevlist, &nidev, odevlist, &nodev, &canmulti, MAXNDEV, DEVDESCSIZE); - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - if (f<0) { - for (int i=0; i<nidev; i++) SETSTRING(argv+i,idevlist+i*DEVDESCSIZE); - typedmess(pd->s_thing, selector, nidev, argv); - } else if (f < nidev) { - SETSTRING(argv, idevlist + f*DEVDESCSIZE); - typedmess(pd->s_thing, selector, 1, argv); - } -} -void glob_audio_getaudiooutdevices(t_pd *, t_symbol *s, int ac, t_atom *av) { - t_audiodevs ai,ao; int rate, dacblocksize, advance, scheduler; - int nidev=0, nodev=0, canmulti=0; t_atom argv[MAXNDEV]; int f = ac ? atom_getintarg(0,ac,av) : -1; - t_symbol *selector = gensym("audiooutdev"), *pd = gensym("pd"); - char idevlist[MAXNDEV*DEVDESCSIZE], odevlist[MAXNDEV*DEVDESCSIZE]; - audio_getdevs(idevlist, &nidev, odevlist, &nodev, &canmulti, MAXNDEV, DEVDESCSIZE); - sys_get_audio_params(&ai,&ao, &rate, &dacblocksize, &advance, &scheduler); - if (f<0) { - for (int i=0; i<nodev; i++) SETSYMBOL(argv+i, gensym(odevlist+i*DEVDESCSIZE)); - typedmess(pd->s_thing, selector, nodev, argv); - } else if (f < nodev) { - SETSTRING(argv, odevlist + f*DEVDESCSIZE); - typedmess(pd->s_thing, selector, 1, argv); - } -} - -/* some prototypes from s_audio_portaudio.c */ -extern void pa_getcurrent_devices(); -extern void pa_getaudioininfo(t_float f); -extern void pa_getaudiooutinfo(t_float f); -extern void pa_test_setting (int ac, t_atom *av); -extern void pa_get_asio_latencies(t_float f); - -void glob_audio_getaudioininfo(t_pd *, t_float f) { -#if defined(USEAPI_PORTAUDIO) && !defined(PABLIO) - if (sys_audioapi == API_PORTAUDIO) pa_getaudioininfo(f); -#endif -} -void glob_audio_getaudiooutinfo(t_pd *, t_float f) { -#if defined(USEAPI_PORTAUDIO) && !defined(PABLIO) - if (sys_audioapi == API_PORTAUDIO) pa_getaudiooutinfo(f); -#endif -} -void glob_audio_testaudiosetting(t_pd *, t_symbol *s, int ac, t_atom *av) { -#if defined(USEAPI_PORTAUDIO) && !defined(PABLIO) - if (sys_audioapi == API_PORTAUDIO) pa_test_setting (ac, av); -#endif -} -void glob_audio_getcurrent_devices() { -#if defined(USEAPI_PORTAUDIO) && !defined(PABLIO) - if (sys_audioapi == API_PORTAUDIO) pa_getcurrent_devices(); -#endif -} -void glob_audio_asio_latencies(t_pd *, t_float f) { -#if defined(USEAPI_PORTAUDIO) && !defined(PABLIO) - if (sys_audioapi == API_PORTAUDIO) pa_get_asio_latencies(f); -#endif -} - -/* tb } */ diff --git a/desiredata/src/s_audio_alsa.c b/desiredata/src/s_audio_alsa.c deleted file mode 100644 index b812fba0..00000000 --- a/desiredata/src/s_audio_alsa.c +++ /dev/null @@ -1,554 +0,0 @@ -/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler, Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* this file inputs and outputs audio using the ALSA API available on linux. */ - -/* support for ALSA pcmv2 api by Karl MacMillan<karlmac@peabody.jhu.edu> */ -/* support for ALSA MMAP noninterleaved by Winfried Ritsch, IEM */ - -#include <alsa/asoundlib.h> - -#include "desire.h" -using namespace desire; -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <sched.h> -#include <sys/mman.h> -#include "s_audio_alsa.h" - -/* Defines */ -#define DEBUG(x) x -#define DEBUG2(x) {x;} - -/* needed for alsa 0.9 compatibility: */ -#if (SND_LIB_MAJOR < 1) -#define ALSAAPI9 -#endif - -//static void alsa_close_audio(); -static void alsa_checkiosync(); -static void alsa_numbertoname(int iodev, char *devname, int nchar); -static int alsa_jittermax; -static void alsa_close_audio(); -#define ALSA_DEFJITTERMAX 3 - - /* don't assume we can turn all 31 bits when doing float-to-fix; - otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */ -#define FMAX 0x7ffff000 -#define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x)) - -static char *alsa_snd_buf; -static int alsa_snd_bufsize; -static int alsa_buf_samps; -static snd_pcm_status_t *alsa_status; -static int alsa_usemmap; -t_alsa alsai,alsao; - -static void check_error(int err, const char *why) {if (err<0) error("%s: %s", why, snd_strerror(err));} - -static int alsaio_canmmap(t_alsa_dev *dev) { - snd_pcm_hw_params_t *hw_params; - int err1, err2; - snd_pcm_hw_params_alloca(&hw_params); - err1 = snd_pcm_hw_params_any(dev->a_handle, hw_params); - if (err1 < 0) { - check_error(err1,"Broken configuration: no configurations available"); - return 0; - } - err1 = snd_pcm_hw_params_set_access(dev->a_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err1 < 0) { - err2 = snd_pcm_hw_params_set_access(dev->a_handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); - } else err2 = -1; -#if 0 - error("err 1 %d (%s), err2 %d (%s)", err1, snd_strerror(err1), err2, snd_strerror(err2)); -#endif - return err1<0 && err2>=0; -} - -static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, int nfrags, int frag_size) { - int bufsizeforthis, err; - snd_pcm_hw_params_t* hw_params; - unsigned int tmp_uint; - snd_pcm_uframes_t tmp_snd_pcm_uframes; - if (sys_verbose) { - if (out) post("configuring sound output..."); - else post("configuring sound input..."); - } - /* set hardware parameters... */ - snd_pcm_hw_params_alloca(&hw_params); - /* get the default params */ - err = snd_pcm_hw_params_any(dev->a_handle, hw_params); - check_error(err, "snd_pcm_hw_params_any"); - /* try to set interleaved access */ - err = snd_pcm_hw_params_set_access(dev->a_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (err < 0) return -1; - check_error(err, "snd_pcm_hw_params_set_access"); - /* Try to set 32 bit format first */ - err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S32); - if (err<0) { - error("PD-ALSA: 32 bit format not available - using 16"); - err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params,SND_PCM_FORMAT_S16); - check_error(err, "snd_pcm_hw_params_set_format"); - dev->a_sampwidth = 2; - } else dev->a_sampwidth = 4; - if (sys_verbose) post("Sample width set to %d bytes", dev->a_sampwidth); - /* set the subformat */ - err = snd_pcm_hw_params_set_subformat(dev->a_handle, hw_params, SND_PCM_SUBFORMAT_STD); - check_error(err, "snd_pcm_hw_params_set_subformat"); - /* set the number of channels */ - tmp_uint = *channels; - err = snd_pcm_hw_params_set_channels_min(dev->a_handle, hw_params, &tmp_uint); - check_error(err, "snd_pcm_hw_params_set_channels"); - if (tmp_uint != (unsigned)*channels) post("ALSA: set input channels to %d", tmp_uint); - *channels = tmp_uint; - dev->a_channels = *channels; - /* set the sampling rate */ - err = snd_pcm_hw_params_set_rate_min(dev->a_handle, hw_params, (unsigned int *)rate, 0); - check_error(err, "snd_pcm_hw_params_set_rate_min (input)"); -#if 0 - err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir); - post("input sample rate %d", err); -#endif - /* set the period - ie frag size */ - /* LATER try this to get a recommended period size... - right now, it trips an assertion failure in ALSA lib */ -#ifdef ALSAAPI9 - err = snd_pcm_hw_params_set_period_size_near(dev->a_handle, hw_params, (snd_pcm_uframes_t)frag_size, 0); -#else - tmp_snd_pcm_uframes = frag_size; - err = snd_pcm_hw_params_set_period_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes, 0); -#endif - check_error(err, "snd_pcm_hw_params_set_period_size_near (input)"); - /* set the number of periods - ie numfrags */ -#ifdef ALSAAPI9 - err = snd_pcm_hw_params_set_periods_near(dev->a_handle, hw_params, nfrags, 0); -#else - tmp_uint = nfrags; - err = snd_pcm_hw_params_set_periods_near(dev->a_handle, hw_params, &tmp_uint, 0); -#endif - check_error(err, "snd_pcm_hw_params_set_periods_near (input)"); - /* set the buffer size */ -#ifdef ALSAAPI9 - err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle, hw_params, nfrags * frag_size); -#else - tmp_snd_pcm_uframes = nfrags * frag_size; - err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes); -#endif - check_error(err, "snd_pcm_hw_params_set_buffer_size_near (input)"); - err = snd_pcm_hw_params(dev->a_handle, hw_params); - check_error(err, "snd_pcm_hw_params (input)"); - /* set up the buffer */ - bufsizeforthis = sys_dacblocksize * dev->a_sampwidth * *channels; - if (alsa_snd_buf) { - if (alsa_snd_bufsize < bufsizeforthis) { - if (!(alsa_snd_buf = (char *)realloc(alsa_snd_buf, bufsizeforthis))) {error("out of memory"); return 0;} - memset(alsa_snd_buf, 0, bufsizeforthis); - alsa_snd_bufsize = bufsizeforthis; - } - } else { - if (!(alsa_snd_buf = (char *)malloc(bufsizeforthis))) {error("out of memory"); return 0;} - memset(alsa_snd_buf, 0, bufsizeforthis); - alsa_snd_bufsize = bufsizeforthis; - } - return 1; -} - -/* return 0 on success */ -static int alsa_open_audio( -int naudioindev, int * audioindev, int nchindev, int * chindev, -int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int dummy) { - int err, inchans = 0, outchans = 0; - char devname[512]; - int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE); - int nfrags, i; - nfrags = int(sys_schedadvance * (float)rate / (1e6 * frag_size)); - /* save our belief as to ALSA's buffer size for later */ - alsa_buf_samps = nfrags * frag_size; - alsai.ndev = alsao.ndev = 0; - alsa_jittermax = ALSA_DEFJITTERMAX; - if (sys_verbose) post("audio buffer set to %d", (int)(0.001 * sys_schedadvance)); - for (int i=0; i<naudioindev; i++) { - alsa_numbertoname(audioindev[i], devname, 512); - err = snd_pcm_open(&alsai.dev[alsai.ndev].a_handle, devname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); - check_error(err, "snd_pcm_open (input)"); - if (err<0) continue; - alsai.dev[alsai.ndev].a_devno = audioindev[i]; - snd_pcm_nonblock(alsai.dev[alsai.ndev].a_handle, 1); - if (sys_verbose) post("opened input device name %s", devname); - alsai.ndev++; - } - for (int i=0; i<naudiooutdev; i++) { - alsa_numbertoname(audiooutdev[i], devname, 512); - err = snd_pcm_open(&alsao.dev[alsao.ndev].a_handle, devname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - check_error(err, "snd_pcm_open (output)"); - if (err<0) continue; - alsao.dev[alsao.ndev].a_devno = audiooutdev[i]; - snd_pcm_nonblock(alsao.dev[alsao.ndev].a_handle, 1); - alsao.ndev++; - } - if (!alsai.ndev && !alsao.ndev) goto blewit; - /* If all the open devices support mmap_noninterleaved, let's call Wini's code in s_audio_alsamm.c */ - alsa_usemmap = 1; - for (int i=0; i<alsai.ndev; i++) if (!alsaio_canmmap(&alsai.dev[i])) alsa_usemmap = 0; - for (int i=0; i<alsao.ndev; i++) if (!alsaio_canmmap(&alsao.dev[i])) alsa_usemmap = 0; - if (alsa_usemmap) { - post("using mmap audio interface"); - if (alsamm_open_audio(rate)) goto blewit; else return 0; - } - for (int i=0; i<alsai.ndev; i++) { - int channels = chindev[i]; - if (alsaio_setup(&alsai.dev[i], 0, &channels, &rate, nfrags, frag_size) < 0) goto blewit; - inchans += channels; - } - for (int i=0; i<alsao.ndev; i++) { - int channels = choutdev[i]; - if (alsaio_setup(&alsao.dev[i], 1, &channels, &rate, nfrags, frag_size) < 0) goto blewit; - outchans += channels; - } - if (!inchans && !outchans) goto blewit; - for (int i=0; i<alsai.ndev; i++) snd_pcm_prepare(alsai.dev[i].a_handle); - for (int i=0; i<alsao.ndev; i++) snd_pcm_prepare(alsao.dev[i].a_handle); - /* if duplex we can link the channels so they start together; however j is not used, so wtf */ - for (int i=0; i<alsai.ndev; i++) { - //for (int j=0; j<alsao.ndev; j++) { - if (alsai.dev[i].a_devno == alsao.dev[i].a_devno) { - snd_pcm_link(alsai.dev[i].a_handle,alsao.dev[i].a_handle); - } - //} - } - /* allocate the status variables */ - if (!alsa_status) { - err = snd_pcm_status_malloc(&alsa_status); - check_error(err, "snd_pcm_status_malloc"); - } - /* fill the buffer with silence */ - memset(alsa_snd_buf, 0, alsa_snd_bufsize); - if (outchans) { - i = (frag_size * nfrags)/sys_dacblocksize + 1; - while (i--) { - for (int i=0; i<alsao.ndev; i++) - snd_pcm_writei(alsao.dev[i].a_handle, alsa_snd_buf, sys_dacblocksize); - } - } else if (inchans) { - for (int i=0; i<alsai.ndev; i++) - if ((err = snd_pcm_start(alsai.dev[i].a_handle)) < 0) check_error(err, "input start failed"); - } - return 0; -blewit: - sys_inchannels = 0; - sys_outchannels = 0; - alsa_close_audio(); - return 1; -} - -static void alsa_close_audio() { - int err; - if (alsa_usemmap) {alsamm_close_audio(); return;} - for (int i=0; i<alsai.ndev; i++) { - err = snd_pcm_close(alsai.dev[i].a_handle); - check_error(err, "snd_pcm_close (input)"); - } - for (int i=0; i<alsao.ndev; i++) { - err = snd_pcm_close(alsao.dev[i].a_handle); - check_error(err, "snd_pcm_close (output)"); - } - alsai.ndev = alsao.ndev = 0; -} - -int alsa_send_dacs() { -#ifdef DEBUG_ALSA_XFER - static int xferno = 0; - static int callno = 0; -#endif - static double timenow; - double timelast; - t_sample *fp1, *fp2; - int j, k, iodev, result, ch; - int chansintogo, chansouttogo; - unsigned int transfersize; - if (alsa_usemmap) return alsamm_send_dacs(); - if (!alsai.ndev && !alsao.ndev) return SENDDACS_NO; - chansintogo = sys_inchannels; - chansouttogo = sys_outchannels; - transfersize = sys_dacblocksize; - timelast = timenow; - timenow = sys_getrealtime(); -#ifdef DEBUG_ALSA_XFER - if (timenow - timelast > 0.050) post("(%d)", int(1000 * (timenow - timelast))); - callno++; -#endif - alsa_checkiosync(); /* check I/O are in sync and data not late */ - for (int i=0; i<alsai.ndev; i++) { - snd_pcm_status(alsai.dev[i].a_handle, alsa_status); - if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO; - } - for (int i=0; i<alsao.ndev; i++) { - snd_pcm_status(alsao.dev[i].a_handle, alsa_status); - if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO; - } - /* do output */ - fp1 = sys_soundout; ch = 0; - for (int iodev=0; iodev<alsao.ndev; iodev++) { - int thisdevchans = alsao.dev[iodev].a_channels; - int chans = min(chansouttogo,thisdevchans); - chansouttogo -= chans; - int i; - if (alsao.dev[iodev].a_sampwidth == 4) { - for (i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) { - fp2 = fp1; - for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans, fp2++) { - float s1 = *fp2 * INT32_MAX; - ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(int(s1)); - } - } - for (; i<thisdevchans; i++, ch++) - for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0; - } else { - for (i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) { - fp2=fp1; - for (int j=ch, k=sys_dacblocksize; k--; j += thisdevchans, fp2++) { - int s = int(*fp2 * 32767.); - if (s > 32767) s = 32767; else if (s < -32767) s = -32767; - ((t_alsa_sample16 *)alsa_snd_buf)[j] = s; - } - } - for (; i < thisdevchans; i++, ch++) - for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample16 *)alsa_snd_buf)[j] = 0; - } - result = snd_pcm_writei(alsao.dev[iodev].a_handle, alsa_snd_buf, transfersize); - if (result != (int)transfersize) { - #ifdef DEBUG_ALSA_XFER - if (result >= 0 || errno == EAGAIN) post("ALSA: write returned %d of %d", result, transfersize); - else error("ALSA: write: %s", snd_strerror(errno)); - post("inputcount %d, outputcount %d, outbufsize %d", - inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsao.dev[iodev].a_sampwidth * outchannels); - #endif - sys_log_error(ERR_DACSLEPT); - return SENDDACS_NO; - } - /* zero out the output buffer */ - memset(sys_soundout, 0, sys_dacblocksize * sizeof(*sys_soundout) * sys_outchannels); - if (sys_getrealtime() - timenow > 0.002) { - #ifdef DEBUG_ALSA_XFER - post("output %d took %d msec", callno, int(1000 * (timenow - timelast))); - #endif - timenow = sys_getrealtime(); - sys_log_error(ERR_DACSLEPT); - } - } - /* do input */ - for (iodev = 0, fp1 = sys_soundin, ch = 0; iodev < alsai.ndev; iodev++) { - int thisdevchans = alsai.dev[iodev].a_channels; - int chans = (chansintogo < thisdevchans ? chansintogo : thisdevchans); - chansouttogo -= chans; - result = snd_pcm_readi(alsai.dev[iodev].a_handle, alsa_snd_buf, transfersize); - if (result < (int)transfersize) { -#ifdef DEBUG_ALSA_XFER - if (result<0) error("snd_pcm_read %d %d: %s", callno, xferno, snd_strerror(errno)); - else post("snd_pcm_read %d %d returned only %d", callno, xferno, result); - post("inputcount %d, outputcount %d, inbufsize %d", - inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsai.dev[iodev].a_sampwidth * inchannels); -#endif - sys_log_error(ERR_ADCSLEPT); - return SENDDACS_NO; - } - if (alsai.dev[iodev].a_sampwidth == 4) { - for (int i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) { - for (j = ch, k = sys_dacblocksize, fp2 = fp1; k--; j += thisdevchans, fp2++) - *fp2 = (float) ((t_alsa_sample32 *)alsa_snd_buf)[j] * (1./ INT32_MAX); - } - } else { - for (int i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) { - for (j = ch, k = sys_dacblocksize, fp2 = fp1; k--; j += thisdevchans, fp2++) - *fp2 = (float) ((t_alsa_sample16 *)alsa_snd_buf)[j] * 3.051850e-05; - } - } - } -#ifdef DEBUG_ALSA_XFER - xferno++; -#endif - if (sys_getrealtime() - timenow > 0.002) { -#ifdef DEBUG_ALSA_XFER - post("routine took %d msec", int(1000 * (sys_getrealtime() - timenow))); -#endif - sys_log_error(ERR_ADCSLEPT); - } - return SENDDACS_YES; -} - -void alsa_printstate() { - int result, i=0; - snd_pcm_sframes_t indelay, outdelay; - if (sys_audioapi != API_ALSA) { - error("restart-audio: implemented for ALSA only."); - return; - } - if (sys_inchannels) { - result = snd_pcm_delay(alsai.dev[i].a_handle, &indelay); - if (result<0) error("snd_pcm_delay 1 failed"); else post( "in delay %d", int( indelay)); - } - if (sys_outchannels) { - result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay); - if (result<0) error("snd_pcm_delay 2 failed"); else post("out delay %d", int(outdelay)); - } - post("sum %ld (%ld mod 64)", indelay + outdelay, (indelay+outdelay)%64); - post("buf samples %d", alsa_buf_samps); -} - - -void alsa_putzeros(int iodev, int n) { - memset(alsa_snd_buf, 0, alsao.dev[iodev].a_sampwidth * sys_dacblocksize * alsao.dev[iodev].a_channels); - for (int i=0; i<n; i++) snd_pcm_writei(alsao.dev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize); -} - -void alsa_getzeros(int iodev, int n) { - for (int i=0; i<n; i++) snd_pcm_readi(alsai.dev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize); -} - -/* call this only if both input and output are open */ -static void alsa_checkiosync() { - int result, giveup = 1000, alreadylogged = 0; - snd_pcm_sframes_t minphase, maxphase, thisphase, outdelay; - while (1) { - if (giveup-- <= 0) {post("tried but couldn't sync A/D/A"); alsa_jittermax += 1; return;} - minphase = 0x7fffffff; - maxphase = -0x7fffffff; - for (int i=0; i<alsao.ndev; i++) { - result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay); - if (result < 0) { - snd_pcm_prepare(alsao.dev[i].a_handle); - result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay); - } - if (result<0) { - error("output snd_pcm_delay failed: %s", snd_strerror(result)); - if (snd_pcm_status(alsao.dev[i].a_handle, alsa_status)<0) error("output snd_pcm_status failed"); - else post("astate %d", snd_pcm_status_get_state(alsa_status)); - return; - } - thisphase = alsa_buf_samps - outdelay; - if (thisphase < minphase) minphase = thisphase; - if (thisphase > maxphase) maxphase = thisphase; - if (outdelay < 0) - sys_log_error(ERR_DATALATE), alreadylogged = 1; - } - for (int i=0; i<alsai.ndev; i++) { - result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase); - if (result < 0) { - snd_pcm_prepare(alsai.dev[i].a_handle); - result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase); - } - if (result < 0) { - error("output snd_pcm_delay failed: %s", snd_strerror(result)); - if (snd_pcm_status(alsao.dev[i].a_handle, alsa_status) < 0) error("output snd_pcm_status failed"); - else post("astate %d", snd_pcm_status_get_state(alsa_status)); - return; - } - if (thisphase < minphase) minphase = thisphase; - if (thisphase > maxphase) maxphase = thisphase; - } - /* the "correct" position is for all the phases to be exactly equal; - but since we only make corrections sys_dacblocksize samples at a time, - we just ask that the spread be not more than 3/4 of a block. */ - if (maxphase <= minphase + (alsa_jittermax * (sys_dacblocksize / 4))) break; - if (!alreadylogged) sys_log_error(ERR_RESYNC), alreadylogged = 1; - for (int i=0; i<alsao.ndev; i++) { - result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay); - if (result < 0) break; - thisphase = alsa_buf_samps - outdelay; - if (thisphase > minphase + sys_dacblocksize) { - alsa_putzeros(i,1); -#if DEBUGSYNC - post("putz %d %d", (int)thisphase, (int)minphase); -#endif - } - } - for (int i=0; i<alsai.ndev; i++) { - result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase); - if (result < 0) break; - if (thisphase > minphase + sys_dacblocksize) { - alsa_getzeros(i, 1); -#if DEBUGSYNC - post("getz %d %d", (int)thisphase, (int)minphase); -#endif - } - } - } -#if DEBUGSYNC - if (alreadylogged) post("done"); -#endif -} - -static int alsa_nnames = 0; -static char **alsa_names = 0; - -void alsa_adddev(char *name) { - if (alsa_nnames) alsa_names = (char **)t_resizebytes(alsa_names, alsa_nnames*sizeof(char *), (alsa_nnames+1)*sizeof(char *)); - else alsa_names = (char **)t_getbytes(sizeof(char *)); - alsa_names[alsa_nnames] = gensym(name)->s_name; - alsa_nnames++; -} - -static void alsa_numbertoname(int devno, char *devname, int nchar) { - int ndev = 0, cardno = -1; - while (!snd_card_next(&cardno) && cardno >= 0) ndev++; - if (devno < 2*ndev) { - if (devno & 1) snprintf(devname, nchar, "plughw:%d", devno/2); - else snprintf(devname, nchar, "hw:%d", devno/2); - } else if (devno <2*ndev + alsa_nnames) - snprintf(devname, nchar, "%s", alsa_names[devno - 2*ndev]); - else snprintf(devname, nchar, "???"); -} - -/* For each hardware card found, we list two devices, the "hard" and - "plug" one. The card scan is derived from portaudio code. */ -static void alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - int ndev = 0, cardno = -1, i, j; - *canmulti = 2; /* supports multiple devices */ - while (!snd_card_next(&cardno) && cardno >= 0) { - snd_ctl_t *ctl; - snd_ctl_card_info_t *info; - char devname[80]; - char *desc; - if (2*ndev + 2 > maxndev) break; - /* apparently, "cardno" is just a counter; but check that here */ - if (ndev != cardno) post("oops: ALSA cards not reported in order?"); - sprintf(devname, "hw:%d", cardno); - /* post("try %s..", devname); */ - if (snd_ctl_open(&ctl, devname, 0) >= 0) { - snd_ctl_card_info_malloc(&info); - snd_ctl_card_info(ctl, info); - desc = strdup(snd_ctl_card_info_get_name(info)); - snd_ctl_card_info_free(info); - } else { - error("ALSA card scan error"); - desc = strdup("???"); - } - sprintf(indevlist + 2*ndev * devdescsize, "%s (hardware)", desc); - sprintf(indevlist + (2*ndev+1) * devdescsize, "%s (plug-in)", desc); - sprintf(outdevlist + 2*ndev * devdescsize, "%s (hardware)", desc); - sprintf(outdevlist + (2*ndev+1) * devdescsize, "%s (plug-in)", desc); - ndev++; - free(desc); - } - for (i=0, j=2*ndev; i<alsa_nnames; i++, j++) { - if (j >= maxndev) break; - snprintf(indevlist + j * devdescsize, devdescsize, "%s", alsa_names[i]); - } - *nindevs = *noutdevs = j; -} - -struct t_audioapi alsa_api = { - alsa_open_audio, - alsa_close_audio, - alsa_send_dacs, - alsa_getdevs, -}; diff --git a/desiredata/src/s_audio_alsa.h b/desiredata/src/s_audio_alsa.h deleted file mode 100644 index 4d67f78f..00000000 --- a/desiredata/src/s_audio_alsa.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 1997- Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - - -typedef int16_t t_alsa_sample16; -typedef int32_t t_alsa_sample32; -#define ALSA_SAMPLEWIDTH_16 sizeof(t_alsa_sample16) -#define ALSA_SAMPLEWIDTH_32 sizeof(t_alsa_sample32) -#define ALSA_XFERSIZE16 (signed int)(sizeof(t_alsa_sample16) * sys_dacblocksize) -#define ALSA_XFERSIZE32 (signed int)(sizeof(t_alsa_sample32) * sys_dacblocksize) -#define ALSA_MAXDEV 4 -#define ALSA_JITTER 1024 -#define ALSA_EXTRABUFFER 2048 -#define ALSA_DEFFRAGSIZE 64 -#define ALSA_DEFNFRAG 12 - -#ifndef INT32_MAX -#define INT32_MAX 0x7fffffff -#endif - -struct t_alsa_dev { - snd_pcm_t *a_handle; - int a_devno; - int a_sampwidth; - int a_channels; - char **a_addr; - int a_synced; -}; - -struct t_alsa { - t_alsa_dev dev[ALSA_MAXDEV]; - int ndev; -}; -extern t_alsa alsai, alsao; - -int alsamm_open_audio(int rate); -void alsamm_close_audio(void); -int alsamm_send_dacs(void); diff --git a/desiredata/src/s_audio_alsamm.c b/desiredata/src/s_audio_alsamm.c deleted file mode 100644 index 54dbbf50..00000000 --- a/desiredata/src/s_audio_alsamm.c +++ /dev/null @@ -1,644 +0,0 @@ -/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ -/* - this audiodriverinterface inputs and outputs audio data using - the ALSA MMAP API available on linux. - this is optimized for hammerfall cards and does not make an attempt to be general - now, please adapt to your needs or let me know ... - constrains now: - - audio Card with ALSA-Driver > 1.0.3, - - alsa-device (preferable hw) with MMAP NONINTERLEAVED SIGNED-32Bit features - - up to 4 cards with has to be hardwaresynced - (winfried) -*/ -#include <alsa/asoundlib.h> -#include "desire.h" -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <sched.h> -#include "s_audio_alsa.h" - -/* needed for alsa 0.9 compatibility: */ -#if (SND_LIB_MAJOR < 1) -#define ALSAAPI9 -#endif -/* sample type magic ... - Hammerfall/HDSP/DSPMADI cards always 32Bit where lower 8Bit not used (played) in AD/DA, - but can have some bits set (subchannel coding) -*/ -#define ALSAMM_SAMPLEWIDTH_32 sizeof(t_alsa_sample32) - -#ifndef INT32_MAX -#define INT32_MAX 0x7fffffff -#endif - -/* maybe: - don't assume we can turn all 31 bits when doing float-to-fix; - otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. - but not now on hammerfall (w) -*/ - -/* 24 Bit are used so MAX Samplevalue not INT32_MAX ??? */ -#define F32MAX 0x7fffff00 -#define CLIP32(x) (((x)>F32MAX)?F32MAX:((x) < -F32MAX)?-F32MAX:(x)) - -#define ALSAMM_FORMAT SND_PCM_FORMAT_S32 -/* maximum of 4 devices. you can mix rme9632,hdsp9632 (18 chans) rme9652,hdsp9652 (26 chans), dsp-madi (64 chans) if synced */ - -/* we need same samplerate, buffertime and so on for each card soo we use global vars... - time is in us, size in frames (i hope so ;-) */ -static unsigned int alsamm_sr = 0; -static unsigned int alsamm_buffertime = 0; -static unsigned int alsamm_buffersize = 0; - -static bool debug=0; - -/* bad style: we asume all cards give the same answer at init so we make this vars global - to have a faster access in writing reading during send_dacs */ -static snd_pcm_sframes_t alsamm_period_size; -static unsigned int alsamm_periods; -static snd_pcm_sframes_t alsamm_buffer_size; - -/* if more than this sleep detected, should be more than periodsize/samplerate ??? */ -static double sleep_time; - -/* now we just sum all inputs/outputs of used cards to a global count - and use them all - ... later we should just use some channels of each card for pd - so we reduce the overhead of using alsways all channels, - and zero the rest once at start, - because rme9652 and hdsp forces us to use all channels - in mmap mode... - -Note on why: - normally hdsp and dspmadi can handle channel - count from one to all since they can switch on/off - the dma for them to reduce pci load, but this is only - implemented in alsa low level drivers for dspmadi now and maybe fixed for hdsp in future -*/ - -static int alsamm_inchannels = 0; -static int alsamm_outchannels = 0; - -/* Defines */ -#define WATCH_PERIODS 90 -static int in_avail[WATCH_PERIODS]; -static int out_avail[WATCH_PERIODS]; -static int in_offset[WATCH_PERIODS]; -static int out_offset[WATCH_PERIODS]; -static int out_cm[WATCH_PERIODS]; -static char *outaddr[WATCH_PERIODS]; -static char *inaddr[WATCH_PERIODS]; -static int xruns_watch[WATCH_PERIODS]; -static int broken_opipe; -static int dac_send = 0; -static int alsamm_xruns = 0; - -static void show_availist() { - for(int i=1; i<WATCH_PERIODS; i++) { - post("%2d:avail i=%7d %s o=%7d(%5d), offset i=%7d %s o=%7d, ptr i=%12p o=%12p, %d xruns ", - i,in_avail[i],(out_avail[i] != in_avail[i])? "!=" : "==" , out_avail[i],out_cm[i], - in_offset[i],(out_offset[i] != in_offset[i])? "!=" : "==" , out_offset[i], - inaddr[i], outaddr[i], xruns_watch[i]); - } -} - -/* protos */ -static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, int *chs); -static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int playback); -static void alsamm_start(); -static void alsamm_stop(); - -/* for debugging attach output of alsa mesages to stdout stream */ -snd_output_t* alsa_stdout; - -static void check_error(int err, const char *why) {if (err < 0) error("%s: %s", why, snd_strerror(err));} -class AlsaError : Error { -public: - int err; - AlsaError (int err) : err(err) {}}; -#define CHK(CODE) do {int err=CODE; if (err<0) {error("%s: %s", #CODE, snd_strerror(err)); throw AlsaError(err);}} while (0) -#define CH(CODE) do {int err=CODE; if (err<0) {error("%s: %s", #CODE, snd_strerror(err)); }} while (0) - -int alsamm_open_audio(int rate) { - int err; - snd_pcm_hw_params_t* hw_params; - snd_pcm_sw_params_t* sw_params; - /* fragsize is an old concept now use periods, used to be called fragments. */ - /* Be aware in ALSA periodsize can be in bytes, where buffersize is in frames, - but sometimes buffersize is in bytes and periods in frames, crazy alsa... - ...we use periodsize and buffersize in frames */ - snd_pcm_hw_params_alloca(&hw_params); - snd_pcm_sw_params_alloca(&sw_params); - /* see add_devname */ - /* first have a look which cards we can get and set up device infos for them */ - /* init some structures */ - for(int i=0; i<ALSA_MAXDEV;i++) { - alsai.dev[i].a_synced=alsao.dev[i].a_synced=0; - alsai.dev[i].a_channels=alsao.dev[i].a_channels=-1; /* query defaults */ - } - alsamm_inchannels = 0; - alsamm_outchannels = 0; - /* opening alsa debug channel */ - CH(snd_output_stdio_attach(&alsa_stdout, stdout, 0)); - /* Weak failure prevention: - first card found (out then in) is used as a reference for parameter, - so this set the globals and other cards hopefully dont change them - */ - alsamm_sr = rate; - /* set the asked buffer time (alsa buffertime in us)*/ - alsamm_buffertime = alsamm_buffersize = 0; - if(sys_blocksize == 0) - alsamm_buffertime = sys_schedadvance; - else - alsamm_buffersize = sys_blocksize; - if(sys_verbose) - post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d" - "or sys_blocksize=%d (samples) to use buffersize=%d", - sys_schedadvance,sys_advance_samples,alsamm_buffertime,sys_blocksize,alsamm_buffersize); - alsamm_periods = 0; /* no one wants periods setting from command line ;-) */ - for (int i=0; i<alsao.ndev;i++) { - /* post("open audio out %d, of %lx, %d",i,&alsa_device[i], alsao.dev[i].a_handle); */ - try { - CHK(set_hwparams(alsao.dev[i].a_handle, hw_params, &(alsao.dev[i].a_channels))); - CHK(set_swparams(alsao.dev[i].a_handle, sw_params,1)); - alsamm_outchannels += alsao.dev[i].a_channels; - alsao.dev[i].a_addr = (char **)malloc(sizeof(char *)*alsao.dev[i].a_channels); - if(!alsao.dev[i].a_addr) {error("playback device outaddr allocation error:"); continue;} - memset(alsao.dev[i].a_addr, 0, sizeof(char*) * alsao.dev[i].a_channels); - post("playback device with %d channels and buffer_time %d us opened", alsao.dev[i].a_channels, alsamm_buffertime); - } catch (AlsaError) {continue;} - } - for (int i=0; i<alsai.ndev; i++) { - if(sys_verbose) post("capture card %d:--------------------",i); - CHK(set_hwparams(alsai.dev[i].a_handle, hw_params, &(alsai.dev[i].a_channels))); - alsamm_inchannels += alsai.dev[i].a_channels; - CHK(set_swparams(alsai.dev[i].a_handle, sw_params,0)); - alsai.dev[i].a_addr = (char **)malloc(sizeof(char*)*alsai.dev[i].a_channels); - if(!alsai.dev[i].a_addr) {error("capture device inaddr allocation error:"); continue;} - memset(alsai.dev[i].a_addr, 0, sizeof(char*) * alsai.dev[i].a_channels); - if(sys_verbose) post("capture device with %d channels and buffertime %d us opened", alsai.dev[i].a_channels,alsamm_buffertime); - } - /* check for linked handles of input for each output*/ - for (int i=0; i<(alsao.ndev < alsai.ndev ? alsao.ndev:alsai.ndev); i++) { - if (alsao.dev[i].a_devno == alsai.dev[i].a_devno) { - if ((err = snd_pcm_link(alsai.dev[i].a_handle, alsao.dev[i].a_handle)) == 0) { - alsai.dev[i].a_synced = alsao.dev[i].a_synced = 1; - if(sys_verbose) post("Linking in and outs of card %d",i); - } else error("could not link in and outs"); - } - } - /* some globals */ - sleep_time = (float) alsamm_period_size/ (float) alsamm_sr; - if (debug) { - /* start ---------------------------- */ - if(sys_verbose) post("open_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns); - alsamm_xruns = dac_send = 0; /* reset debug */ - /* start alsa in open or better in send_dacs once ??? we will see */ - for (int i=0;i<alsao.ndev;i++) snd_pcm_dump(alsao.dev[i].a_handle, alsa_stdout); - for (int i=0;i<alsai.ndev;i++) snd_pcm_dump(alsai.dev[i].a_handle, alsa_stdout); - fflush(stdout); - } - sys_setchsr(alsamm_inchannels, alsamm_outchannels, alsamm_sr, sys_dacblocksize); - alsamm_start(); - /* report success */ - return 0; -} - -void alsamm_close_audio() { - if(debug&&sys_verbose) post("closing devices"); - alsamm_stop(); - for (int i=0; i<alsao.ndev; i++) { - //if(debug&&sys_verbose) post("unlink audio out %d, of %lx",i,used_outdevice[i]); - if(alsao.dev[i].a_synced) { - CHK(snd_pcm_unlink(alsao.dev[i].a_handle)); - alsao.dev[i].a_synced = 0; - } - CHK(snd_pcm_close(alsao.dev[i].a_handle)); - if(alsao.dev[i].a_addr) {free(alsao.dev[i].a_addr); alsao.dev[i].a_addr=0;} - alsao.dev[i].a_channels = 0; - } - for (int i=0; i<alsai.ndev; i++) { - CHK(snd_pcm_close(alsai.dev[i].a_handle)); - if(alsai.dev[i].a_addr) {free(alsai.dev[i].a_addr); alsai.dev[i].a_addr=0;} - alsai.dev[i].a_channels = 0; - } - alsai.ndev = alsao.ndev = 0; - if(debug) { - if(sys_verbose) post("close_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns); - alsamm_xruns = dac_send = 0; - } -} - -/* ------- PCM INITS --------------------------------- */ -static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params,int *chs) { - try { -#ifndef ALSAAPI9 - unsigned int rrate; - /* choose all parameters */ - CHK(snd_pcm_hw_params_any(handle, params)); - /* set the nointerleaved read/write format */ - CHK(snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)); - /* set the sample format */ - CHK(snd_pcm_hw_params_set_format(handle, params, ALSAMM_FORMAT)); - if(debug&&sys_verbose) post("Setting format to %s",snd_pcm_format_name(ALSAMM_FORMAT)); - /* first check samplerate since channels numbers are samplerate dependend (double speed) */ - /* set the stream rate */ - rrate = alsamm_sr; - if(debug&&sys_verbose) post("Samplerate request: %i Hz",rrate); - int dir=-1; - CHK(snd_pcm_hw_params_set_rate_near(handle, params, &rrate, &dir)); - if (rrate != alsamm_sr) { - post("Warning: rate %iHz doesn't match requested %iHz", rrate,alsamm_sr); - alsamm_sr = rrate; - } else if (sys_verbose) post("Samplerate is set to %iHz",alsamm_sr); - /* Info on channels */ - { - int maxchs,minchs,channels = *chs; - CHK(snd_pcm_hw_params_get_channels_max(params, (unsigned *)&maxchs)); - CHK(snd_pcm_hw_params_get_channels_min(params, (unsigned *)&minchs)); - if(debug&&sys_verbose) post("Getting channels:min=%d, max= %d for request=%d",minchs,maxchs,channels); - if(channels<0) channels=maxchs; - if(channels>maxchs) channels = maxchs; - if(channels<minchs) channels = minchs; - if(channels != *chs) post("requested channels=%d but used=%d",*chs,channels); - *chs = channels; - if(debug&&sys_verbose) post("trying to use channels: %d",channels); - } - /* set the count of channels */ - CHK(snd_pcm_hw_params_set_channels(handle, params, *chs)); - /* testing for channels */ - CH(snd_pcm_hw_params_get_channels(params,(unsigned int *)chs)); - if(debug&&sys_verbose) post("When setting channels count, got %d",*chs); - /* if buffersize is set use this instead buffertime */ - if(alsamm_buffersize > 0) { - if(debug&&sys_verbose) post("hw_params: ask for max buffersize of %d samples", (unsigned int) alsamm_buffersize); - alsamm_buffer_size = alsamm_buffersize; - CHK(snd_pcm_hw_params_set_buffer_size_near(handle, params, (unsigned long *)&alsamm_buffer_size)); - } - else { - if(alsamm_buffertime <= 0) /* should never happen, but use 20ms */ - alsamm_buffertime = 20000; - if(debug&&sys_verbose) post("hw_params: ask for max buffertime of %d ms", (unsigned int) (alsamm_buffertime*0.001) ); - CHK(snd_pcm_hw_params_set_buffer_time_near(handle, params, &alsamm_buffertime, &dir)); - } - CHK(snd_pcm_hw_params_get_buffer_time(params, (unsigned *)&alsamm_buffertime, &dir)); - if(debug&&sys_verbose) post("hw_params: got buffertime to %f ms", float(alsamm_buffertime*0.001)); - CHK(snd_pcm_hw_params_get_buffer_size(params, (unsigned long *)&alsamm_buffer_size)); - if(debug&&sys_verbose) post("hw_params: got buffersize to %d samples",(int) alsamm_buffer_size); - CHK(snd_pcm_hw_params_get_period_size(params, (unsigned long *)&alsamm_period_size, &dir)); - if(debug&&sys_verbose) post("Got period size of %d", (int) alsamm_period_size); - { - unsigned int pmin,pmax; - CHK(snd_pcm_hw_params_get_periods_min(params, &pmin, &dir)); - CHK(snd_pcm_hw_params_get_periods_min(params, &pmax, &dir)); - /* use maximum of periods */ - if( alsamm_periods <= 0) alsamm_periods = pmax; - alsamm_periods = (alsamm_periods > pmax)?pmax:alsamm_periods; - alsamm_periods = (alsamm_periods < pmin)?pmin:alsamm_periods; - CHK(snd_pcm_hw_params_set_periods(handle, params, alsamm_periods, dir)); - CHK(snd_pcm_hw_params_get_periods(params, &pmin, &dir)); - if(debug&&sys_verbose) post("Got periods of %d, where periodsmin=%d, periodsmax=%d",alsamm_periods,pmin,pmax); - } - /* write the parameters to device */ - CHK(snd_pcm_hw_params(handle, params)); -#endif /* ALSAAPI9 */ - return 0; - } catch (AlsaError e) {return e.err;} -} - -static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int playback) { - try { -#ifndef ALSAAPI9 - snd_pcm_uframes_t ps,ops; - snd_pcm_uframes_t bs,obs; - /* get the current swparams */ - CHK(snd_pcm_sw_params_current(handle, swparams)); - /* AUTOSTART: start the transfer on each write/commit ??? */ - snd_pcm_sw_params_get_start_threshold(swparams, &obs); - CHK(snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U)); - snd_pcm_sw_params_get_start_threshold(swparams, &bs); - if(debug&&sys_verbose) post("sw_params: got start_thresh_hold= %d (was %d)",(int) bs,(int)obs); - /* AUTOSTOP: never stop the machine */ - snd_pcm_sw_params_get_stop_threshold(swparams, &obs); - CHK(snd_pcm_sw_params_set_stop_threshold(handle, swparams, (snd_pcm_uframes_t)-1)); - snd_pcm_sw_params_get_stop_threshold(swparams, &bs); - if(debug&&sys_verbose) post("sw_params: set stop_thresh_hold= %d (was %d)", (int) bs,(int)obs); - /* AUTOSILENCE: silence if overrun.... */ - snd_pcm_sw_params_get_silence_threshold(swparams, &ops); - CHK(snd_pcm_sw_params_set_silence_threshold(handle, swparams, alsamm_period_size)); - snd_pcm_sw_params_get_silence_threshold(swparams, &ps); - if(debug&&sys_verbose) post("sw_params: set silence_threshold = %d (was %d)", (int) ps,(int)ops); - snd_pcm_sw_params_get_silence_size(swparams, &ops); - CHK(snd_pcm_sw_params_set_silence_size(handle, swparams, alsamm_period_size)); - snd_pcm_sw_params_get_silence_size(swparams, &ps); - if(debug&&sys_verbose) post("sw_params: set silence_size = %d (was %d)", (int) ps,(int)ops); - /* AVAIL: allow the transfer when at least period_size samples can be processed */ - snd_pcm_sw_params_get_avail_min(swparams, &ops); - CHK(snd_pcm_sw_params_set_avail_min(handle, swparams, sys_dacblocksize/2)); - snd_pcm_sw_params_get_avail_min(swparams, &ps); - if(debug&&sys_verbose) post("sw_params: set avail_min= %d (was %d)", (int) ps, (int) ops); - /* ALIGN: align all transfers to 1 sample */ - snd_pcm_sw_params_get_xfer_align(swparams, &ops); - CHK(snd_pcm_sw_params_set_xfer_align(handle, swparams, 1)); - snd_pcm_sw_params_get_xfer_align(swparams, &ps); - if(debug&&sys_verbose) post("sw_params: set xfer_align = %d (was %d)", (int) ps, (int) ops); - /* write the parameters to the playback device */ - CHK(snd_pcm_sw_params(handle, swparams)); - if(debug&&sys_verbose) post("set sw finished"); -#else - post("alsa: need version 1.0 or above for mmap operation"); -#endif /* ALSAAPI9 */ - return 0; - } catch (AlsaError e) {return e.err;} -} - -/* ALSA Transfer helps */ - -/* xrun_recovery is called if time to late or error - Note: use outhandle if synced i/o; the devices are linked so prepare has only be called on out, hopefully resume too... -*/ -static int xrun_recovery(snd_pcm_t *handle, int err) { - if (debug) alsamm_xruns++; /* count xruns */ - if (err == -EPIPE) { /* under-run */ - CH(snd_pcm_prepare(handle)); - CH(snd_pcm_start(handle)); - return 0; - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep(1); /* wait until the suspend flag is released */ - if (err < 0) { - CH(snd_pcm_prepare(handle)); - CH(snd_pcm_start(handle)); - } - return 0; - } - return err; -} - -/* note that snd_pcm_avail has to be called before using this funtion */ -static int alsamm_get_channels(snd_pcm_t *dev, snd_pcm_uframes_t *avail, snd_pcm_uframes_t *offset, int nchns, char **addr) { - int err = 0; - const snd_pcm_channel_area_t *mm_areas; - if (nchns>0 && avail && offset) { - err = snd_pcm_mmap_begin(dev, &mm_areas, offset, avail); - if (err<0) {check_error(err,"setmems: begin_mmap failure ???"); return err;} - for (int chn=0; chn<nchns; chn++) { - const snd_pcm_channel_area_t *a = &mm_areas[chn]; - addr[chn] = (char *) a->addr + ((a->first + a->step * *offset) / 8); - } - return err; - } - return -1; -} - -static void alsamm_start() { - int err = 0; - /* first prepare for in/out */ - for (int devno=0; devno<alsao.ndev; devno++) { - snd_pcm_uframes_t offset, avail; - t_alsa_dev *dev = &alsao.dev[devno]; - /* snd_pcm_prepare also in xrun, but cannot harm here */ - err = snd_pcm_prepare(dev->a_handle); - if (err<0) {check_error(err,"outcard prepare error for playback"); return;} - offset = 0; - avail = snd_pcm_avail_update(dev->a_handle); - if (avail != (snd_pcm_uframes_t) alsamm_buffer_size) { - check_error(avail,"full buffer not available at start"); - } - /* cleaning out mmap buffer before start */ - if(debug&&sys_verbose) post("start: set mems for avail=%ld,offset=%ld at buffersize=%ld",avail,offset,alsamm_buffer_size); - if(avail > 0) { - int comitted = 0; - err = alsamm_get_channels(dev->a_handle, &avail, &offset, dev->a_channels,dev->a_addr); - if (err<0) {check_error(err,"setting initial out channelspointer failure ?"); continue;} - for (int chn=0; chn<dev->a_channels; chn++) memset(dev->a_addr[chn],0,avail*ALSAMM_SAMPLEWIDTH_32); - comitted = snd_pcm_mmap_commit (dev->a_handle, offset, avail); - avail = snd_pcm_avail_update(dev->a_handle); - if(debug&&sys_verbose) post("start: now channels cleared, out with avail=%ld, offset=%ld,comitted=%d",avail,offset,comitted); - } - /* now start, should be autostarted */ - avail = snd_pcm_avail_update(dev->a_handle); - if(debug&&sys_verbose) post("start: finish start, out with avail=%ld, offset=%ld",avail,offset); - /* we have no autostart so anyway start*/ - err = snd_pcm_start (dev->a_handle); - if (err<0) check_error(err,"could not start playback"); - } - for (int devno=0; devno<alsai.ndev; devno++) { - snd_pcm_uframes_t ioffset, iavail; - t_alsa_dev *dev = &alsai.dev[devno]; - /* if devices are synced then don't need to prepare; hopefully dma in aereas allready filled correct by the card */ - if (dev->a_synced == 0) { - err = snd_pcm_prepare (dev->a_handle); - if (err<0) {check_error(err,"incard prepare error for capture"); /* return err;*/} - } - ioffset = 0; - iavail = snd_pcm_avail_update (dev->a_handle); - /* cleaning out mmap buffer before start */ - if (debug) post("start in: set in mems for avail=%ld,offset=%ld at buffersize=%ld",iavail,ioffset,alsamm_buffer_size); - if (iavail > (snd_pcm_uframes_t) 0) { - if (debug) post("empty buffer not available at start, since avail %ld != %ld buffersize",iavail,alsamm_buffer_size); - err = alsamm_get_channels(dev->a_handle, &iavail, &ioffset, dev->a_channels,dev->a_addr); - if (err<0) {check_error(err,"getting in channelspointer failure ????"); continue;} - snd_pcm_mmap_commit (dev->a_handle, ioffset, iavail); - iavail = snd_pcm_avail_update (dev->a_handle); - if (debug) post("start in now avail=%ld",iavail); - } - if (debug) post("start: init inchannels with avail=%ld, offset=%ld",iavail,ioffset); - /* if devices are synced then dont need to start */ - /* start with autostart , but anyway start */ - if(dev->a_synced == 0) { - err = snd_pcm_start (dev->a_handle); - if (err<0) {check_error(err,"could not start capture"); continue;} - } - } -} - -static void alsamm_stop() { - for (int devno=0; devno<alsai.ndev; devno++) { - t_alsa_dev *dev = &alsai.dev[devno]; if(sys_verbose) post("stop in device %d",devno); - CH(snd_pcm_drop(dev->a_handle)); - } - for (int devno=0; devno<alsao.ndev;devno++) { - t_alsa_dev *dev = &alsao.dev[devno]; if(sys_verbose) post("stop out device %d",devno); - CH(snd_pcm_drop(dev->a_handle)); - } - if (debug) show_availist(); -} - -/* ---------- ADC/DAC tranfer in the main loop ------- */ -/* I see: (a guess as a documentation) - all DAC data is in sys_soundout array with - sys_dacblocksize (mostly 64) for each channels which - if we have more channels opened then dac-channels = sys_outchannels - we have to zero (silence them), which should be done once. - -Problems to solve: - - a) Since in ALSA MMAP, the MMAP reagion can change (don't ask me why) - we have to do it each cycle or we say on RME HAMMERFALL/HDSP/DSPMADI - it never changes to it once. so maybe we can do it once in open - - b) we never know if inputs are synced and zero them if not, - except we use the control interface to check for, but this is - a systemcall we cannot afford in RT Loops so we just dont - and if not it will click... users fault ;-))) -*/ - -int alsamm_send_dacs() { - static double timenow,timelast; - t_sample *fpo, *fpi, *fp1, *fp2; - int i, err, devno; - snd_pcm_sframes_t size; - snd_pcm_sframes_t commitres; - snd_pcm_state_t state; - /* unused channels should be zeroed out on startup (open) and stay this */ - int inchannels = sys_inchannels; - int outchannels = sys_outchannels; - timelast = sys_getrealtime(); - if (debug) { - if(dac_send++ < 0) post("dac send called in %d, out %d, xrun %d",inchannels,outchannels, alsamm_xruns); - if(alsamm_xruns && (alsamm_xruns % 1000) == 0) post("1000 xruns accoured"); - if(dac_send < WATCH_PERIODS) { - out_cm[dac_send] = -1; - in_avail[dac_send] = out_avail[dac_send] = -1; - in_offset[dac_send] = out_offset[dac_send] = -1; - outaddr[dac_send] = inaddr[dac_send] = NULL; - xruns_watch[dac_send] = alsamm_xruns; - } - } - if (!inchannels && !outchannels) return SENDDACS_NO; - /* here we should check if in and out samples are here. - but, the point is if out samples available also in sample should, - so we don't make a precheck of insamples here and let outsample check be the first of the first card. */ - /* OUTPUT Transfer */ - fpo = sys_soundout; - for (int devno=0; devno<alsao.ndev; devno++) { - t_alsa_dev *dev = &alsao.dev[devno]; - snd_pcm_t *out = dev->a_handle; - int ochannels =dev->a_channels; - /* how much samples available ??? */ - snd_pcm_sframes_t ooffset=0, oavail=snd_pcm_avail_update(out); - /* only one reason i can think about, the driver stopped and says broken pipe - so this should not happen if we have enough stopthreshold but if try to restart with next commit */ - if (oavail<0) { - if (debug) broken_opipe++; - err = xrun_recovery(out, -EPIPE); - if (err < 0) {check_error(err,"otavail<0 recovery failed"); return SENDDACS_NO;} - oavail = snd_pcm_avail_update(out); - } - /* check if we are late and have to (able to) catch up */ - /* xruns will be ignored since you cant do anything since already happend */ - state = snd_pcm_state(out); - if (state == SND_PCM_STATE_XRUN) { - err = xrun_recovery(out, -EPIPE); if (err<0) {check_error(err,"DAC XRUN recovery failed" ); return SENDDACS_NO;} - oavail = snd_pcm_avail_update(out); - } else if (state == SND_PCM_STATE_SUSPENDED) { - err = xrun_recovery(out, -ESTRPIPE); if (err<0) {check_error(err,"DAC SUSPEND recovery failed"); return SENDDACS_NO;} - oavail = snd_pcm_avail_update(out); - } - if(debug && dac_send < WATCH_PERIODS) out_avail[dac_send] = oavail; - /* we only transfer transfersize of bytes request, this should only happen on first card otherwise we got a problem */ - if(oavail < sys_dacblocksize) return SENDDACS_NO; - /* transfer now */ - size = sys_dacblocksize; fp1 = fpo; - /* since this can go over a buffer boundery we maybe need two steps to transfer - (normally when buffersize is a multiple of transfersize this should never happen) */ - while (size>0) { - snd_pcm_sframes_t oframes = size; - err = alsamm_get_channels(out, (unsigned long *)&oframes, (unsigned long *)&ooffset,ochannels,dev->a_addr); - if(debug && dac_send < WATCH_PERIODS) {out_offset[dac_send] = ooffset; outaddr[dac_send] = (char *) dev->a_addr[0];} - if (err<0) { - err = xrun_recovery(out, err); - if (err<0) {check_error(err,"MMAP begins avail error"); break; /* next card please */} - } - /* transfer into memory */ - for (int chn=0; chn<ochannels; chn++) { - t_alsa_sample32 *buf = (t_alsa_sample32 *)dev->a_addr[chn]; - /* osc(buf, oframes, (dac_send%1000 < 500)?-100.0:-10.0,440,&(indexes[chn])); */ - for (i = 0, fp2 = fp1 + chn*sys_dacblocksize; i < oframes; i++,fp2++) { - /* better but slower, better never clip ;-) buf[i] = CLIP32(s1); */ - buf[i] = int(*fp2 * F32MAX) & 0xFFFFFF00; - *fp2 = 0.0; - } - } - commitres = snd_pcm_mmap_commit(out, ooffset, oframes); - if (commitres < 0 || commitres != oframes) { - err = xrun_recovery(out, commitres >= 0 ? -EPIPE : commitres); - if (err<0) {check_error(err,"MMAP commit error"); return SENDDACS_NO;} - } - if(debug && dac_send < WATCH_PERIODS) out_cm[dac_send] = oframes; - fp1 += oframes; - size -= oframes; - } /* while size */ - fpo += ochannels*sys_dacblocksize; - }/* for devno */ - fpi = sys_soundin; /* star first card first channel */ - for (devno=0; devno<alsai.ndev; devno++) { - t_alsa_dev *dev = &alsai.dev[devno]; - snd_pcm_t *in = dev->a_handle; - int ichannels = dev->a_channels; - snd_pcm_sframes_t ioffset=0, iavail=snd_pcm_avail_update(in); - if (iavail<0) { - err = xrun_recovery(in, iavail); - if (err<0) {check_error(err,"input avail update failed"); return SENDDACS_NO;} - iavail=snd_pcm_avail_update(in); - } - state = snd_pcm_state(in); - if (state == SND_PCM_STATE_XRUN) { - err = xrun_recovery(in, -EPIPE); if (err<0) {check_error(err,"ADC XRUN recovery failed" ); return SENDDACS_NO;} - iavail=snd_pcm_avail_update(in); - } else if (state == SND_PCM_STATE_SUSPENDED) { - err = xrun_recovery(in,-ESTRPIPE); if (err<0) {check_error(err,"ADC SUSPEND recovery failed"); return SENDDACS_NO;} - iavail=snd_pcm_avail_update(in); - } - /* only transfer full transfersize or nothing */ - if(iavail < sys_dacblocksize) return SENDDACS_NO; - size = sys_dacblocksize; - fp1 = fpi; - /* since sysdata can go over a driver buffer boundery we maybe need two steps to transfer - (normally when buffersize is a multiple of transfersize this should never happen) */ - while(size>0) { - snd_pcm_sframes_t iframes = size; - err = alsamm_get_channels(in, (unsigned long *)&iframes, (unsigned long *)&ioffset,ichannels,dev->a_addr); - if (err<0) { - err = xrun_recovery(in, err); - if (err<0) {check_error(err,"MMAP begins avail error"); return SENDDACS_NO;} - } - if(debug && dac_send < WATCH_PERIODS) {in_avail[dac_send] = iavail; in_offset[dac_send] = ioffset; inaddr[dac_send] = dev->a_addr[0];} - /* transfer into memory */ - for (int chn=0; chn<ichannels; chn++) { - t_alsa_sample32 *buf = (t_alsa_sample32 *) dev->a_addr[chn]; - for (i = 0, fp2 = fp1 + chn*sys_dacblocksize; i < iframes; i++,fp2++) { - /* mask the lowest bits, since subchannels info can make zero samples nonzero */ - *fp2 = float(t_alsa_sample32(buf[i]&0xFFFFFF00)) * (1.0/float(INT32_MAX)); - } - } - commitres = snd_pcm_mmap_commit(in, ioffset, iframes); - if (commitres < 0 || commitres != iframes) { - post("please never"); - err = xrun_recovery(in, commitres >= 0 ? -EPIPE : commitres); - if (err<0) {check_error(err,"MMAP synced in commit error"); return SENDDACS_NO;} - } - fp1 += iframes; - size -= iframes; - } - fpi += ichannels*sys_dacblocksize; - } /* for out devno < alsamm_outcards */ - timenow = sys_getrealtime(); - if (timenow > timelast+sleep_time) { - if(debug && dac_send < 10 && sys_verbose) - post("slept %f > %f + %f (=%f)", timenow,timelast,sleep_time,(timelast + sleep_time)); - return SENDDACS_SLEPT; - } - return SENDDACS_YES; -} diff --git a/desiredata/src/s_audio_asio.cpp b/desiredata/src/s_audio_asio.cpp deleted file mode 100644 index fde2891d..00000000 --- a/desiredata/src/s_audio_asio.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -/* Copyright (c) 2004, Tim Blechmann and others - * supported by vibrez.net - * For information on usage and redistribution, and for a DISCLAIMER OF ALL - * WARRANTIES, see the file, "LICENSE.txt" in this distribution. */ - -/* native ASIO interface for windows - * adapted from hostsample.cpp (ASIO SDK) - */ - -#ifdef MSW -#include "windows.h" /* for application window handle */ -#define IEEE754_64FLOAT 1 -#else -#error This is for MS Windows (Intel CPU architecture) only!! -#endif - -#ifdef _MSC_VER -#pragma warning( disable : 4091 ) -#endif - -#include "m_pd.h" -extern "C" { -#include "s_stuff.h" -#include "m_simd.h" -} - -#include "asio.h" /* steinberg's header file */ -#include "asiodrivers.h" /* ASIODrivers class */ -#include "asiosys.h" -#include "pthread.h" -#include "stdio.h" /* for sprintf */ - -#include <time.h> -#include <sys/timeb.h> - -#include "assert.h" -#define ASSERT assert - - -/* fast float to integer conversion adapted from Erik de Castro Lopo */ -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 -#include "math.h" - -// seconds to wait for driver to respond -#define DRIVERWAIT 1 - -#define ASIODEBUG - -/* public function prototypes */ -// extern "C" void asio_open_audio(int naudioindev, int *audioindev, int nchindev, -// int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int srate, int scheduler); -extern "C" void asio_close_audio(); -extern "C" void asio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize); -extern "C" int asio_send_dacs(); - -/* asio callback prototypes for traditional scheduling*/ -static void asio_bufferSwitch(long db_idx, ASIOBool directprocess); -static void asio_sampleRateDidChange(ASIOSampleRate srate); -static long asio_messages(long selector, long value, void* message, double* opt); -static ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess); - -/* asio callback prototypes for callback-based scheduling*/ -static void asio_bufferSwitch_cb(long db_idx, ASIOBool directprocess); -static void asio_sampleRateDidChange_cb(ASIOSampleRate srate); -static long asio_messages_cb(long selector, long value, void* message, double* opt); -static ASIOTime *asio_bufferSwitchTimeInfo_cb(ASIOTime *params, long db_idx, ASIOBool directprocess); - -static void float32tofloat32(void* inbuffer, void* outbuffer, long frames); -static void float32tofloat32_S(void* inbuffer, void* outbuffer, long frames); -static void float32tofloat64(void* inbuffer, void* outbuffer, long frames); -static void float64tofloat32(void* inbuffer, void* outbuffer, long frames); -static void float32toInt16(void* inbuffer, void* outbuffer, long frames); -static void Int16tofloat32(void* inbuffer, void* outbuffer, long frames); -static void float32toInt24(void* inbuffer, void* outbuffer, long frames); -static void Int24tofloat32(void* inbuffer, void* outbuffer, long frames); -static void float32toInt32(void* inbuffer, void* outbuffer, long frames); -static void Int32tofloat32(void* inbuffer, void* outbuffer, long frames); -static void float32toInt16_S(void* inbuffer, void* outbuffer, long frames); -static void Int16tofloat32_S(void* inbuffer, void* outbuffer, long frames); -static void float32toInt24_S(void* inbuffer, void* outbuffer, long frames); -static void Int24tofloat32_S(void* inbuffer, void* outbuffer, long frames); -static void float32toInt32_S(void* inbuffer, void* outbuffer, long frames); -static void Int32tofloat32_S(void* inbuffer, void* outbuffer, long frames); -void asio_close_audio(void); - -typedef void converter_t(void* inbuffer, void* outbuffer, long frames); - -/* sample converting helper functions: - * - global send / receive functions - * - sample conversion functions (adapted from ASIOConvertSamples.cpp */ -static converter_t *asio_converter_send (ASIOSampleType format); -static converter_t *asio_converter_receive (ASIOSampleType format); - -/* pointers to the converter functions of each channel are stored here */ -static converter_t **asio_converter = NULL; - -/* function to get sample width of data according to ASIOSampleType */ -static int asio_get_samplewidth(ASIOSampleType format); - -/* that's the sample width in bytes (per output channel) - - * it's only for silence when stopping the driver.... (please find a better solution) */ -static int *asio_samplewidth = NULL; - - -/* some local helper functions */ -static void prepare_asio_drivernames(); - -/* system dependent helper functions */ -static unsigned long get_sys_reference_time(); - -/* global storage */ -static ASIODriverInfo * asio_driver = NULL; -static ASIOBufferInfo * asio_bufferinfo = NULL; -static ASIOChannelInfo* asio_channelinfo = NULL; -static AsioTimeInfo * asio_timerinfo = NULL; -static ASIOCallbacks asio_callbacks; -extern AsioDrivers * asioDrivers; /* declared in asiodrivers.cpp */ - -static char ** asio_drivernames = NULL; - -static ASIOSampleRate asio_srate; -static long asio_inchannels; -static long asio_outchannels; - -static long asio_minbufsize; -static long asio_maxbufsize; -static long asio_prefbufsize; -static long asio_granularity; -static unsigned char asio_useoutputready; -static long asio_inputlatency; -static long asio_outputlatency; - -static long asio_bufsize; /* hardware buffer size */ -static long asio_ticks_per_callback; - -unsigned long sys_reftime; - -/* ringbuffer stuff */ -static t_sample ** asio_ringbuffer = NULL; /* ringbuffers */ -static int asio_ringbuffer_inoffset; /* ringbuffer(in) pointer offset for dac */ -static int asio_ringbuffer_outoffset; /* ringbuffer(out) pointer offset */ -static int asio_ringbuffer_length; /* latency - hardware latency in samples*/ - -/* i hope we can remove this to use callback based dsp scheduling */ -static pthread_mutex_t asio_ringbuf_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t asio_ringbuf_cond = PTHREAD_COND_INITIALIZER; - -/* some global definitions: */ -#define ASIOVERSION 2 /* i hope we are compatible with asio 2 */ - -/* definitions from s_audio.c ... it should be save to use them */ -#define DEVDESCSIZE 80 -#define MAXNDEV 20 - -/* from m_sched.c: */ -extern "C" double sys_time_per_dsp_tick; -extern "C" double sys_time; - - -/**************************************************************************/ -/* some function pointers for eventual fast copying when SIMD is possible */ - -static void (*copyblock)(t_sample *dst,t_sample *src,int n); -static void (*zeroblock)(t_sample *dst,int n); -static t_int *(*clipblock)(t_int *w); - -static void copyvec_nrm(t_sample *dst,t_sample *src,int n) { memcpy(dst,src,n*sizeof(t_sample)); } -static void zerovec_nrm(t_sample *dst,int n) { memset(dst,0,n*sizeof(t_sample)); } - -/*************************************************************************/ - - -/* open asio interface */ -/* todo: some more error messages */ -void asio_open_audio(int naudioindev, int *audioindev, int nchindev, -int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int srate, int scheduler) { - ASIOError status = ASE_OK; - ASIOBufferInfo * buffers = NULL; - int i; - int channels; - -#ifdef IEEE754_64FLOAT - asio_srate=(ASIOSampleRate)srate; -#else - sprintf(asio_srate,"%8d",srate); -#endif - /* check, if the driver is still running */ - if(asio_driver) asio_close_audio(); - /* check, if we use the first asio device */ - prepare_asio_drivernames(); - asioDrivers->getDriverNames(asio_drivernames,MAXNDEV); - - try { - asioDrivers->loadDriver(asio_drivernames[*audioindev]); - } - catch(...) { - error("ASIO: Error loading driver"); - goto bailout; - } - /* initialize ASIO */ - asio_driver = (ASIODriverInfo*) getbytes (sizeof(ASIODriverInfo)); - asio_driver->asioVersion = ASIOVERSION; - asio_driver->sysRef = GetDesktopWindow(); - status = ASIOInit(asio_driver); -#ifdef ASIODEBUG - post("sysRef: %x", asio_driver->sysRef); - post("asioversion: %d", asio_driver->asioVersion); - post("driverversion: %d", asio_driver->driverVersion); - post("name: %s", asio_driver->name); -#endif - - switch (status) { - if(status) post("error: %s", asio_driver->errorMessage); - case ASE_NotPresent: error("ASIO: ASE_NotPresent"); goto bailout; - case ASE_NoMemory: error("ASIO: ASE_NoMemory"); goto bailout; - case ASE_HWMalfunction: error("ASIO: ASE_HWMalfunction"); goto bailout; - } -#ifdef ASIODEBUG - post("ASIO initialized successfully"); -#endif - - - /* query driver */ - status = ASIOGetChannels(&asio_inchannels, &asio_outchannels); - if(status != ASE_OK) { - error("ASIO: Couldn't get channel count"); - goto bailout; - } - -#ifdef ASIODEBUG - post ("ASIOGetChannels\tinputs: %d, outputs: %d", asio_inchannels, - asio_outchannels); -#endif - - sys_inchannels = *chindev <= asio_inchannels ? *chindev : asio_inchannels; - sys_outchannels = *choutdev <= asio_outchannels ? *choutdev : asio_outchannels; - channels = sys_inchannels + sys_outchannels; - status = ASIOGetBufferSize(&asio_minbufsize, &asio_maxbufsize, &asio_prefbufsize, &asio_granularity); - if(status != ASE_OK) { - error("ASIO: Couldn't get buffer size"); - goto bailout; - } -#ifdef ASIODEBUG - post ("ASIOGetBufferSize\tmin: %d, max: %d, preferred: %d, granularity: " - "%d", asio_minbufsize, asio_maxbufsize, asio_prefbufsize, - asio_granularity); -#endif - - /* todo: buffer size hardcoded to asio hardware */ - asio_bufsize = asio_prefbufsize; - if (scheduler) { - if ( asio_bufsize % sys_dacblocksize == 0 ) { - /* use callback scheduler */ - sys_setscheduler(1); - asio_ticks_per_callback = asio_bufsize / sys_dacblocksize; - post("ASIO: using callback-based scheduler"); - } - } else post("ASIO: using traditional scheduler"); - /* try to set sample rate */ - if(ASIOCanSampleRate( asio_srate ) != ASE_OK) { - error ("Samplerate not supported, using default"); -#ifdef IEEE754_64FLOAT - asio_srate = (ASIOSampleRate)44100.0; -#else - sprintf(&asio_srate,"%8d",44100); -#endif - srate=44100; - } - - status = ASIOSetSampleRate( asio_srate ); - if(status != ASE_OK) -#ifdef IEEE754_64FLOAT - post("Setting ASIO sample rate to %lg failed... is the device in slave sync mode?", (double)asio_srate); -#else - post("Setting ASIO sample rate to %s failed... is the device in slave sync mode?", asio_srate); -#endif - - if(ASIOOutputReady() == ASE_OK) - asio_useoutputready = 1; - else - asio_useoutputready = 0; - - - /* set callbacks */ - if(sys_callbackscheduler) { - asio_callbacks.bufferSwitch = &asio_bufferSwitch_cb; - asio_callbacks.sampleRateDidChange = &asio_sampleRateDidChange_cb; - asio_callbacks.asioMessage = &asio_messages_cb; - asio_callbacks.bufferSwitchTimeInfo = &asio_bufferSwitchTimeInfo_cb; - } else { - asio_callbacks.bufferSwitch = &asio_bufferSwitch; - asio_callbacks.sampleRateDidChange = &asio_sampleRateDidChange; - asio_callbacks.asioMessage = &asio_messages; - asio_callbacks.bufferSwitchTimeInfo = &asio_bufferSwitchTimeInfo; - } - /* prepare, create and set up buffers */ - asio_bufferinfo = (ASIOBufferInfo*) getbytes (channels*sizeof(ASIOBufferInfo)); - asio_channelinfo = (ASIOChannelInfo*) getbytes(channels*sizeof(ASIOChannelInfo)); - if (!(asio_bufferinfo && asio_channelinfo)) { - error("ASIO: couldn't allocate buffer or channel info"); - goto bailout; - } - - for (i = 0; i != sys_inchannels + sys_outchannels; ++i) { - if (i < sys_outchannels) { - asio_bufferinfo[i].isInput = ASIOFalse; - asio_bufferinfo[i].channelNum = i; - asio_bufferinfo[i].buffers[0] = asio_bufferinfo[i].buffers[1] = 0; - } else { - asio_bufferinfo[i].isInput = ASIOTrue; - asio_bufferinfo[i].channelNum = i - sys_outchannels; - asio_bufferinfo[i].buffers[0] = asio_bufferinfo[i].buffers[1] = 0; - } - } - status = ASIOCreateBuffers(asio_bufferinfo, sys_inchannels + sys_outchannels, asio_bufsize, &asio_callbacks); - if(status != ASE_OK) { - error("ASIO: couldn't allocate buffers"); - goto bailout; - } -#ifdef ASIODEBUG - post("ASIO: buffers allocated"); -#endif - - asio_converter = (converter_t **)getbytes(channels * sizeof (converter_t *)); - asio_samplewidth = (int *)getbytes((sys_outchannels + sys_inchannels) * sizeof (int)); - for (i = 0; i != sys_outchannels + sys_inchannels; ++i) { - asio_channelinfo[i].channel = asio_bufferinfo[i].channelNum; - asio_channelinfo[i].isInput = asio_bufferinfo[i].isInput; - ASIOGetChannelInfo(&asio_channelinfo[i]); - -#ifdef ASIODEBUG - post("ASIO: channel %d type %d", i, asio_channelinfo[i].type); -#endif - asio_samplewidth[i] = asio_get_samplewidth(asio_channelinfo[i].type); - if (i < sys_outchannels) asio_converter[i] = asio_converter_send( asio_channelinfo[i].type); - else asio_converter[i] = asio_converter_receive(asio_channelinfo[i].type); - } - - /* get latencies */ - ASIOGetLatencies(&asio_inputlatency, &asio_outputlatency); -#ifdef ASIODEBUG - post("ASIO: input latency: %d, output latency: %d",asio_inputlatency, asio_outputlatency); -#endif - - - /* we need a ringbuffer if we use the traditional scheduler */ - if (!sys_callbackscheduler) { - /* a strange way to find the least common multiple, but works, since sys_dacblocksize (expt 2 x) */ - asio_ringbuffer_length = asio_bufsize * sys_dacblocksize; - while ( !(asio_ringbuffer_length % sys_dacblocksize) && !(asio_ringbuffer_length % asio_bufsize)) { - asio_ringbuffer_length /= 2; - } - asio_ringbuffer_length *= 2; -#ifdef ASIODEBUG - post("ASIO: ringbuffer size: %d",asio_ringbuffer_length); -#endif - /* allocate ringbuffer */ - asio_ringbuffer = (t_sample**) getbytes (channels * sizeof (t_sample*)); - for (i = 0; i != channels; ++i) { - asio_ringbuffer[i] = (t_sample*)getalignedbytes(asio_ringbuffer_length * sizeof (t_sample)); - if (!asio_ringbuffer[i]) - error("ASIO: couldn't allocate ASIO ringbuffer"); - memset(asio_ringbuffer[i], 0, asio_ringbuffer_length * sizeof (t_sample)); - } - /* initialize ringbuffer pointers */ - asio_ringbuffer_inoffset = asio_ringbuffer_outoffset = 0; - } - if(ASIOStart() != ASE_OK) goto bailout; - /* set block copy/zero/clip functions */ - if(SIMD_CHKCNT(sys_dacblocksize) && simd_runtime_check()) { - // urgh... ugly cast - copyblock = (void (*)(t_sample *,t_sample *,int))©vec_simd; - zeroblock = &zerovec_simd; - clipblock = &clip_perf_simd; - } else { - copyblock = ©vec_nrm; - zeroblock = &zerovec_nrm; - clipblock = &clip_perform; - } - - post("ASIO: started"); - return; - -bailout: - if(status) post("error: %s", asio_driver->errorMessage); - post("ASIO: couldn't start"); - asio_close_audio(); - return; -} - - - -/* stop asio, free buffers and close asio interface */ -void asio_close_audio() { - if (asio_driver) { - pthread_cond_broadcast(&asio_ringbuf_cond); - - ASIOError status; - int channels = sys_inchannels + sys_outchannels; - int i; - - if(asio_useoutputready) { - // the DMA buffers would be played past ASIOStop - // -> clear output buffers and notify driver -#if 0 - if(asio_ringbuffer) { - // slow, blocking method - for(i = 0; i != sys_outchannels; ++i) - zerovec_simd(asio_ringbuffer[i], asio_ringbuffer_length); - // wait for bufferswitch to process silence (twice) - pthread_cond_wait(&asio_ringbuf_cond, &asio_ringbuf_mutex); - for(i = 0; i != sys_outchannels; ++i) memset(asio_ringbuffer[i], 0, asio_ringbuffer_length * sizeof (t_sample)); - pthread_cond_wait(&asio_ringbuf_cond, &asio_ringbuf_mutex); - } -#else - // direct method - clear both hardware buffers - if(asio_bufferinfo && asio_samplewidth) { - for(i = 0; i < sys_outchannels; ++i) { - long bytes = asio_bufsize*asio_samplewidth[i]; - memset(asio_bufferinfo[i].buffers[0],0,bytes); - memset(asio_bufferinfo[i].buffers[1],0,bytes); - } - } - // notify driver - status = ASIOOutputReady(); -#endif - } - - status = ASIOStop(); - if(status == ASE_OK) post("ASIO: stopped"); - status = ASIODisposeBuffers(); - try { - // ASIOExit can crash if driver not really running - status = ASIOExit(); - } catch(...) {} - // deallocate all memory - if(asio_ringbuffer) { - for(i = 0; i < channels; i++) - if(asio_ringbuffer[i]) freealignedbytes(asio_ringbuffer[i],asio_ringbuffer_length * sizeof (t_sample)); - freebytes(asio_ringbuffer, channels * sizeof (t_sample *)); - asio_ringbuffer = NULL; - } - - if(asio_bufferinfo) { - freebytes(asio_bufferinfo, channels * sizeof (ASIOBufferInfo)); - asio_bufferinfo = NULL; - } - if(asio_channelinfo) { - freebytes(asio_channelinfo, channels * sizeof (ASIOChannelInfo)); - asio_channelinfo = NULL; - } - if(asio_converter) { - freebytes(asio_converter, channels * sizeof (converter_t *)); - asio_converter = NULL; - } - if(asio_samplewidth) { - freebytes(asio_samplewidth, (sys_outchannels + sys_inchannels) * sizeof (int)); - asio_samplewidth = NULL; - } - freebytes(asio_driver, sizeof (ASIODriverInfo)); - asio_driver = NULL; - /* leave the scheduler and return to traditional mode */ - if (sys_callbackscheduler) sys_setscheduler(0); - } -} - -void asio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - prepare_asio_drivernames(); - *canmulti = 0; /* we will only support one asio device */ - *nindevs = *noutdevs = (int)asioDrivers->getDriverNames(asio_drivernames, maxndev); - for(int i = 0; i!= *nindevs; ++i) { - sprintf(indevlist + i * devdescsize, "%s", asio_drivernames[i]); - sprintf(outdevlist + i * devdescsize, "%s", asio_drivernames[i]); - } -} - -/* called on every dac~ send */ -int asio_send_dacs() { - t_sample * sp; /* sample pointer */ - int i, j; - double timenow; - double timeref = sys_getrealtime(); -#ifdef ASIODEBUG - if (!asio_driver) { - static int written = 0; - if(written%100 == 0) error("ASIO not running"); - written++; - return SENDDACS_NO; - } - -#endif - - /* send sound to ringbuffer */ - sp = sys_soundout; - for (i = 0; i < sys_outchannels; i++) { - t_float lo = -1.f; - t_float hi = 1.f; - t_int clipargs[6]; - clipargs[1] = (t_int)sp; - clipargs[2] = (t_int)(asio_ringbuffer[i] + asio_ringbuffer_inoffset); - clipargs[3] = (t_int)&lo; - clipargs[4] = (t_int)&hi; - clipargs[5] = (t_int)sys_dacblocksize; - clipblock(clipargs); - zeroblock(sp,sys_dacblocksize); - sp+=sys_dacblocksize; - } - /* get sound from ringbuffer */ - sp = sys_soundin; - for (j = 0; j < sys_inchannels; j++) { -#if 0 - /* we should be able to read from the ringbuffer on a different position - * to reduce latency for asio buffer sizes that aren't multiples of 64... */ - int offset = asio_bufsize + sys_dacblocksize; - offset += sys_dacblocksize - offset % sys_dacblocksize; - if (asio_ringbuffer_inoffset < offset) { - memcpy(sp, asio_ringbuffer[i+j] + asio_ringbuffer_length + - asio_ringbuffer_inoffset - offset, 64 *sizeof(t_sample)); - } else memcpy(sp, asio_ringbuffer[i+j] + asio_ringbuffer_inoffset - offset, 64*sizeof(t_sample)); -#else - /* working but higher latency */ - copyblock(sp, asio_ringbuffer[i+j] + asio_ringbuffer_inoffset,sys_dacblocksize); -#endif - sp+=sys_dacblocksize; - } - asio_ringbuffer_inoffset += sys_dacblocksize; -#if 1 - // blocking method - if (asio_ringbuffer_inoffset >= asio_ringbuffer_outoffset + asio_bufsize) { - struct timespec tm; - _timeb tmb; - _ftime(&tmb); - tm.tv_nsec = tmb.millitm*1000000; - tm.tv_sec = tmb.time+DRIVERWAIT; // delay - if(pthread_cond_timedwait(&asio_ringbuf_cond, &asio_ringbuf_mutex, &tm) == ETIMEDOUT) { - error("ASIO: ASIO driver non-responsive! - closing"); - asio_close_audio(); - return SENDDACS_SLEPT; - } - if (asio_ringbuffer_inoffset == asio_ringbuffer_length) { - asio_ringbuffer_outoffset = 0; - asio_ringbuffer_inoffset = 0; - } else asio_ringbuffer_outoffset += asio_bufsize; - } - if ((timenow = sys_getrealtime()) - timeref > 0.002) { - return SENDDACS_SLEPT; - } -#else - // non-blocking... let PD wait -> doesn't work! - if (asio_ringbuffer_inoffset >= asio_ringbuffer_outoffset + asio_bufsize) return SENDDACS_NO; - if (asio_ringbuffer_inoffset == asio_ringbuffer_length) { - asio_ringbuffer_outoffset = 0; - asio_ringbuffer_inoffset = 0; - } else asio_ringbuffer_outoffset += asio_bufsize; -#endif - return SENDDACS_YES; -} - -/* buffer switch callback */ -static void asio_bufferSwitch(long db_idx, ASIOBool directprocess) { - ASIOTime time; -#ifdef ASIODEBUG - static int written = 0; - if(written == 0) { - post("ASIO: asio_bufferSwitch_cb"); - written = 1; - } -#endif - memset (&time, 0, sizeof (time)); - /* todo: do we need to syncronize with other media ??? */ - asio_bufferSwitchTimeInfo(&time, db_idx, directprocess); -} - -/* sample rate change callback */ -static void asio_sampleRateDidChange(ASIOSampleRate srate) { - asio_srate = srate; -#ifdef ASIODEBUG - post("sample rate changed"); -#endif -} - -/* asio messaging callback */ -static long asio_messages(long selector, long value, void* message, double* opt) { - switch (selector) { - case kAsioSelectorSupported: - if (value == kAsioResetRequest || value == kAsioSupportsTimeInfo) return 1L; - return 0L; - case kAsioEngineVersion: - return ASIOVERSION; - case kAsioResetRequest: - /* how to handle this without changing the dsp scheduler? */ - post("ASIO: Reset request"); - return 1L; - case kAsioBufferSizeChange: - /* todo */ - post("ASIO: Buffer size changed"); - sys_reopen_audio(); - return 1L; - case kAsioResyncRequest: - post("ASIO: Resync request"); - return 0L; - case kAsioLatenciesChanged: - /* we are not handling the latencies atm */ - return 0L; - case kAsioSupportsTimeInfo: - return 1L; - case kAsioSupportsTimeCode: - /* we don't support that atm */ - return 0L; - } - return 0L; -} - -static ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess) { - /* todo: i'm not sure if we'll have to synchronize with other media ... probably yes ... */ - /* sys_reftime = get_sys_reference_time(); */ - /* perform the processing */ - int timeout = sys_dacblocksize * (float)asio_ticks_per_callback / (float) sys_dacsr * 1e6; - if (sys_timedlock(timeout) == ETIMEDOUT) /* we're late */ { - post("timeout %d", timeout); - sys_log_error(ERR_SYSLOCK); - return 0; - } - for (long i = 0; i < sys_outchannels + sys_inchannels; i++) { - if(asio_converter[i]) - if (asio_bufferinfo[i].isInput != ASIOTrue) { - asio_converter[i](asio_ringbuffer[i]+asio_ringbuffer_outoffset, - asio_bufferinfo[i].buffers[db_idx], asio_bufsize); - } - else /* these are the input channels */ { - asio_converter[i](asio_bufferinfo[i].buffers[db_idx], - asio_ringbuffer[i]+asio_ringbuffer_outoffset, asio_bufsize); - } - } - pthread_cond_broadcast(&asio_ringbuf_cond); - sys_unlock(); - if(asio_useoutputready) ASIOOutputReady(); - return 0L; /* time info!!! */ -} - -/* get system reference time on both platforms */ -static unsigned long get_sys_reference_time() { -#if WINDOWS - return timeGetTime(); -#elif MAC - static const double twoRaisedTo32 = 4294967296.; - UnsignedWide ys; - Microseconds(&ys); - double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo); - return (unsigned long)(r / 1000.); -#endif -} - -/* sample converting helper functions */ -static converter_t *asio_converter_send(ASIOSampleType format) { -#ifdef ASIODEBUG - /* post("ASIO: Sample Type %d", format); */ -#endif - switch (format) { - case ASIOSTInt16LSB: return float32toInt16; - case ASIOSTInt24LSB: return float32toInt24; // used for 20 bits as well - case ASIOSTInt32LSB: return float32toInt32; - case ASIOSTInt16MSB: return float32toInt16_S; - case ASIOSTInt24MSB: return float32toInt24_S; // used for 20 bits as well - case ASIOSTInt32MSB: return float32toInt32_S; - case ASIOSTFloat32LSB:return float32tofloat32; // IEEE 754 32 bit float, as found on Intel x86 architecture - case ASIOSTFloat32MSB:return float32tofloat32_S; - case ASIOSTFloat64LSB:return float32tofloat64; // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - default: - post("Output sample Type %d not supported, yet!!!",format); - return NULL; - } -} - -static converter_t *asio_converter_receive (ASIOSampleType format) { -#ifdef ASIODEBUG - /* post("ASIO: Sample Type %d", format); */ -#endif - switch (format) { - case ASIOSTInt16LSB: return Int16tofloat32; - case ASIOSTInt24LSB: return Int24tofloat32; // used for 20 bits as well - case ASIOSTInt32LSB: return Int32tofloat32; - case ASIOSTInt16MSB: return Int16tofloat32_S; - case ASIOSTInt24MSB: return Int24tofloat32_S; // used for 20 bits as well - case ASIOSTInt32MSB: return Int32tofloat32_S; - case ASIOSTFloat32MSB:return float32tofloat32_S; // IEEE 754 32 bit float, as found on Intel x86 architecture - case ASIOSTFloat32LSB:return float32tofloat32; // IEEE 754 32 bit float, as found on Intel x86 architecture - case ASIOSTFloat64LSB:return float64tofloat32; // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32LSB16: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - default: - post("Input sample Type %d not supported, yet!!!",format); - return NULL; - } -} - -static int asio_get_samplewidth(ASIOSampleType format) { - switch (format) { - case ASIOSTInt16LSB: case ASIOSTInt16MSB: return 2; - case ASIOSTInt24LSB: case ASIOSTInt24MSB: return 3; - case ASIOSTFloat32LSB:case ASIOSTFloat32MSB: - case ASIOSTInt32LSB: case ASIOSTInt32MSB: - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32LSB16: - case ASIOSTInt32LSB18: - case ASIOSTInt32LSB20: - case ASIOSTInt32LSB24: - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - case ASIOSTInt32MSB16: - case ASIOSTInt32MSB18: - case ASIOSTInt32MSB20: - case ASIOSTInt32MSB24: - return 4; - case ASIOSTFloat64MSB: - case ASIOSTFloat64LSB: - return 8; - default: - post("Input sample Type %d not supported, yet!!!",format); - return 0; - } -} - -/* dithering algo taken from Portaudio ASIO implementation */ -/************************************************************* -** Calculate 2 LSB dither signal with a triangular distribution. -** Ranged properly for adding to a 32 bit integer prior to >>15. -*/ -#define DITHER_BITS (15) -#define DITHER_SCALE (1.0f / ((1<<DITHER_BITS)-1)) -inline static long triangulardither() { - static unsigned long previous = 0; - static unsigned long randSeed1 = 22222; - static unsigned long randSeed2 = 5555555; - long current, highPass; -/* Generate two random numbers. */ - randSeed1 = (randSeed1 * 196314165) + 907633515; - randSeed2 = (randSeed2 * 196314165) + 907633515; -/* Generate triangular distribution about 0. */ - current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS)); - /* High pass filter to reduce audibility. */ - highPass = current - previous; - previous = current; - return highPass; -} - -/* sample conversion functions */ - -#define SCALE_INT16 32767.f /* (- (expt 2 15) 1) */ -#define SCALE_INT24 8388607.f /* (- (expt 2 23) 1) */ -#define SCALE_INT32 2147483647.f /* (- (expt 2 31) 1) */ - -/* Swap LSB to MSB and vice versa */ -inline __int32 swaplong(__int32 v) { - return ((v>>24)&0xFF)|((v>>8)&0xFF00)|((v&0xFF00)<<8)|((v&0xFF)<<24); -} - -inline __int16 swapshort(__int16 v) { - return ((v>>8)&0xFF)|((v&0xFF)<<8); -} - -/* todo: check dithering */ - -static void float32tofloat32(void* inbuffer, void* outbuffer, long frames) { - if(SIMD_CHECK2(frames,inbuffer,outbuffer)) copyvec_simd((float *)outbuffer,(float *)inbuffer,frames); - else memcpy (outbuffer, inbuffer, frames* sizeof (float)); -} - -static void float32tofloat32_S(void* inbuffer, void* outbuffer, long frames) { - __int32 *in = (__int32 *)inbuffer; - __int32* out = (__int32*)outbuffer; - while (frames--) *out++ = swaplong(*(in++)); -} - -static void float32tofloat64(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - double* out = (double*)outbuffer; - while (frames--) *(out++) = *(in++); -} - -static void float64tofloat32(void* inbuffer, void* outbuffer, long frames) { - const double *in = (const double *)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = *(in++); -} - -static void float32toInt16(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - __int16* out = (__int16*)outbuffer; - while (frames--) { - float o = *(in++) * SCALE_INT16 + triangulardither() * DITHER_SCALE; - __int16 lng = lrintf(o); - *out++ = lng ; - } -} - -static void Int16tofloat32(void* inbuffer, void* outbuffer, long frames) { - const __int16* in = (const __int16*)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = (float)*(in++) * (1.f / SCALE_INT16); -} - -static void float32toInt24(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - __int32* out = (__int32*)outbuffer; - while (frames--) { - float o = *(in++) * SCALE_INT24; - __int32 intg = (__int32)lrintf(o); - *(out++) = intg; - } -} - -static void Int24tofloat32(void* inbuffer, void* outbuffer, long frames) { - const __int32* in = (const __int32*)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = (float)*(in++) * (1.f / SCALE_INT24); -} - -static void float32toInt32(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - __int32* out = (__int32*)outbuffer; - while (frames--) { - float o = (float)*(in++) * SCALE_INT32 + triangulardither() * DITHER_SCALE; - *out++ = lrintf(o); - } -} - -static void Int32tofloat32(void* inbuffer, void* outbuffer, long frames) { - const __int32* in = (const __int32*)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = (float)*(in++) * (1.f / SCALE_INT32); -} - -static void float32toInt16_S(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - __int16* out = (__int16*)outbuffer; - while (frames--) { - float o = (float)*(in++) * SCALE_INT16 + triangulardither() * DITHER_SCALE; - __int16 reverse = (__int16)lrintf(o); - *out++ = swapshort(reverse); - } -} - -static void Int16tofloat32_S(void* inbuffer, void* outbuffer, long frames) { - const __int16* in = (const __int16*)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = (float)swapshort(*(in++)) * (1.f / SCALE_INT16); -} - -static void float32toInt24_S(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - char* out = (char*)outbuffer; - while (frames--) { - float o = (float)*(in++) * SCALE_INT24; - __int32 reverse = (__int32)lrintf(o); - out[2] = ((char *)&reverse)[0]; - out[1] = ((char *)&reverse)[1]; - out[0] = ((char *)&reverse)[2]; - out += 3; - } -} - -static void Int24tofloat32_S(void* inbuffer, void* outbuffer, long frames) { - const char* in = (const char*)inbuffer; - float *out = (float *)outbuffer; - __int32 d = 0; - while (frames--) { - ((char *)&d)[1] = in[2]; - ((char *)&d)[2] = in[1]; - ((char *)&d)[3] = in[0]; - *(out++) = (float)d * (1.f / SCALE_INT24); - in += 3; - } -} - -static void float32toInt32_S(void* inbuffer, void* outbuffer, long frames) { - const float *in = (const float *)inbuffer; - __int32* out = (__int32*)outbuffer; - while (frames--) { - float o = (float)*(in++) * SCALE_INT32 + triangulardither() * DITHER_SCALE; - __int32 reverse = (__int32)lrintf(o); - *out++ = swaplong(reverse); - } -} - -static void Int32tofloat32_S(void* inbuffer, void* outbuffer, long frames) { - const __int32* in = (const __int32*)inbuffer; - float *out = (float *)outbuffer; - while (frames--) *(out++) = (float)swaplong(*(in++)) * (1.f / SCALE_INT32); -} - - -/* some local helper functions */ -static void prepare_asio_drivernames() { - if (!asio_drivernames) { - asio_drivernames = (char**)getbytes(MAXNDEV * sizeof(char*)); - for (int i = 0; i!= MAXNDEV; ++i) { - asio_drivernames[i] = (char*)getbytes (32 * sizeof(char)); - } - } - /* load the driver */ - if (!asioDrivers) asioDrivers = new AsioDrivers(); - return; -} - -/* callback-based scheduling callbacks: */ - -/* buffer switch callback */ -static void asio_bufferSwitch_cb(long db_idx, ASIOBool directprocess) { - ASIOTime time; -#ifdef ASIODEBUG - static int written = 0; - if(written == 0) { - post("ASIO: asio_bufferSwitch_cb"); - written = 1; - } -#endif - memset (&time, 0, sizeof (time)); - /* todo: do we need to syncronize with other media ??? */ - asio_bufferSwitchTimeInfo_cb(&time, db_idx, directprocess); -} - -/* sample rate change callback */ -static void asio_sampleRateDidChange_cb(ASIOSampleRate srate) { - asio_sampleRateDidChange(srate); -} - -/* asio messaging callback */ -static long asio_messages_cb(long selector, long value, void* message, double* opt) { - return asio_messages(selector, value, message, opt); -} - -static ASIOTime *asio_bufferSwitchTimeInfo_cb(ASIOTime *params, long db_idx, ASIOBool directprocess) { - /* todo: i'm not sure if we'll have to synchronize with other media ... probably yes ... */ - /* perform the processing */ - int timeout = sys_dacblocksize * (float)asio_ticks_per_callback / (float) sys_dacsr * 1e6; - if (sys_timedlock(timeout) == ETIMEDOUT) - /* we're late ... lets hope that jack doesn't kick us out */ - return 0; - - for (int j = 0; j != asio_ticks_per_callback; j++) { - t_sample * sp = sys_soundin; - /* get sounds from input channels */ - for (long i = 0; i < sys_outchannels + sys_inchannels; i++) { - if(asio_converter[i]) - if (asio_bufferinfo[i].isInput == ASIOTrue) { - asio_converter[i]((char*)asio_bufferinfo[i].buffers[db_idx] + - asio_samplewidth[i] * j *sys_dacblocksize, sp, sys_dacblocksize); - sp += sys_dacblocksize; - } - } - /* run dsp */ - sched_tick(sys_time + sys_time_per_dsp_tick); - sp = sys_soundout; - /* send sound to hardware */ - for (long i = 0; i < sys_outchannels + sys_inchannels; i++) { - if (asio_bufferinfo[i].isInput != ASIOTrue) { - /* clip */ - t_float lo = -1.f; - t_float hi = 1.f; - t_int clipargs[6]; - clipargs[1] = clipargs[2] = (t_int)sp; - clipargs[3] = (t_int)&lo; - clipargs[4] = (t_int)&hi; - clipargs[5] = (t_int)sys_dacblocksize; - clipblock(clipargs); - /* send */ - if(asio_converter[i]) - asio_converter[i](sp, (char*)asio_bufferinfo[i].buffers[db_idx] - + asio_samplewidth[i] * j *sys_dacblocksize, sys_dacblocksize); - zeroblock(sp,sys_dacblocksize); - sp += sys_dacblocksize; - } - } - } - if(asio_useoutputready) ASIOOutputReady(); - sys_unlock(); - return 0L; /* time info!!! */ -} - -t_audioapi asio_api = { - asio_open_audio, - asio_close_audio, - asio_send_dacs, - asio_getdevs, -}; diff --git a/desiredata/src/s_audio_jack.c b/desiredata/src/s_audio_jack.c deleted file mode 100644 index 8f851e2c..00000000 --- a/desiredata/src/s_audio_jack.c +++ /dev/null @@ -1,354 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include "m_simd.h" -#include <jack/jack.h> -#include <regex.h> -#include <errno.h> -#define MAX_CLIENTS 100 -#define NUM_JACK_PORTS 32 -#define BUF_JACK 4096 -static jack_nframes_t jack_out_max; -#define JACK_OUT_MAX 64 -static jack_nframes_t jack_filled = 0; -static float jack_outbuf[NUM_JACK_PORTS*BUF_JACK]; -static float jack_inbuf[NUM_JACK_PORTS*BUF_JACK]; -static int jack_started = 0; -static jack_port_t * input_port[NUM_JACK_PORTS]; -static jack_port_t *output_port[NUM_JACK_PORTS]; -static int outport_count = 0; -static jack_client_t *jack_client = 0; -char *jack_client_names[MAX_CLIENTS]; -static int jack_dio_error; -static int jack_scheduler; -pthread_mutex_t jack_mutex; -pthread_cond_t jack_sem; -t_int jack_save_connection_state(t_int* dummy); -static void jack_restore_connection_state(); -void run_all_idle_callbacks(); - -static int process (jack_nframes_t nframes, void *arg) { - jack_out_max = max(int(nframes),JACK_OUT_MAX); - if (jack_filled >= nframes) { - if (jack_filled != nframes) post("Partial read"); - for (int j=0; j<sys_outchannels; j++) { - float *out = (float *)jack_port_get_buffer(output_port[j], nframes); - memcpy(out, jack_outbuf + (j * BUF_JACK), sizeof(float)*nframes); - } - for (int j=0; j<sys_inchannels; j++) { - float *in = (float *)jack_port_get_buffer( input_port[j], nframes); - memcpy(jack_inbuf + (j * BUF_JACK), in, sizeof(float)*nframes); - } - jack_filled -= nframes; - } else { /* PD could not keep up ! */ - if (jack_started) jack_dio_error = 1; - for (int j=0; j<outport_count; j++) { - float *out = (float *)jack_port_get_buffer (output_port[j], nframes); - memset(out, 0, sizeof (float) * nframes); - } - memset(jack_outbuf,0,sizeof(jack_outbuf)); - jack_filled = 0; - } - /* tb: wait in the scheduler: pthread_cond_broadcast(&jack_sem); */ - return 0; -} - -void sys_peakmeters(); -extern int sys_meters; /* true if we're metering */ -static int dspticks_per_jacktick; -static void (*copyblock)(t_sample *dst,t_sample *src,int n); -static void (*zeroblock)(t_sample *dst,int n); -extern int canvas_dspstate; - -static int cb_process (jack_nframes_t nframes, void *arg) { - int timeout = int(nframes * 1e6 / sys_dacsr); - if (canvas_dspstate == 0) { - /* dsp is switched off, the audio is open ... */ - for (int j=0; j<sys_outchannels; j++) { - t_sample *out = (t_sample *)jack_port_get_buffer (output_port[j], nframes); - zeroblock(out, dspticks_per_jacktick * sys_dacblocksize); - } - return 0; - } - int status = sys_timedlock(timeout); - if (status) { - if (status == ETIMEDOUT) {error("timeout %d", (timeout)); sys_log_error(ERR_SYSLOCK); return 0;} - else {post("sys_timedlock returned %d", status); return 0;} - } - for (int i = 0; i != dspticks_per_jacktick; ++i) { - for (int j=0; j<sys_inchannels; j++) { - t_sample *in = (t_sample *)jack_port_get_buffer(input_port[j], nframes); - copyblock(sys_soundin + j * sys_dacblocksize, in + i * sys_dacblocksize, sys_dacblocksize); - } - sched_tick(sys_time + sys_time_per_dsp_tick); - for (int j=0; j<sys_outchannels; j++) { - t_sample *out = (t_sample *)jack_port_get_buffer(output_port[j], nframes); - copyblock(out + i * sys_dacblocksize, sys_soundout + j * sys_dacblocksize, sys_dacblocksize); - } - if (sys_meters) sys_peakmeters(); - zeroblock(sys_soundout, sys_outchannels * sys_dacblocksize); - } - run_all_idle_callbacks(); - sys_unlock(); - return 0; -} - -static int jack_srate (jack_nframes_t srate, void *arg) { - sys_dacsr = srate; - return 0; -} - -static void jack_close_audio(void); -static int jack_ignore_graph_callback = 0; -static t_int jack_shutdown_handler(t_int* none) { - error("jack kicked us out ... trying to reconnect"); - jack_ignore_graph_callback = 1; - jack_close_audio(); - /* try to reconnect to jack server */ - jack_open_audio(sys_inchannels, sys_outchannels, int(sys_dacsr), jack_scheduler); - jack_restore_connection_state(); - jack_ignore_graph_callback = 0; - return 0; -} - -/* register idle callback in scheduler */ -static void jack_shutdown (void *arg) {sys_callback(jack_shutdown_handler,0,0);} -static int jack_graph_order_callback(void* arg) {sys_callback(jack_save_connection_state,0,0); return 0;} - -static char** jack_get_clients() { - int num_clients = 0; - regex_t port_regex; - const char **jack_ports = jack_get_ports(jack_client, "", "", 0); - regcomp(&port_regex, "^[^:]*", REG_EXTENDED); - jack_client_names[0] = 0; - /* Build a list of clients from the list of ports */ - for (int i=0; jack_ports[i] != 0; i++) { - regmatch_t match_info; - char tmp_client_name[100]; - /* extract the client name from the port name, using a regex that parses the clientname:portname syntax */ - regexec(&port_regex, jack_ports[i], 1, &match_info, 0); - memcpy(tmp_client_name, &jack_ports[i][match_info.rm_so], match_info.rm_eo-match_info.rm_so); - tmp_client_name[ match_info.rm_eo - match_info.rm_so ] = '\0'; - /* do we know about this port's client yet? */ - int client_seen = 0; - for (int j=0; j<num_clients; j++) if (strcmp(tmp_client_name, jack_client_names[j])==0) client_seen = 1; - if (!client_seen) { - jack_client_names[num_clients] = (char*)getbytes(strlen(tmp_client_name) + 1); - /* The alsa_pcm client should go in spot 0. If this is the alsa_pcm client AND we are NOT about to put - it in spot 0 put it in spot 0 and move whatever was already in spot 0 to the end. */ - if (strcmp("alsa_pcm",tmp_client_name)==0 && num_clients>0) { - /* alsa_pcm goes in spot 0 */ - char* tmp = jack_client_names[num_clients]; - jack_client_names[num_clients] = jack_client_names[0]; - jack_client_names[0] = tmp; - strcpy(jack_client_names[0], tmp_client_name); - } else { - /* put the new client at the end of the client list */ - strcpy(jack_client_names[num_clients], tmp_client_name); - } - num_clients++; - } - } - /* for (int i=0; i<num_clients; i++) post("client: %s",jack_client_names[i]); */ - free(jack_ports); - return jack_client_names; -} - -/* Wire up all the ports of one client. */ -static int jack_connect_ports(char *client) { - char regex_pattern[100]; - static int entered = 0; - if (entered) return 0; - entered = 1; - if (strlen(client) > 96) return -1; - sprintf(regex_pattern, "%s:.*", client); - const char **jack_ports = jack_get_ports(jack_client, regex_pattern, 0, JackPortIsOutput); - if (jack_ports) - for (int i=0;jack_ports[i] != 0 && i < sys_inchannels;i++) - if (jack_connect(jack_client, jack_ports[i], jack_port_name(input_port[i]))) - error("cannot connect input ports %s -> %s", jack_ports[i],jack_port_name(input_port[i])); - free(jack_ports); - jack_ports = jack_get_ports(jack_client, regex_pattern, 0, JackPortIsInput); - if (jack_ports) - for (int i=0;jack_ports[i] != 0 && i < sys_outchannels;i++) - if (jack_connect(jack_client, jack_port_name(output_port[i]), jack_ports[i])) - error("cannot connect output ports %s -> %s",jack_port_name(output_port[i]),jack_ports[i]); - free(jack_ports); - return 0; -} - -static void jack_error(const char *desc) {} - -int jack_open_audio_2(int inchans, int outchans, int rate, int scheduler); -int jack_open_audio( int inchans, int outchans, int rate, int scheduler) { - jack_dio_error = 0; - if (inchans==0 && outchans==0) return 0; - int ret = jack_open_audio_2(inchans,outchans,rate,scheduler); - if (ret) sys_setscheduler(0); - return ret; -} - -int jack_open_audio_2(int inchans, int outchans, int rate, int scheduler) { - char port_name[80] = ""; - int new_jack = 0; - if (outchans > NUM_JACK_PORTS) {post("%d output ports not supported, setting to %d",outchans, NUM_JACK_PORTS); outchans = NUM_JACK_PORTS;} - if ( inchans > NUM_JACK_PORTS) {post( "%d input ports not supported, setting to %d", inchans, NUM_JACK_PORTS); inchans = NUM_JACK_PORTS;} - if (jack_client && scheduler != sys_getscheduler()) {jack_client_close(jack_client); jack_client = 0;} - sys_setscheduler(scheduler); - jack_scheduler = scheduler; - /* set block copy/zero functions */ - if(SIMD_CHKCNT(sys_dacblocksize) && simd_runtime_check()) { - copyblock = (void (*)(t_sample *,t_sample *,int))©vec_simd; - zeroblock = &zerovec_simd; - } else { - copyblock = (void (*)(t_sample *,t_sample *,int))©vec; - zeroblock = &zerovec; - } - /* try to become a client of the JACK server (we allow two pd's)*/ - if (!jack_client) { - int client_iterator = 0; - do { - sprintf(port_name,"pure_data_%d",client_iterator); - client_iterator++; - } while (((jack_client = jack_client_new (port_name)) == 0) && client_iterator < 2); - // jack spits out enough messages already, do not warn - if (!jack_client) {sys_inchannels = sys_outchannels = 0; return 1;} - jack_get_clients(); - /* tell the JACK server to call `process()' whenever there is work to be done. - tb: adapted for callback based scheduling */ - if (scheduler == 1) { - dspticks_per_jacktick = jack_get_buffer_size(jack_client) / sys_schedblocksize; - jack_set_process_callback (jack_client, cb_process, 0); - } else jack_set_process_callback (jack_client, process, 0); - jack_set_error_function (jack_error); -#ifdef JACK_XRUN - jack_set_xrun_callback (jack_client, jack_xrun, 0); -#endif - jack_set_graph_order_callback(jack_client, jack_graph_order_callback, 0); - /* tell the JACK server to call `srate()' whenever the sample rate of the system changes. */ - jack_set_sample_rate_callback (jack_client, jack_srate, 0); - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it just decides to stop calling us. */ - jack_on_shutdown (jack_client, jack_shutdown, 0); - for (int j=0;j<NUM_JACK_PORTS;j++) {input_port[j]=0; output_port[j]=0;} - new_jack = 1; - } - /* display the current sample rate. once the client is activated - (see below), you should rely on your own sample rate callback (see above) for this value. */ - int srate = jack_get_sample_rate (jack_client); - sys_dacsr = srate; - /* create the ports */ - for (int j=0; j<inchans; j++) { - sprintf(port_name, "input%d", j); - if (!input_port[j]) input_port[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - } - for (int j=0; j<outchans; j++) { - sprintf(port_name, "output%d", j); - if (!output_port[j]) output_port[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - } - outport_count = outchans; - /* tell the JACK server that we are ready to roll */ - if (new_jack) { - if (jack_activate (jack_client)) {error("cannot activate client"); sys_inchannels = sys_outchannels = 0; return 1;} - memset(jack_outbuf,0,sizeof(jack_outbuf)); - if (jack_client_names[0]) jack_connect_ports(jack_client_names[0]); - pthread_mutex_init(&jack_mutex,0); - pthread_cond_init(&jack_sem,0); - } - /* tb: get advance from jack server */ - sys_schedadvance = int((float)jack_port_get_total_latency(jack_client,output_port[0]) * 1000. / sys_dacsr * 1000); - return 0; -} - -static void jack_close_audio() { - if (!jack_client) return; - jack_deactivate(jack_client); - jack_started = 0; - jack_client_close(jack_client); - jack_client = 0; - for (int i=0; i<NUM_JACK_PORTS; i++) {input_port[i] = 0; output_port[i] = 0;} -} - -int jack_send_dacs() { - int rtnval = SENDDACS_YES; - int timeref = int(sys_getrealtime()); - if (!jack_client) return SENDDACS_NO; - if (!sys_inchannels && !sys_outchannels) return SENDDACS_NO; - if (jack_dio_error) {sys_log_error(ERR_RESYNC); jack_dio_error = 0;} - if (jack_filled >= jack_out_max) return SENDDACS_NO; - /* tb: wait in the scheduler: pthread_cond_wait(&jack_sem,&jack_mutex); */ - jack_started = 1; - float *fp = sys_soundout; - for (int j=0; j<sys_outchannels; j++, fp += sys_dacblocksize) - memcpy(jack_outbuf + j*BUF_JACK + jack_filled, fp, sys_dacblocksize*sizeof(float)); - fp = sys_soundin; - for (int j=0; j<sys_inchannels; j++, fp += sys_dacblocksize) - memcpy(fp, jack_inbuf + j*BUF_JACK + jack_filled, sys_dacblocksize*sizeof(float)); - int timenow = int(sys_getrealtime()); - if (timenow-timeref > sys_sleepgrain*1e-6) rtnval = SENDDACS_SLEPT; - memset(sys_soundout,0,sys_dacblocksize*sizeof(float)*sys_outchannels); - jack_filled += sys_dacblocksize; - return rtnval; -} - -void jack_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - *canmulti = 0; /* supports multiple devices */ - int ndev = 1; - for (int i=0; i<ndev; i++) { - sprintf( indevlist + i*devdescsize, "JACK"); - sprintf(outdevlist + i*devdescsize, "JACK"); - } - *nindevs = *noutdevs = ndev; -} - -void jack_listdevs () {error("device listing not implemented for jack yet");} - -static const char ** jack_in_connections[NUM_JACK_PORTS]; /* ports connected to the inputs */ -static const char **jack_out_connections[NUM_JACK_PORTS]; /* ports connected to the outputs */ - -/* tb: save the current state of pd's jack connections */ -t_int jack_save_connection_state(t_int* dummy) { - if (jack_ignore_graph_callback) return 0; - for (int i=0; i<NUM_JACK_PORTS; i++) { - if ( jack_in_connections[i]) free( jack_in_connections[i]); - jack_in_connections[i] = i< sys_inchannels ? jack_port_get_all_connections(jack_client, input_port[i]) : 0; - if (jack_out_connections[i]) free(jack_out_connections[i]); - jack_out_connections[i]= i<sys_outchannels ? jack_port_get_all_connections(jack_client, output_port[i]) : 0; - } - return 0; -} - -/* todo: don't try to connect twice if we're both input and output host */ -static void jack_restore_connection_state() { - post("restoring connections"); - for (int i=0; i<NUM_JACK_PORTS; i++) { - /* restoring the inputs connections */ - if (jack_in_connections[i]) { - for (int j=0;;j++) { - const char *port = jack_in_connections[i][j]; - if (!port) break; /* we've connected all incoming ports */ - int status = jack_connect(jack_client, port, jack_port_name(input_port[i])); - if (status) error("cannot connect input ports %s -> %s", port, jack_port_name(input_port[i])); - } - } - /* restoring the output connections */ - if (jack_out_connections[i]) { - for (int j=0;;j++) { - const char *port = jack_out_connections[i][j]; - if (!port) break; /* we've connected all outgoing ports */ - int status = jack_connect(jack_client, jack_port_name(output_port[i]), port); - if (status) error("cannot connect output ports %s -> %s", jack_port_name(output_port[i]), port); - } - } - } -} - -struct t_audioapi jack_api = { - 0 /*jack_open_audio*/, - jack_close_audio, - jack_send_dacs, - jack_getdevs, -}; diff --git a/desiredata/src/s_audio_mmio.c b/desiredata/src/s_audio_mmio.c deleted file mode 100644 index f21b999e..00000000 --- a/desiredata/src/s_audio_mmio.c +++ /dev/null @@ -1,476 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* modified 2/98 by Winfried Ritsch to deal with up to 4 synchronized -"wave" devices, which is how ADAT boards appear to the WAVE API. */ - -#include "desire.h" -#include <stdio.h> -#include <windows.h> -#include <mmsystem.h> -using namespace desire; - -/* ------------------------- audio -------------------------- */ - -static void nt_noresync(); - -#define NAPORTS 16 /* wini hack for multiple ADDA devices */ -#define CHANNELS_PER_DEVICE 2 -#define DEFAULTCHANS 2 -#define DEFAULTSRATE 44100 -#define SAMPSIZE 2 - -int nt_realdacblksize; -#define DEFREALDACBLKSIZE (4 * sys_dacblocksize) /* larger underlying bufsize */ - -#define MAXBUFFER 100 /* number of buffers in use at maximum advance */ -#define DEFBUFFER 30 /* default is about 30x6 = 180 msec! */ -static int nt_naudiobuffer = DEFBUFFER; -static int nt_meters; /* true if we're metering */ -static float mmi_max, mmo_max; /* max amplitude */ -static int mmi_nwave, mmo_nwave; /* number of WAVE devices */ - -typedef struct _sbuf { - HANDLE hData; - HPSTR lpData; // pointer to waveform data memory - HANDLE hWaveHdr; - WAVEHDR *lpWaveHdr; // pointer to header structure -} t_sbuf; - -t_sbuf mmo_vec[NAPORTS][MAXBUFFER]; /* circular buffer array */ -t_sbuf mmi_vec[NAPORTS][MAXBUFFER]; /* circular buffer array */ -HWAVEOUT mmo_dev[NAPORTS]; /* output device */ -HWAVEIN mmi_dev[NAPORTS]; /* input device */ -static int mmo_phase[NAPORTS]; /* index of next buffer to send */ -static int mmi_phase[NAPORTS]; /* index of next buffer to read */ -static UINT nt_whichdac = WAVE_MAPPER, nt_whichadc = WAVE_MAPPER; - -static void mmi_waveerror(const char *s, int err) {char t[256]; waveInGetErrorText(err, t, 256); error(s,t);} -static void mmo_waveerror(const char *s, int err) {char t[256]; waveOutGetErrorText(err, t, 256); error(s,t);} - -static void wave_prep(t_sbuf *bp, int setdone) { - WAVEHDR *wh; - /* Allocate and lock memory for the waveform data. The memory for waveform data must be globally allocated with - * GMEM_MOVEABLE and GMEM_SHARE flags. */ - if (!(bp->hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)))) - printf("alloc 1 failed\n"); - if (!(bp->lpData = (HPSTR) GlobalLock(bp->hData))) - printf("lock 1 failed\n"); - /* Allocate and lock memory for the header. */ - if (!(bp->hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR)))) - printf("alloc 2 failed\n"); - if (!(wh = bp->lpWaveHdr = (WAVEHDR *) GlobalLock(bp->hWaveHdr))) - printf("lock 2 failed\n"); - short *sp = (short *)bp->lpData; - for (int i=CHANNELS_PER_DEVICE*nt_realdacblksize; i--; ) *sp++ = 0; - wh->lpData = bp->lpData; - wh->dwBufferLength = CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize; - wh->dwFlags = 0; - wh->dwLoops = 0L; - wh->lpNext = 0; - wh->reserved = 0; - /* optionally (for writing) set DONE flag as if we had queued them */ - if (setdone) wh->dwFlags = WHDR_DONE; -} - -int mmio_do_open_audio() { - PCMWAVEFORMAT form; - UINT r; - static int naudioprepped = 0, nindevsprepped = 0, noutdevsprepped = 0; - if (sys_verbose) post("%d devices in, %d devices out", mmi_nwave, mmo_nwave); - form.wf.wFormatTag = WAVE_FORMAT_PCM; - form.wf.nChannels = CHANNELS_PER_DEVICE; - form.wf.nSamplesPerSec = sys_dacsr; - form.wf.nAvgBytesPerSec = sys_dacsr * (CHANNELS_PER_DEVICE * SAMPSIZE); - form.wf.nBlockAlign = CHANNELS_PER_DEVICE * SAMPSIZE; - form.wBitsPerSample = 8 * SAMPSIZE; - if (mmi_nwave <= 1 && mmo_nwave <= 1) nt_noresync(); - if (nindevsprepped < mmi_nwave) { - for (int i=nindevsprepped; i<mmi_nwave; i++) for (int j=0; j<naudioprepped; j++) wave_prep(&mmi_vec[i][j], 0); - nindevsprepped = mmi_nwave; - } - if (noutdevsprepped < mmo_nwave) { - for (int i=noutdevsprepped; i<mmo_nwave; i++) for (int j=0; j<naudioprepped; j++) wave_prep(&mmo_vec[i][j], 1); - noutdevsprepped = mmo_nwave; - } - if (naudioprepped < nt_naudiobuffer) { - for (int j=naudioprepped; j<nt_naudiobuffer; j++) { - for (int i=0; i<mmi_nwave; i++) wave_prep(&mmi_vec[i][j], 0); - for (int i=0; i<mmo_nwave; i++) wave_prep(&mmo_vec[i][j], 1); - } - naudioprepped = nt_naudiobuffer; - } - for (int n=0; n<mmi_nwave; n++) { - /* Open waveform device(s), sucessively numbered, for input */ - r = waveInOpen(&mmi_dev[n], nt_whichadc+n, (WAVEFORMATEX *)&form, 0L, 0L, CALLBACK_NULL); - if (sys_verbose) printf("opened adc device %d with return %d\n", nt_whichadc+n,r); - if (r != MMSYSERR_NOERROR) { - mmi_waveerror("waveInOpen: %s", r); - mmi_nwave = n; /* mmi_nwave = 0 wini */ - } else { - for (int i=0; i<nt_naudiobuffer; i++) { - r = waveInPrepareHeader(mmi_dev[n], mmi_vec[n][i].lpWaveHdr, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmi_waveerror("waveinprepareheader: %s", r); - r = waveInAddBuffer( mmi_dev[n], mmi_vec[n][i].lpWaveHdr, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmi_waveerror("waveInAddBuffer: %s", r); - } - } - } - /* quickly start them all together */ - for (int n=0; n<mmi_nwave; n++) waveInStart(mmi_dev[n]); - for (int n=0; n<mmo_nwave; n++) { - /* Open a waveform device for output in sucessiv device numbering*/ - r = waveOutOpen(&mmo_dev[n], nt_whichdac + n, (WAVEFORMATEX *)&form, 0L, 0L, CALLBACK_NULL); - if (sys_verbose) post("opened dac device %d, with return %d", nt_whichdac +n, r); - if (r != MMSYSERR_NOERROR) { - post("Wave out open device %d + %d",nt_whichdac,n); - mmo_waveerror("waveOutOpen device: %s", r); - mmo_nwave = n; - } - } - return 0; -} - -static void mmio_close_audio() { - int errcode; - if (sys_verbose) post("closing audio..."); - for (int n=0; n<mmo_nwave; n++) /*if (mmo_nwave) wini */ { - errcode = waveOutReset(mmo_dev[n]); if (errcode!=MMSYSERR_NOERROR) printf("error resetting output %d: %d",n,errcode); - errcode = waveOutClose(mmo_dev[n]); if (errcode!=MMSYSERR_NOERROR) printf("error closing output %d: %d", n,errcode); - } - mmo_nwave = 0; - for (int n=0; n<mmi_nwave;n++) /* if (mmi_nwave) wini */ { - errcode = waveInReset(mmi_dev[n]); if (errcode!=MMSYSERR_NOERROR) printf("error resetting input: %d", errcode); - errcode = waveInClose(mmi_dev[n]); if (errcode!=MMSYSERR_NOERROR) printf("error closing input: %d", errcode); - } - mmi_nwave = 0; -} - -#define ADCJITTER 10 /* We tolerate X buffers of jitter by default */ -#define DACJITTER 10 - -static int nt_adcjitterbufsallowed = ADCJITTER; -static int nt_dacjitterbufsallowed = DACJITTER; - -/* ------------- MIDI time stamping from audio clock ------------ */ - -#ifdef MIDI_TIMESTAMP - -static double nt_hibuftime; -static double initsystime = -1; - -/* call this whenever we reset audio */ -static void nt_resetmidisync() {initsystime = clock_getsystime(); nt_hibuftime = sys_getrealtime();} - -/* call this whenever we're idled waiting for audio to be ready. - The routine maintains a high and low water point for the difference between real and DAC time. */ - -static void nt_midisync() { - if (initsystime == -1) nt_resetmidisync(); - double jittersec = max(nt_dacjitterbufsallowed,nt_adcjitterbufsallowed) * nt_realdacblksize / sys_getsr(); - double diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime); - if (diff > nt_hibuftime) nt_hibuftime = diff; - if (diff < nt_hibuftime - jittersec) {post("jitter excess %d %f", dac, diff); nt_resetmidisync();} -} - -static double nt_midigettimefor(LARGE_INTEGER timestamp) { - /* this is broken now... used to work when "timestamp" was derived from - QueryPerformanceCounter() instead of the gates approved timeGetSystemTime() call in the MIDI callback routine below. */ - return nt_tixtotime(timestamp) - nt_hibuftime; -} -#endif /* MIDI_TIMESTAMP */ - -static int nt_fill = 0; -#define WRAPFWD(x) ((x) >= nt_naudiobuffer ? (x) - nt_naudiobuffer: (x)) -#define WRAPBACK(x) ((x) < 0 ? (x) + nt_naudiobuffer: (x)) -#define MAXRESYNC 500 - -#if 0 /* this is used for debugging */ -static void nt_printaudiostatus() { - for (int n=0; n<mmi_nwave; n++) { - int phase = mmi_phase[n]; - int phase2 = phase, phase3 = WRAPFWD(phase2), ntrans = 0; - int firstphasedone = -1, firstphasebusy = -1; - for (int count=0; count<nt_naudiobuffer; count++) { - int donethis = (mmi_vec[n][phase2].lpWaveHdr->dwFlags & WHDR_DONE); - int donenext = (mmi_vec[n][phase3].lpWaveHdr->dwFlags & WHDR_DONE); - if (donethis && !donenext) {if (firstphasebusy >= 0) goto multipleadc; else firstphasebusy = count;} - if (!donethis && donenext) {if (firstphasedone >= 0) goto multipleadc; else firstphasedone = count;} - phase2 = phase3; - phase3 = WRAPFWD(phase2 + 1); - } - post("nad %d phase %d busy %d done %d", n, phase, firstphasebusy, firstphasedone); - continue; - multipleadc: - startpost("nad %d phase %d: oops:", n, phase); - for (int count=0; count<nt_naudiobuffer; count++) { - char buf[80]; - sprintf(buf, " %d", (mmi_vec[n][count].lpWaveHdr->dwFlags & WHDR_DONE)); - poststring(buf); - } - endpost(); - } - for (int n=0; n<mmo_nwave; n++) { - int phase = mmo_phase[n]; - int phase2 = phase, phase3 = WRAPFWD(phase2), ntrans = 0; - int firstphasedone = -1, firstphasebusy = -1; - for (count = 0; count < nt_naudiobuffer; count++) { - int donethis = (mmo_vec[n][phase2].lpWaveHdr->dwFlags & WHDR_DONE); - int donenext = (mmo_vec[n][phase3].lpWaveHdr->dwFlags & WHDR_DONE); - if (donethis && !donenext) {if (firstphasebusy >= 0) goto multipledac; else firstphasebusy = count;} - if (!donethis && donenext) {if (firstphasedone >= 0) goto multipledac; else firstphasedone = count;} - phase2 = phase3; - phase3 = WRAPFWD(phase2 + 1); - } - if (firstphasebusy < 0) post("nda %d phase %d all %d", n, phase, (mmo_vec[n][0].lpWaveHdr->dwFlags & WHDR_DONE)); - else post("nda %d phase %d busy %d done %d", n, phase, firstphasebusy, firstphasedone); - continue; - multipledac: - startpost("nda %d phase %d: oops:", n, phase); - for (count = 0; count < nt_naudiobuffer; count++) { - char buf[80]; - sprintf(buf, " %d", (mmo_vec[n][count].lpWaveHdr->dwFlags & WHDR_DONE)); - poststring(buf); - } - endpost(); - } -} -#endif /* 0 */ - -/* this is a hack to avoid ever resyncing audio pointers in case for whatever reason the sync testing below gives false positives. */ - -static int nt_resync_cancelled; -static void nt_noresync() {nt_resync_cancelled = 1;} - -static void nt_resyncaudio() { - UINT r; - if (nt_resync_cancelled) return; - /* for each open input device, eat all buffers which are marked ready. The next one will thus be "busy". */ - post("resyncing audio"); - for (int n=0; n<mmi_nwave; n++) { - int phase = mmi_phase[n], count; - for (count=0; count<MAXRESYNC; count++) { - WAVEHDR *h = mmi_vec[n][phase].lpWaveHdr; - if (!(h->dwFlags & WHDR_DONE)) break; - if (h->dwFlags & WHDR_PREPARED) waveInUnprepareHeader(mmi_dev[n], h, sizeof(WAVEHDR)); - h->dwFlags = 0L; - waveInPrepareHeader(mmi_dev[n], h, sizeof(WAVEHDR)); - r = waveInAddBuffer(mmi_dev[n], h, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmi_waveerror("waveInAddBuffer: %s", r); - mmi_phase[n] = phase = WRAPFWD(phase+1); - } - if (count == MAXRESYNC) post("resync error at input"); - } - /* Each output buffer which is "ready" is filled with zeros and queued. */ - for (int n=0; n<mmo_nwave; n++) { - int phase = mmo_phase[n], count; - for (count=0; count<MAXRESYNC; count++) { - WAVEHDR *h = mmo_vec[n][phase].lpWaveHdr; - if (!(h->dwFlags & WHDR_DONE)) break; - if (h->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(mmo_dev[n], h, sizeof(WAVEHDR)); - h->dwFlags = 0L; - memset((char *)(mmo_vec[n][phase].lpData), 0, (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)); - waveOutPrepareHeader(mmo_dev[n], h, sizeof(WAVEHDR)); - r = waveOutWrite(mmo_dev[n], h, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmo_waveerror("waveOutAddBuffer: %s", r); - mmo_phase[n] = phase = WRAPFWD(phase+1); - } - if (count == MAXRESYNC) post("resync error at output"); - } -#ifdef MIDI_TIMESTAMP - nt_resetmidisync(); -#endif -} - -#define LATE 0 -#define RESYNC 1 -#define NOTHING 2 - -void nt_logerror(int which) { -#if 0 - post("error %d %d", count, which); - if (which < NOTHING) nt_errorcount++; - if (which == RESYNC) nt_resynccount++; - if (sys_getrealtime() > nt_nextreporttime) { - post("%d audio I/O error%s", nt_errorcount, (nt_errorcount > 1 ? "s" : "")); - if (nt_resynccount) post("DAC/ADC sync error"); - nt_errorcount = nt_resynccount = 0; - nt_nextreporttime = sys_getrealtime() - 5; - } -#endif -} - -static int mmio_send_dacs() { - UINT r; - if (!mmi_nwave && !mmo_nwave) return 0; - if (nt_meters) { - float maxsamp = mmi_max; - for (int i=0, n=2*mmi_nwave*sys_dacblocksize; i<n; i++) { - float f = sys_soundin[i]; - if (f > maxsamp) maxsamp = f; else if (-f > maxsamp) maxsamp = -f; - } - mmi_max = maxsamp; - maxsamp = mmo_max; - for (int i=0, n=2*mmo_nwave*sys_dacblocksize; i<n; i++) { - float f = sys_soundout[i]; - if (f > maxsamp) maxsamp = f; else if (-f > maxsamp) maxsamp = -f; - } - mmo_max = maxsamp; - } - /* the "fill pointer" nt_fill controls where in the next I/O buffers we will write and/or read. If it's zero, we - first check whether the buffers are marked "done". */ - if (!nt_fill) { - for (int n=0; n<mmi_nwave; n++) { - WAVEHDR *h = mmi_vec[n][mmi_phase[n]].lpWaveHdr; if (!(h->dwFlags & WHDR_DONE)) goto idle; - } - for (int n=0; n<mmo_nwave; n++) { - WAVEHDR *h = mmo_vec[n][mmo_phase[n]].lpWaveHdr; if (!(h->dwFlags & WHDR_DONE)) goto idle; - } - for (int n=0; n<mmi_nwave; n++) { - WAVEHDR *h = mmi_vec[n][mmi_phase[n]].lpWaveHdr; if (h->dwFlags & WHDR_PREPARED) waveInUnprepareHeader(mmi_dev[n],h,sizeof(WAVEHDR)); - } - for (int n=0; n<mmo_nwave; n++) { - WAVEHDR *h = mmo_vec[n][mmo_phase[n]].lpWaveHdr; if (h->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(mmo_dev[n],h,sizeof(WAVEHDR)); - } - } - /* Convert audio output to fixed-point and put it in the output buffer. */ - short *sp1, *sp2; - float *fp1, *fp2; - fp1 = sys_soundout; - for (int n=0; n<mmo_nwave; n++) { - int phase = mmo_phase[n]; - sp1=(short *)(mmo_vec[n][phase].lpData)+CHANNELS_PER_DEVICE*nt_fill; - for (int i=0; i<2; i++, fp1 += sys_dacblocksize, sp1++) { - fp2 = fp1; sp2 = sp1; - for (int j=0; j<sys_dacblocksize; j++, fp2++, sp2 += CHANNELS_PER_DEVICE) { - *sp2 = clip(int(*fp2*32767),-32768,32767); - } - } - } - memset(sys_soundout, 0, (sys_dacblocksize *sizeof(t_sample)*CHANNELS_PER_DEVICE)*mmo_nwave); - /* vice versa for the input buffer */ - fp1 = sys_soundin; - for (int n=0; n<mmi_nwave; n++) { - int phase = mmi_phase[n]; - sp1=(short *)(mmi_vec[n][phase].lpData)+CHANNELS_PER_DEVICE*nt_fill; - for (int i=0; i<2; i++, fp1 += sys_dacblocksize, sp1++) { - fp2 = fp1; sp2 = sp1; - for (int j=0; j<sys_dacblocksize; j++, fp2++, sp2 += CHANNELS_PER_DEVICE) *fp2 = float(1./32767.)*float(*sp2); - } - } - nt_fill += sys_dacblocksize; - if (nt_fill == nt_realdacblksize) { - nt_fill = 0; - for (int n=0; n<mmi_nwave; n++) { - int phase = mmi_phase[n]; - HWAVEIN device = mmi_dev[n]; - WAVEHDR *h = mmi_vec[n][phase].lpWaveHdr; - waveInPrepareHeader(device, h, sizeof(WAVEHDR)); - r = waveInAddBuffer(device, h, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmi_waveerror("waveInAddBuffer: %s", r); - mmi_phase[n] = WRAPFWD(phase+1); - } - for (int n=0; n<mmo_nwave; n++) { - int phase = mmo_phase[n]; - HWAVEOUT device = mmo_dev[n]; - WAVEHDR *h = mmo_vec[n][phase].lpWaveHdr; - waveOutPrepareHeader(device, h, sizeof(WAVEHDR)); - r = waveOutWrite(device, h, sizeof(WAVEHDR)); - if (r != MMSYSERR_NOERROR) mmo_waveerror("waveOutWrite: %s", r); - mmo_phase[n] = WRAPFWD(phase+1); - } - /* check for DAC underflow or ADC overflow. */ - for (int n=0; n<mmi_nwave; n++) { - int phase = WRAPBACK(mmi_phase[n]-2); WAVEHDR *h = mmi_vec[n][phase].lpWaveHdr; - if (h->dwFlags & WHDR_DONE) goto late; - } - for (int n=0; n<mmo_nwave; n++) { - int phase = WRAPBACK(mmo_phase[n]-2); WAVEHDR *h = mmo_vec[n][phase].lpWaveHdr; - if (h->dwFlags & WHDR_DONE) goto late; - } - } - return 1; -late: - nt_logerror(LATE); - nt_resyncaudio(); - return 1; -idle: - /* If more than nt_adcjitterbufsallowed ADC buffers are ready on any input device, resynchronize */ - for (int n=0; n<mmi_nwave; n++) { - WAVEHDR *h = mmi_vec[n][WRAPFWD(mmi_phase[n] + nt_adcjitterbufsallowed)].lpWaveHdr; - if (h->dwFlags & WHDR_DONE) {nt_resyncaudio(); return 0;} - } - /* test dac sync the same way */ - for (int n=0; n<mmo_nwave; n++) { - WAVEHDR *h = mmo_vec[n][WRAPFWD(mmo_phase[n] + nt_dacjitterbufsallowed)].lpWaveHdr; - if (h->dwFlags & WHDR_DONE) {nt_resyncaudio(); return 0;} - } -#ifdef MIDI_TIMESTAMP - nt_midisync(); -#endif - return 0; -} - -/* ------------------- public routines -------------------------- */ - -static int mmio_open_audio( - int naudioidev, int *audioidev, int nchidev, int *chidev, - int naudioodev, int *audioodev, int nchodev, int *chodev, int rate, int dummy) /* IOhannes */ { - nt_realdacblksize = (sys_blocksize ? sys_blocksize : DEFREALDACBLKSIZE); - int nbuf = sys_advance_samples/nt_realdacblksize; - if (nbuf >= MAXBUFFER) { - post("pd: audio buffering maxed out to %d", int(MAXBUFFER * ((nt_realdacblksize * 1000.)/44100.))); - nbuf = MAXBUFFER; - } else if (nbuf < 4) nbuf = 4; - post("%d audio buffers", nbuf); - nt_naudiobuffer = nbuf; - if (nt_adcjitterbufsallowed > nbuf-2) nt_adcjitterbufsallowed = nbuf-2; - if (nt_dacjitterbufsallowed > nbuf-2) nt_dacjitterbufsallowed = nbuf-2; - mmi_nwave = sys_inchannels / 2; - mmo_nwave = sys_outchannels / 2; - nt_whichadc = (naudioidev < 1 ? (mmi_nwave > 1 ? WAVE_MAPPER : -1) : audioidev[0]); - nt_whichdac = (naudioodev < 1 ? (mmo_nwave > 1 ? WAVE_MAPPER : -1) : audioodev[0]); - if (naudioodev>1 || naudioidev>1) post("separate audio device choice not supported; using sequential devices."); - mmio_do_open_audio(); - return 0; -} - -#if 0 -/* list the audio and MIDI device names */ -void mmio_listdevs() { - UINT ndevices = waveInGetNumDevs(); - for (unsigned i=0; i<ndevices; i++) { - WAVEINCAPS w; UINT wRtn = waveInGetDevCaps( i, (LPWAVEINCAPS) &w, sizeof(w)); - if (wRtn) mmi_waveerror( "waveInGetDevCaps: %s", wRtn); else post("audio input device #%d: %s", i+1, w.szPname); - } - ndevices = waveOutGetNumDevs(); - for (unsigned i=0; i<ndevices; i++) { - WAVEOUTCAPS w; UINT wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS)&w, sizeof(w)); - if (wRtn) mmo_waveerror("waveOutGetDevCaps: %s", wRtn); else post("audio output device #%d: %s", i+1, w.szPname); - } -} -#endif - -static void mmio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - *canmulti = 2; /* supports multiple devices */ - int ndev = min(maxndev,int(waveInGetNumDevs())); - *nindevs = ndev; - for (int i=0; i<ndev; i++) { - WAVEINCAPS w; int wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &w, sizeof(w)); - sprintf(indevlist + i*devdescsize, wRtn?"???":w.szPname); - } - ndev = min(maxndev,int(waveOutGetNumDevs())); - *noutdevs = ndev; - for (int i=0; i<ndev; i++) { - WAVEOUTCAPS w; int wRtn = waveOutGetDevCaps(i,(LPWAVEOUTCAPS)&w, sizeof(w)); - sprintf(outdevlist + i*devdescsize, wRtn?"???":w.szPname); - } -} - -struct t_audioapi api_mmio = { - mmio_open_audio, - mmio_close_audio, - mmio_send_dacs, - mmio_getdevs, -}; diff --git a/desiredata/src/s_audio_oss.c b/desiredata/src/s_audio_oss.c deleted file mode 100644 index 323f114b..00000000 --- a/desiredata/src/s_audio_oss.c +++ /dev/null @@ -1,521 +0,0 @@ -/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* this file inputs and outputs audio using the OSS API available on linux. */ -#include <linux/soundcard.h> - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <sched.h> -#include <sys/mman.h> - -/* Defines */ -#define DEBUG(x) x -#define DEBUG2(x) {x;} - -#define OSS_MAXCHPERDEV 32 /* max channels per OSS device */ -#define OSS_MAXDEV 4 /* maximum number of input or output devices */ -#define OSS_DEFFRAGSIZE 256 /* default log fragment size (frames) */ -#define OSS_DEFAUDIOBUF 40000 /* default audiobuffer, microseconds */ -#define OSS_DEFAULTCH 2 -#define RME_DEFAULTCH 8 /* need this even if RME undefined */ -typedef int16_t t_oss_int16; -typedef int32_t t_oss_int32; -#define OSS_MAXSAMPLEWIDTH sizeof(t_oss_int32) -#define OSS_BYTESPERCHAN(width) (sys_dacblocksize * (width)) -#define OSS_XFERSAMPS(chans) (sys_dacblocksize* (chans)) -#define OSS_XFERSIZE(chans, width) (sys_dacblocksize * (chans) * (width)) - -static int linux_fragsize = 0; /* for block mode; block size (sample frames) */ - -/* our device handles */ -struct t_oss_dev { - int fd; - unsigned int space; /* bytes available for writing/reading */ - int bufsize; /* total buffer size in blocks for this device */ - int dropcount; /* # of buffers to drop for resync (output only) */ - unsigned int nchannels; /* number of channels for this device */ - unsigned int bytespersamp; /* bytes per sample (2 for 16 bit, 4 for 32) */ -}; - -static t_oss_dev linux_dacs[OSS_MAXDEV]; -static t_oss_dev linux_adcs[OSS_MAXDEV]; -static int linux_noutdevs = 0; -static int linux_nindevs = 0; - -/* OSS-specific private variables */ -static int oss_blockmode = 0; /* flag to use "blockmode" */ -static int oss_32bit = 0; /* allow 23 bit transfers in OSS */ - -/* don't assume we can turn all 31 bits when doing float-to-fix; - otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */ -#define FMAX 0x7ffff000 -#define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x)) - -/* ---------------- public routines ----------------------- */ -static int oss_ndev = 0; - -/* find out how many OSS devices we have. Since this has to - open the devices to find out if they're there, we have - to be called before audio is actually started up. So we - cache the results, which in effect are the number of available devices. */ -void oss_init() { - static int countedthem = 0; - if (countedthem) return; - for (int i=0; i<10; i++) { - char devname[100]; - if (i == 0) strcpy(devname, "/dev/dsp"); else sprintf(devname, "/dev/dsp%d", i); - int fd = open(devname, O_WRONLY|O_NONBLOCK); - if (fd<0) break; - oss_ndev++; - close(fd); - } - countedthem = 1; -} - -void oss_set32bit() {oss_32bit=1;} - -struct t_multidev { - int fd; - int channels; - int format; -}; - -int oss_reset(int fd) { - int err = ioctl(fd,SNDCTL_DSP_RESET); - if (err<0) error("OSS: Could not reset"); - return err; -} - -/* The AFMT_S32_BLOCKED format is not defined in standard linux kernels - but is proposed by Guenter Geiger to support extending OSS to handle - 32 bit sample. This is user in Geiger's OSS driver for RME Hammerfall. - I'm not clear why this isn't called AFMT_S32_[SLN]E... */ - -#ifndef AFMT_S32_BLOCKED -#define AFMT_S32_BLOCKED 0x0000400 -#endif - -void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize) { - /* IOhannes */ - int orig, param, fd = dev->fd, wantformat; - int nchannels = dev->nchannels; - audio_buf_info ainfo; - /* IOhannes : pd is very likely to crash if different formats are used on multiple soundcards */ - /* set resolution - first try 4 byte samples */ - if (oss_32bit && (ioctl(fd,SNDCTL_DSP_GETFMTS,¶m) >= 0) && (param & AFMT_S32_BLOCKED)) { - wantformat = AFMT_S32_BLOCKED; - dev->bytespersamp = 4; - } else { - wantformat = AFMT_S16_NE; - dev->bytespersamp = 2; - } - param = wantformat; - - if (sys_verbose) post("bytes per sample = %d", dev->bytespersamp); - if (ioctl(fd, SNDCTL_DSP_SETFMT, ¶m) == -1) error("OSS: Could not set DSP format"); - else if (wantformat != param) error("OSS: DSP format: wanted %d, got %d", wantformat, param); - /* sample rate */ - orig = param = srate; - if (ioctl(fd, SNDCTL_DSP_SPEED, ¶m) == -1) error("OSS: Could not set sampling rate for device"); - else if (orig != param) error("OSS: sampling rate: wanted %d, got %d", orig, param ); - - if (oss_blockmode && !skipblocksize) { - int fragbytes, logfragsize, nfragment; - /* setting fragment count and size. */ - linux_fragsize = sys_blocksize; - if (!linux_fragsize) { - linux_fragsize = OSS_DEFFRAGSIZE; - while (linux_fragsize > sys_dacblocksize && linux_fragsize * 6 > sys_advance_samples) - linux_fragsize = linux_fragsize/2; - } - /* post("adv_samples %d", sys_advance_samples); */ - nfragment = int(sys_schedadvance * 44100.e-6 / linux_fragsize); - fragbytes = linux_fragsize * (dev->bytespersamp * nchannels); - logfragsize = ilog2(fragbytes); - if (fragbytes != (1 << logfragsize)) - post("warning: OSS takes only power of 2 blocksize; using %d", (1<<logfragsize)/(dev->bytespersamp*nchannels)); - if (sys_verbose) post("setting nfrags = %d, fragsize %d", nfragment, fragbytes); - - param = orig = (nfragment<<16) + logfragsize; - if (ioctl(fd,SNDCTL_DSP_SETFRAGMENT, ¶m) == -1) error("OSS: Could not set or read fragment size"); - if (param != orig) { - nfragment = ((param >> 16) & 0xffff); - logfragsize = (param & 0xffff); - post("warning: actual fragments %d, blocksize %d", nfragment, 1<<logfragsize); - } - if (sys_verbose) post("audiobuffer set to %d msec", (int)(0.001 * sys_schedadvance)); - } - - if (dac) { - /* use "free space" to learn the buffer size. Normally you - should set this to your own desired value; but this seems not - to be implemented uniformly across different sound cards. LATER - we should figure out what to do if the requested scheduler advance - is greater than this buffer size; for now, we just print something - out. */ - if (ioctl(fd, SOUND_PCM_GETOSPACE,&ainfo) < 0) error("OSS: ioctl on output device failed"); - dev->bufsize = ainfo.bytes; - int defect = sys_advance_samples*(dev->bytespersamp*nchannels) - dev->bufsize - OSS_XFERSIZE(nchannels, dev->bytespersamp); - if (defect>0) { - if (sys_verbose || defect > (dev->bufsize >> 2)) - error("OSS: requested audio buffer size %d limited to %d", - sys_advance_samples*(dev->bytespersamp*nchannels), dev->bufsize); - sys_advance_samples = (dev->bufsize-OSS_XFERSAMPS(nchannels)) / (dev->bytespersamp*nchannels); - } - } -} - -static int oss_setchannels(int fd, int wantchannels, char *devname) { - /* IOhannes */ - int param = wantchannels; - while (param > 1) { - int save = param; - if (ioctl(fd, SNDCTL_DSP_CHANNELS, ¶m) == -1) error("OSS: SNDCTL_DSP_CHANNELS failed %s",devname); - else if (param == save) return param; - param = save - 1; - } - return 0; -} - -#define O_AUDIOFLAG O_NDELAY -/* what's the deal with (!O_NDELAY) ? does it make sense to you? */ - -ssize_t read2(int fd, void *buf, size_t count) { - ssize_t r = read(fd,buf,count); - if (r<0) error("can't read: %s",strerror(errno)); - if (r<(ssize_t)count) error("incomplete read"); - return r; -} -ssize_t write2(int fd, const void *buf, size_t count) { - ssize_t r = write(fd,buf,count); - if (r<0) error("can't write: %s",strerror(errno)); - if (r<(ssize_t)count) error("incomplete write"); - return r; -} - -int oss_open_audio(int nindev, int *indev, int nchin, int *chin, - int noutdev, int *outdev, int nchout, int *chout, int rate, int bogus) -{ /* IOhannes */ - int capabilities = 0; - int inchannels = 0, outchannels = 0; - char devname[20]; - int fd, flags; - char buf[OSS_MAXSAMPLEWIDTH * sys_dacblocksize * OSS_MAXCHPERDEV]; - linux_nindevs = linux_noutdevs = 0; - /* mark devices unopened */ - for (int i=0; i<OSS_MAXDEV; i++) linux_adcs[i].fd = linux_dacs[i].fd = -1; - /* open output devices */ - int wantmore=0; - if (noutdev < 0 || nindev < 0) bug("linux_open_audio"); - for (int n=0; n<noutdev; n++) { - int gotchans, inindex = -1; - int thisdevice = (outdev[n] >= 0 ? outdev[n] : 0); - int wantchannels = (nchout>n) ? chout[n] : wantmore; - fd = -1; - if (!wantchannels) goto end_out_loop; - if (thisdevice > 0) sprintf(devname, "/dev/dsp%d", thisdevice); else sprintf(devname, "/dev/dsp"); - /* search for input request for same device. Succeed only if the number of channels matches. */ - for (int j=0; j<nindev; j++) if (indev[j] == thisdevice && chin[j] == wantchannels) inindex = j; - /* if the same device is requested for input and output, try to open it read/write */ - if (inindex >= 0) { - sys_setalarm(1000000); - if ((fd = open(devname, O_RDWR | O_AUDIOFLAG)) == -1) { - post("%s (read/write): %s", devname, strerror(errno)); - post("(now will try write-only...)"); - } else { - if (fcntl(fd, F_SETFD, 1) < 0) post("couldn't set close-on-exec flag on audio"); - if ((flags = fcntl(fd, F_GETFL)) < 0) post("couldn't get audio device flags"); - else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) post("couldn't set audio device flags"); - if (sys_verbose) post("opened %s for reading and writing", devname); - linux_adcs[inindex].fd = fd; - } - } - /* if that didn't happen or if it failed, try write-only */ - if (fd == -1) { - sys_setalarm(1000000); - if ((fd = open(devname, O_WRONLY | O_AUDIOFLAG)) == -1) { - post("%s (writeonly): %s", devname, strerror(errno)); - break; - } - if (fcntl(fd, F_SETFD, 1) < 0) post("couldn't set close-on-exec flag on audio"); - if ((flags = fcntl(fd, F_GETFL)) < 0) post("couldn't get audio device flags"); - else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) post("couldn't set audio device flags"); - if (sys_verbose) post("opened %s for writing only", devname); - } - if (ioctl(fd, SNDCTL_DSP_GETCAPS, &capabilities) == -1) error("OSS: SNDCTL_DSP_GETCAPS failed %s", devname); - gotchans = oss_setchannels(fd, (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels, devname); - if (sys_verbose) post("opened audio output on %s; got %d channels", devname, gotchans); - if (gotchans < 2) { - close(fd); /* can't even do stereo? just give up. */ - } else { - linux_dacs[linux_noutdevs].nchannels = gotchans; - linux_dacs[linux_noutdevs].fd = fd; - oss_configure(&linux_dacs[linux_noutdevs], rate, 1, 0); - linux_noutdevs++; - outchannels += gotchans; - if (inindex >= 0) { - linux_adcs[inindex].nchannels = gotchans; - chin[inindex] = gotchans; - } - } - /* LATER think about spreading large numbers of channels over various dsp's and vice-versa */ - wantmore = wantchannels - gotchans; - end_out_loop: ; - } - /* open input devices */ - wantmore = 0; - for (int n=0; n<nindev; n++) { - int gotchans=0; - int thisdevice = (indev[n] >= 0 ? indev[n] : 0); - int wantchannels = (nchin>n)?chin[n]:wantmore; - int alreadyopened = 0; - if (!wantchannels) goto end_in_loop; - if (thisdevice > 0) sprintf(devname, "/dev/dsp%d", thisdevice); else sprintf(devname, "/dev/dsp"); - sys_setalarm(1000000); - /* perhaps it's already open from the above? */ - if (linux_dacs[n].fd >= 0) { - fd = linux_adcs[n].fd; - alreadyopened = 1; - } else { - /* otherwise try to open it here. */ - if ((fd = open(devname, O_RDONLY | O_AUDIOFLAG)) == -1) { - post("%s (readonly): %s", devname, strerror(errno)); - goto end_in_loop; - } - if (fcntl(fd, F_SETFD, 1) < 0) post("couldn't set close-on-exec flag on audio"); - if ((flags = fcntl(fd, F_GETFL)) < 0) post("couldn't get audio device flags"); - else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) post("couldn't set audio device flags"); - if (sys_verbose) post("opened %s for reading only", devname); - } - linux_adcs[linux_nindevs].fd = fd; - gotchans = oss_setchannels(fd, (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels, devname); - if (sys_verbose) post("opened audio input device %s; got %d channels", devname, gotchans); - if (gotchans < 1) { - close(fd); - goto end_in_loop; - } - linux_adcs[linux_nindevs].nchannels = gotchans; - oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened); - inchannels += gotchans; - linux_nindevs++; - wantmore = wantchannels-gotchans; - /* LATER think about spreading large numbers of channels over various dsp's and vice-versa */ - end_in_loop: ; - } - /* We have to do a read to start the engine. This is necessary because sys_send_dacs waits until the input - buffer is filled and only reads on a filled buffer. This is good, because it's a way to make sure that we - will not block. But I wonder why we only have to read from one of the devices and not all of them??? */ - if (linux_nindevs) { - if (sys_verbose) post("OSS: issuing first ADC 'read'..."); - read2(linux_adcs[0].fd, buf, linux_adcs[0].bytespersamp * linux_adcs[0].nchannels * sys_dacblocksize); - if (sys_verbose) post("...done."); - } - /* now go and fill all the output buffers. */ - for (int i=0; i<linux_noutdevs; i++) { - t_oss_dev &d = linux_dacs[i]; - memset(buf, 0, d.bytespersamp * d.nchannels * sys_dacblocksize); - for (int j=0; j<sys_advance_samples/sys_dacblocksize; j++) - write2(d.fd, buf, d.bytespersamp * d.nchannels * sys_dacblocksize); - } - sys_setalarm(0); - sys_inchannels = inchannels; - sys_outchannels = outchannels; - return 0; -} - -void oss_close_audio() { - for (int i=0;i<linux_nindevs ;i++) close(linux_adcs[i].fd); - for (int i=0;i<linux_noutdevs;i++) close(linux_dacs[i].fd); - linux_nindevs = linux_noutdevs = 0; -} - -static int linux_dacs_write(int fd,void *buf,long bytes) {return write(fd, buf, bytes);} -static int linux_adcs_read (int fd,void *buf,long bytes) {return read(fd, buf, bytes);} - - /* query audio devices for "available" data size. */ -static void oss_calcspace() { - audio_buf_info ainfo; - for (int dev=0; dev<linux_noutdevs; dev++) { - if (ioctl(linux_dacs[dev].fd, SOUND_PCM_GETOSPACE,&ainfo) < 0) - error("OSS: ioctl on output device %d failed (fd=%d)", dev, linux_dacs[dev].fd); - linux_dacs[dev].space = ainfo.bytes; - } - for (int dev=0; dev<linux_nindevs; dev++) { - if (ioctl(linux_adcs[dev].fd, SOUND_PCM_GETISPACE,&ainfo) < 0) - error("OSS: ioctl on input device %d failed (fd=%d)", dev, linux_adcs[dev].fd); - linux_adcs[dev].space = ainfo.bytes; - } -} - -/* this call resyncs audio output and input which will cause discontinuities -in audio output and/or input. */ - -static void oss_doresync() { - int zeroed = 0; - char buf[OSS_MAXSAMPLEWIDTH * sys_dacblocksize * OSS_MAXCHPERDEV]; - audio_buf_info ainfo; - /* 1. if any input devices are ahead (have more than 1 buffer stored), drop one or more buffers worth */ - for (int dev=0; dev<linux_nindevs; dev++) { - t_oss_dev d = linux_adcs[dev]; - if (d.space == 0) { - linux_adcs_read(d.fd, buf, OSS_XFERSIZE(d.nchannels, d.bytespersamp)); - } else while (d.space > OSS_XFERSIZE(d.nchannels, d.bytespersamp)) { - linux_adcs_read(d.fd, buf, OSS_XFERSIZE(d.nchannels, d.bytespersamp)); - if (ioctl(d.fd, SOUND_PCM_GETISPACE, &ainfo) < 0) { error("OSS: ioctl on input device %d, fd %d failed",dev,d.fd); break;} - d.space = ainfo.bytes; - } - } - /* 2. if any output devices are behind, feed them zeros to catch them up */ - for (int dev=0; dev<linux_noutdevs; dev++) { - t_oss_dev d = linux_dacs[dev]; - while (d.space > d.bufsize - sys_advance_samples*d.nchannels*d.bytespersamp) { - if (!zeroed) { - for (unsigned int i=0; i<OSS_XFERSAMPS(d.nchannels); i++) buf[i] = 0; - zeroed = 1; - } - linux_dacs_write(d.fd, buf, OSS_XFERSIZE(d.nchannels, d.bytespersamp)); - if (ioctl(d.fd, SOUND_PCM_GETOSPACE, &ainfo) < 0) {error("OSS: ioctl on output device %d, fd %d failed",dev,d.fd); break;} - d.space = ainfo.bytes; - } - } - /* 3. if any DAC devices are too far ahead, plan to drop the number of frames which will let the others catch up. */ - for (int dev=0; dev<linux_noutdevs; dev++) { - t_oss_dev d = linux_dacs[dev]; - if (d.space > d.bufsize - (sys_advance_samples - 1) * d.nchannels * d.bytespersamp) { - d.dropcount = sys_advance_samples - 1 - (d.space - d.bufsize) / (d.nchannels * d.bytespersamp); - } else d.dropcount = 0; - } -} - -int oss_send_dacs() { - float *fp1, *fp2; - int rtnval = SENDDACS_YES; - char buf[OSS_MAXSAMPLEWIDTH * sys_dacblocksize * OSS_MAXCHPERDEV]; - /* the maximum number of samples we should have in the ADC buffer */ - int idle = 0; - double timeref, timenow; - if (!linux_nindevs && !linux_noutdevs) return SENDDACS_NO; - if (!oss_blockmode) { - /* determine whether we're idle. This is true if either (1) - some input device has less than one buffer to read or (2) some - output device has fewer than (sys_advance_samples) blocks buffered already. */ - oss_calcspace(); - for (int dev=0; dev<linux_noutdevs; dev++) { - t_oss_dev d = linux_dacs[dev]; - if (d.dropcount || (d.bufsize - d.space > sys_advance_samples * d.bytespersamp * d.nchannels)) idle = 1; - } - for (int dev=0; dev<linux_nindevs; dev++) { - t_oss_dev d = linux_adcs[dev]; - if (d.space < OSS_XFERSIZE(d.nchannels, d.bytespersamp)) idle = 1; - } - } - if (idle && !oss_blockmode) { - /* sometimes---rarely---when the ADC available-byte-count is zero, it's genuine, but usually it's because we're so - late that the ADC has overrun its entire kernel buffer. We distinguish between the two by waiting 2 msec and - asking again. There should be an error flag we could check instead; look for this someday... */ - for (int dev=0; dev<linux_nindevs; dev++) if (linux_adcs[dev].space == 0) { - sys_microsleep(sys_sleepgrain); /* tb: changed to sys_sleepgrain */ - oss_calcspace(); - if (linux_adcs[dev].space != 0) continue; - /* here's the bad case. Give up and resync. */ - sys_log_error(ERR_DATALATE); - oss_doresync(); - return SENDDACS_NO; - } - /* check for slippage between devices, either because data got lost in the driver from a previous late condition, - or because the devices aren't synced. When we're idle, no input device should have more than one buffer readable - and no output device should have less than sys_advance_samples-1 */ - for (int dev=0; dev<linux_noutdevs; dev++) { - t_oss_dev d = linux_dacs[dev]; - if (!d.dropcount && (d.bufsize - d.space < (sys_advance_samples - 2)*d.bytespersamp*d.nchannels)) goto badsync; - } - for (int dev=0; dev<linux_nindevs; dev++) - if (linux_adcs[dev].space > 3 * OSS_XFERSIZE(linux_adcs[dev].nchannels, linux_adcs[dev].bytespersamp)) goto badsync; - /* return zero to tell the scheduler we're idle. */ - return SENDDACS_NO; - badsync: - sys_log_error(ERR_RESYNC); - oss_doresync(); - return SENDDACS_NO; - } - /* do output */ - timeref = sys_getrealtime(); - t_oss_int16 *sp; - t_oss_int32 *lp; - for (int dev=0, thischan = 0; dev < linux_noutdevs; dev++) { - t_oss_dev d = linux_dacs[dev]; - int nchannels = d.nchannels; - if (d.dropcount) d.dropcount--; - else { - fp1 = sys_soundout + sys_dacblocksize*thischan; - if (d.bytespersamp == 4) { - lp = (t_oss_int32 *)buf; - for (int i=sys_dacblocksize * nchannels; i--; fp1++, lp++) *lp = int(clip(*fp1*2147483648.,-2147483648.,2147483647.)); - } else { - sp = (t_oss_int16 *)buf; - for (int i=sys_dacblocksize; i--; fp1++, sp += nchannels) { - fp2 = fp1; - for (int j=0; j<nchannels; j++, fp2 += sys_dacblocksize) sp[j] = clip(int(*fp2*32767.),-32768,32767); - } - } - linux_dacs_write(d.fd, buf, OSS_XFERSIZE(nchannels, d.bytespersamp)); - if ((timenow = sys_getrealtime()) - timeref > 0.002) { - if (!oss_blockmode) sys_log_error(ERR_DACSLEPT); else rtnval = SENDDACS_SLEPT; - } - timeref = timenow; - } - thischan += nchannels; - } - memset(sys_soundout, 0, sys_outchannels * (sizeof(float) * sys_dacblocksize)); - for (int dev=0, thischan = 0; dev < linux_nindevs; dev++) { - int nchannels = linux_adcs[dev].nchannels; - linux_adcs_read(linux_adcs[dev].fd, buf, OSS_XFERSIZE(nchannels, linux_adcs[dev].bytespersamp)); - if ((timenow = sys_getrealtime()) - timeref > 0.002) { - if (!oss_blockmode) sys_log_error(ERR_ADCSLEPT); else rtnval = SENDDACS_SLEPT; - } - timeref = timenow; - fp1 = sys_soundin + thischan*sys_dacblocksize; - if (linux_adcs[dev].bytespersamp == 4) { - lp = (t_oss_int32 *)buf; - for (int i=sys_dacblocksize*nchannels; i--; fp1++, lp++) - *fp1 = float(*lp)*float(1./2147483648.); - } else { - sp = (t_oss_int16 *)buf; - for (int i=sys_dacblocksize; i--; fp1++, sp += nchannels) - for (int j=0; j<nchannels; j++) fp1[j*sys_dacblocksize] = (float)sp[j]*(float)3.051850e-05; - } - thischan += nchannels; - } - return rtnval; -} - -void oss_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - int ndev = min(oss_ndev,maxndev); - *canmulti = 2; /* supports multiple devices */ - for (int i=0; i<ndev; i++) { - sprintf(indevlist + i*devdescsize, "OSS device #%d", i+1); - sprintf(outdevlist + i*devdescsize, "OSS device #%d", i+1); - } - *nindevs = *noutdevs = ndev; -} - -struct t_audioapi oss_api = { - oss_open_audio, - oss_close_audio, - oss_send_dacs, - oss_getdevs, -}; diff --git a/desiredata/src/s_audio_pa.c b/desiredata/src/s_audio_pa.c deleted file mode 100644 index d6a086b3..00000000 --- a/desiredata/src/s_audio_pa.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Copyright (c) 2001 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's - the main way in for Mac OS and, with Michael Casey's help, also into ASIO in Windows. */ - -/* tb: requires portaudio >= V19 */ - -#include "desire.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <portaudio.h> -#include <errno.h> - -#ifdef MSW -/* jmz thinks that we have to include: - * on Windows: <malloc.h> (probably this is already included?) - * on linux: <alloca.h> (might be true for osX too, no way to check right now...) - */ -# include <malloc.h> -#else -# include <alloca.h> -#endif - -#ifdef MSW -#include "pthread.h" /* for ETIMEDOUT */ -#endif - -#define MAX_PA_CHANS 32 - -/* portaudio's blocking api is not working, yet: */ -/* #define PABLOCKING */ - -//#ifndef PABLOCKING -#include "s_audio_pablio.h" -//#endif - -static int pa_inchans, pa_outchans; - -static PaStream *pa_stream; -static PABLIO_Stream *pablio_stream; -static PaStreamCallback *pa_callback = NULL; - -int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, -PaStreamCallbackFlags statusFlags, void *userData); - -/*int naudioindev, int * audioindev, int nchindev, int * chindev, -int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int dummy*/ -int pa_open_audio(int inchans, int outchans, int rate, int advance, int indeviceno, int outdeviceno, int schedmode) { - PaError err; - int j, devno, pa_indev = -1, pa_outdev = -1; - pa_callback = schedmode==1 ? process : NULL; - sys_setscheduler(schedmode); - /* Initialize PortAudio */ - err = Pa_Initialize(); - if (err != paNoError) { - error("Error number %d occured initializing portaudio: %s", err, Pa_GetErrorText(err)); - return 1; - } - /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */ - if ( inchans > MAX_PA_CHANS) {post( "input channels reduced to maximum %d", MAX_PA_CHANS); inchans = MAX_PA_CHANS;} - if (outchans > MAX_PA_CHANS) {post("output channels reduced to maximum %d", MAX_PA_CHANS); outchans = MAX_PA_CHANS;} - if (inchans > 0) { - for (j = 0, devno = 0; j < Pa_GetDeviceCount(); j++) { - const PaDeviceInfo *info = Pa_GetDeviceInfo(j); - int maxchans = info->maxInputChannels; - if (maxchans > 0) { - if (devno == indeviceno) { - if (maxchans < inchans) inchans = maxchans; - pa_indev = j; - break; - } - devno++; - } - } - } - if (outchans > 0) { - for (j = 0, devno = 0; j < Pa_GetDeviceCount(); j++) { - const PaDeviceInfo *info = Pa_GetDeviceInfo(j); - int maxchans = info->maxOutputChannels; - if (maxchans > 0) { - if (devno == outdeviceno) { - if (maxchans < outchans) outchans = maxchans; - pa_outdev = j; - break; - } - devno++; - } - } - } - if (sys_verbose) { - post( "input device %d, channels %d", pa_indev, inchans); - post("output device %d, channels %d", pa_outdev, outchans); - post("latency advance %d", advance); - } - if (inchans || outchans) { -#ifndef PABLOCKING - if (schedmode == 1) { -#endif - PaStreamParameters inputParameters, outputParameters; - /* initialize input */ - inputParameters.device = pa_indev ; - inputParameters.channelCount = inchans; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; - inputParameters.suggestedLatency = advance * 0.001; - inputParameters.hostApiSpecificStreamInfo = NULL; - /* initialize output */ - outputParameters.device = pa_outdev; - outputParameters.channelCount = outchans; - outputParameters.sampleFormat = paFloat32 | paNonInterleaved; - outputParameters.suggestedLatency = advance * 0.001; - outputParameters.hostApiSpecificStreamInfo = NULL; - /* report to portaudio */ - err = Pa_OpenStream(&pa_stream, - ( pa_indev!=-1 ? &inputParameters : 0), - (pa_outdev!=-1 ? &outputParameters : 0), - rate, sys_dacblocksize, paClipOff, /* tb: we should be faster ;-) */ pa_callback, NULL); - if (err == paNoError) { - const PaStreamInfo * streaminfo = Pa_GetStreamInfo (pa_stream); - sys_schedadvance = 1e6 * streaminfo->outputLatency; - } -#ifndef PABLOCKING - } else { - int nbuffers = sys_advance_samples / sys_dacblocksize; - err = PD_OpenAudioStream( &pablio_stream, rate, paFloat32, - inchans, outchans, sys_dacblocksize, nbuffers, pa_indev, pa_outdev); - } -#endif - } else err = 0; - if (err != paNoError) { - post("Error number %d occured opening portaudio stream", err); - post("Error message: %s", Pa_GetErrorText(err)); - Pa_Terminate(); - sys_inchannels = sys_outchannels = 0; - return 1; - } else if (sys_verbose) post("... opened OK."); - pa_inchans = inchans; - pa_outchans = outchans; -#ifndef PABLOCKING - if (schedmode) -#endif - err = Pa_StartStream(pa_stream); - if (err != paNoError) { - post("Error number %d occured starting portaudio stream", err); - post("Error message: %s", Pa_GetErrorText(err)); - Pa_Terminate(); - sys_inchannels = sys_outchannels = 0; - return 1; - } - post("successfully started"); - return 0; -} - -void sys_peakmeters(void); -extern int sys_meters; /* true if we're metering */ - -int process (const void *input, void *output, unsigned long frameCount, -const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { - int i,j; - int timeout = (float)frameCount / (float) sys_dacsr * 1e6; - if (sys_timedlock(timeout) == ETIMEDOUT) /* we're late */ { - post("timeout %d", timeout); - sys_log_error(ERR_SYSLOCK); - return 0; - } - for (int j=0; j<sys_inchannels; j++) { - t_sample * in = ((t_sample**)input)[j]; - copyvec( sys_soundin + j * sys_dacblocksize,in,sys_dacblocksize); - } - sched_tick(sys_time + sys_time_per_dsp_tick); - for (int j=0; j<sys_outchannels; j++) { - t_sample *out = ((t_sample**)output)[j]; - copyvec(out,sys_soundout + j * sys_dacblocksize, sys_dacblocksize); - } - /* update peak meters */ - if (sys_meters) sys_peakmeters(); - /* clear the output buffer */ - zerovec(sys_soundout, pa_outchans * sys_dacblocksize); - sys_unlock(); - return 0; -} - -void pa_close_audio() { - post("closing portaudio"); - if (pa_inchans || pa_outchans) { - if (pa_stream) { - Pa_StopStream(pa_stream); - Pa_CloseStream(pa_stream); - pa_stream = NULL; - } - if (pablio_stream) { - PD_CloseAudioStream(pablio_stream); - pablio_stream = NULL; - } - } - post("portaudio closed"); - pa_inchans = pa_outchans = 0; -} - -/* for blocked IO */ -int pa_send_dacs() { -#ifdef PABLOCKING /* tb: blocking IO isn't really working for v19 yet */ - double timenow, timebefore; - if (( pa_inchans && Pa_GetStreamReadAvailable(pa_stream) < sys_dacblocksize*0.8) && - (pa_outchans && Pa_GetStreamWriteAvailable(pa_stream) < sys_dacblocksize*0.8)) { - /* we can't transfer data ... wait in the scheduler */ - return SENDDACS_NO; - } - timebefore = sys_getrealtime(); - if (pa_outchans) Pa_WriteStream(pa_stream, &sys_soundout, sys_dacblocksize); - if ( pa_inchans) Pa_ReadStream(pa_stream, &sys_soundin, sys_dacblocksize); - zerovec(sys_soundout, pa_inchans * sys_dacblocksize); - while (( pa_inchans && Pa_GetStreamReadAvailable(pa_stream) < sys_dacblocksize*0.8) && - (pa_outchans && Pa_GetStreamWriteAvailable(pa_stream) < sys_dacblocksize*0.8)) { - if (pa_outchans) Pa_WriteStream(pa_stream, &sys_soundout, sys_dacblocksize); - if ( pa_inchans) Pa_ReadStream(pa_stream, &sys_soundin, sys_dacblocksize); - zerovec(sys_soundout, pa_inchans * sys_dacblocksize); - sched_tick(sys_time + sys_time_per_dsp_tick); - } - if (sys_getrealtime() > timebefore + sys_sleepgrain * 1e-6) { - return SENDDACS_SLEPT; - } else return SENDDACS_YES; -#else /* for now we're using pablio */ - float *samples, *fp1, *fp2; - int i, j; - double timebefore; - samples=(float*)alloca(sizeof(float) * MAX_PA_CHANS * sys_dacblocksize); - timebefore = sys_getrealtime(); - if ((pa_inchans && PD_GetAudioStreamReadable(pablio_stream) < sys_dacblocksize) || - (pa_outchans && PD_GetAudioStreamWriteable(pablio_stream) < sys_dacblocksize)) { - if (pa_inchans && pa_outchans) { - int synced = 0; - while (PD_GetAudioStreamWriteable(pablio_stream) > 2*sys_dacblocksize) { - for (j = 0; j < pa_outchans; j++) - for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_outchans) - *fp2 = 0; - synced = 1; - PD_WriteAudioStream(pablio_stream, samples, sys_dacblocksize); - } - while (PD_GetAudioStreamReadable(pablio_stream) > 2*sys_dacblocksize) { - synced = 1; - PD_ReadAudioStream(pablio_stream, samples, sys_dacblocksize); - } -/* if (synced) post("sync"); */ - } - return SENDDACS_NO; - } - if (pa_inchans) { - PD_ReadAudioStream(pablio_stream, samples, sys_dacblocksize); - for (j = 0, fp1 = sys_soundin; j < pa_inchans; j++, fp1 += sys_dacblocksize) - for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_inchans) - fp1[i] = *fp2; - } - if (pa_outchans) { - for (j = 0, fp1 = sys_soundout; j < pa_outchans; j++, fp1 += sys_dacblocksize) - for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_outchans) { - *fp2 = fp1[i]; - fp1[i] = 0; - } - PD_WriteAudioStream(pablio_stream, samples, sys_dacblocksize); - } - if (sys_getrealtime() > timebefore + sys_sleepgrain * 1e-6) { - /* post("slept"); */ - return SENDDACS_SLEPT; - } else return SENDDACS_YES; -#endif -} - -void pa_listdevs() /* lifted from pa_devs.c in portaudio */ { - int j, numDevices; - const PaDeviceInfo *pdi; - PaError err; - Pa_Initialize(); - numDevices = Pa_GetDeviceCount(); - if (numDevices<0) { - error("ERROR: Pa_GetDeviceCount returned %d", numDevices); - err = numDevices; - goto error; - } - post("Audio Devices:"); - for (int i=0; i<numDevices; i++) { - const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i); - post("device %s", pdi->name); - post("device %d:", i+1); - post(" %s;", pdi->name); - post("%d inputs, ", pdi->maxInputChannels); - post("%d outputs", pdi->maxOutputChannels); -#ifdef PA19 - if (i == Pa_GetDefaultInputDevice ()) post(" (Default Input)"); - if (i == Pa_GetDefaultOutputDevice()) post(" (Default Output)"); -#else - if (i == Pa_GetDefaultInputDeviceID ()) post(" (Default Input)"); - if (i == Pa_GetDefaultOutputDeviceID()) post(" (Default Output)"); -#endif - post(""); - } - post(""); - return; -error: - error("An error occured while using the portaudio stream: #%d: %s",err,Pa_GetErrorText(err)); -} -/* scanning for devices */ -void pa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - int i, nin = 0, nout = 0, ndev; - *canmulti = 1; /* one dev each for input and output */ - Pa_Initialize(); - ndev = Pa_GetDeviceCount(); - for (i = 0; i < ndev; i++) { - const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i); - if (pdi->maxInputChannels > 0 && nin < maxndev) { - sprintf(indevlist + nin * devdescsize, "(%d)%s", pdi->hostApi,pdi->name); - /* strcpy(indevlist + nin * devdescsize, pdi->name); */ - nin++; - } - if (pdi->maxOutputChannels > 0 && nout < maxndev) { - sprintf(outdevlist + nout * devdescsize, "(%d)%s", pdi->hostApi,pdi->name); - /* strcpy(outdevlist + nout * devdescsize, pdi->name); */ - nout++; - } - } - *nindevs = nin; - *noutdevs = nout; -} - -t_audioapi pa_api = { - pa_open_audio, - pa_close_audio, - pa_send_dacs, - pa_getdevs, -}; diff --git a/desiredata/src/s_audio_pablio.c b/desiredata/src/s_audio_pablio.c deleted file mode 100644 index 5915250b..00000000 --- a/desiredata/src/s_audio_pablio.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * $Id: s_audio_pablio.c,v 1.1.4.2.2.4.2.2 2007-07-30 22:19:11 matju Exp $ - * pablio.c - * Portable Audio Blocking Input/Output utility. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - - /* changes by Miller Puckette to support Pd: device selection, - settable audio buffer size, and settable number of channels. - LATER also fix it to poll for input and output fifo fill points. */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "portaudio.h" -#include "s_audio_paring.h" -#include "s_audio_pablio.h" /* MSP */ -#include <string.h> - - /* MSP -- FRAMES_PER_BUFFER constant removed */ -static void NPa_Sleep(int n) { /* MSP wrapper to check we never stall... */ -#if 0 - post("sleep"); -#endif - Pa_Sleep(n); -} - -/************************************************************************/ -/******** Prototypes ****************************************************/ -/************************************************************************/ - -#ifdef PA19 -static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /*MSP */ - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo *outTime, - PaStreamCallbackFlags myflags, - void *userData ); -#else -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -#endif -static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame ); -static PaError PABLIO_TermFIFO( RingBuffer *rbuf ); - -/************************************************************************/ -/******** Functions *****************************************************/ -/************************************************************************/ - -/* Called from PortAudio. - * Read and write data only if there is room in FIFOs. - */ -#ifdef PA19 -static int blockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, -const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, void *userData) -#else -static int blockingIOCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, -PaTimestamp outTime, void *userData ) -#endif -{ - PABLIO_Stream *data = (PABLIO_Stream*)userData; -// (void) outTime; - /* This may get called with NULL inputBuffer during initial setup. */ - if (inputBuffer) PD_RingBuffer_Write( &data->inFIFO, inputBuffer, data->inbytesPerFrame * framesPerBuffer ); - if (outputBuffer) { - int numBytes = data->outbytesPerFrame * framesPerBuffer; - int numRead = PD_RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes); - /* Zero out remainder of buffer if we run out of data. */ - for (int i=numRead; i<numBytes; i++) ((char *)outputBuffer)[i] = 0; - } - return 0; -} - -/* Allocate buffer. */ -static PaError PABLIO_InitFIFO(RingBuffer *rbuf, long numFrames, long bytesPerFrame) { - long numBytes = numFrames * bytesPerFrame; - char *buffer = (char *)malloc(numBytes); - if (!buffer) return paInsufficientMemory; - memset(buffer, 0, numBytes); - return (PaError) PD_RingBuffer_Init(rbuf, numBytes, buffer); -} - -/* Free buffer. */ -static PaError PABLIO_TermFIFO(RingBuffer *rbuf) { - if (rbuf->buffer) free(rbuf->buffer); - rbuf->buffer = NULL; - return paNoError; -} - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long PD_WriteAudioStream(PABLIO_Stream *aStream, void *data, long numFrames) { - long bytesWritten; - char *p = (char *) data; - long numBytes = aStream->outbytesPerFrame * numFrames; - while (numBytes > 0) { - bytesWritten = PD_RingBuffer_Write(&aStream->outFIFO, p, numBytes); - numBytes -= bytesWritten; - p += bytesWritten; - if (numBytes>0) NPa_Sleep(10); /* MSP */ - } - return numFrames; -} - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long PD_ReadAudioStream(PABLIO_Stream *aStream, void *data, long numFrames) { - char *p = (char *)data; - long numBytes = aStream->inbytesPerFrame * numFrames; - while (numBytes > 0) { - long bytesRead = PD_RingBuffer_Read(&aStream->inFIFO, p, numBytes); - numBytes -= bytesRead; - p += bytesRead; - if (numBytes > 0) NPa_Sleep(10); /* MSP */ - } - return numFrames; -} - -/* Return the number of frames that could be written to the stream without having to wait. */ -long PD_GetAudioStreamWriteable(PABLIO_Stream *aStream) { - int bytesEmpty = PD_RingBuffer_GetWriteAvailable(&aStream->outFIFO); - return bytesEmpty / aStream->outbytesPerFrame; -} - -/* Return the number of frames that are available to be read from the stream without having to wait. */ -long PD_GetAudioStreamReadable(PABLIO_Stream *aStream) { - int bytesFull = PD_RingBuffer_GetReadAvailable(&aStream->inFIFO); - return bytesFull / aStream->inbytesPerFrame; -} - -static unsigned long RoundUpToNextPowerOf2(unsigned long n) { - long numBits = 0; - if( ((n-1) & n) == 0) return n; /* Already Power of two. */ - while(n > 0) { - n= n>>1; - numBits++; - } - return 1<<numBits; -} - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * flags parameter can be an ORed combination of: - * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE */ -PaError PD_OpenAudioStream(PABLIO_Stream **rwblPtr, double sampleRate, PaSampleFormat format, int inchannels, -int outchannels, int framesperbuf, int nbuffers, int indeviceno, int outdeviceno) { - long bytesPerSample; - long doRead = 0; - long doWrite = 0; - PaError err; - PABLIO_Stream *aStream; - long minNumBuffers; - long numFrames; -#ifdef PA19 - PaStreamParameters instreamparams, outstreamparams; /* MSP */ -#endif - /* post("open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d", - sampleRate, format, flags, nchannels, framesperbuf, nbuffers, indeviceno, outdeviceno); */ - if (indeviceno < 0) { -#ifdef PA19 - indeviceno = Pa_GetDefaultInputDevice(); -#else - indeviceno = Pa_GetDefaultInputDeviceID(); -#endif - if (indeviceno == paNoDevice) inchannels = 0; - post("using default input device number: %d", indeviceno); - } - if (outdeviceno<0) { -#ifdef PA19 - outdeviceno = Pa_GetDefaultOutputDevice(); -#else - outdeviceno = Pa_GetDefaultOutputDeviceID(); -#endif - if(outdeviceno == paNoDevice) outchannels = 0; - post("using default output device number: %d", outdeviceno); - } - /* post("nchan %d, flags %d, bufs %d, framesperbuf %d", nchannels, flags, nbuffers, framesperbuf); */ - /* Allocate PABLIO_Stream structure for caller. */ - aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream)); - if( aStream == NULL ) return paInsufficientMemory; - memset(aStream, 0, sizeof(PABLIO_Stream)); - /* Determine size of a sample. */ - bytesPerSample = Pa_GetSampleSize(format); - if (bytesPerSample<0) {err = (PaError) bytesPerSample; goto error;} - aStream-> insamplesPerFrame = inchannels; aStream-> inbytesPerFrame = bytesPerSample * aStream-> insamplesPerFrame; - aStream->outsamplesPerFrame = outchannels; aStream->outbytesPerFrame = bytesPerSample * aStream->outsamplesPerFrame; - err = Pa_Initialize(); - if (err != paNoError) goto error; -#ifdef PA19 - numFrames = nbuffers * framesperbuf; /* ...MSP */ - instreamparams.device = indeviceno; /* MSP... */ - instreamparams.channelCount = inchannels; - instreamparams.sampleFormat = format; - instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; - instreamparams.hostApiSpecificStreamInfo = 0; - outstreamparams.device = outdeviceno; - outstreamparams.channelCount = outchannels; - outstreamparams.sampleFormat = format; - outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; - outstreamparams.hostApiSpecificStreamInfo = 0; /* ... MSP */ -#else -/* Warning: numFrames must be larger than amount of data processed per - interrupt inside PA to prevent glitches. */ /* MSP */ - minNumBuffers = Pa_GetMinNumBuffers(framesperbuf, sampleRate); - if (minNumBuffers > nbuffers) - post("warning: number of buffers %d less than recommended minimum %d", (int)nbuffers, (int)minNumBuffers); -#endif - numFrames = nbuffers * framesperbuf; - /* post("numFrames %d", numFrames); */ - /* Initialize Ring Buffers */ - doRead = (inchannels != 0); - doWrite = (outchannels != 0); - if(doRead) { - err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->inbytesPerFrame); - if (err != paNoError) goto error; - } - if(doWrite) { - long numBytes; - err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->outbytesPerFrame); - if (err != paNoError) goto error; - /* Make Write FIFO appear full initially. */ - numBytes = PD_RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - PD_RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes ); - } - -/* Open a PortAudio stream that we will use to communicate with the underlying audio drivers. */ -#ifdef PA19 - err = Pa_OpenStream(&aStream->stream, (doRead ? &instreamparams : 0), (doWrite ? &outstreamparams : 0), - sampleRate, framesperbuf, paNoFlag, blockingIOCallback, aStream); -#else - err = Pa_OpenStream(&aStream->stream, - (doRead ? indeviceno : paNoDevice), (doRead ? aStream->insamplesPerFrame : 0 ), format, NULL, - (doWrite ? outdeviceno : paNoDevice), (doWrite ? aStream->outsamplesPerFrame : 0 ), format, NULL, - sampleRate, framesperbuf, nbuffers, paNoFlag, blockingIOCallback, aStream); -#endif - if (err != paNoError) goto error; - err = Pa_StartStream( aStream->stream ); - if (err != paNoError) { - error("Pa_StartStream failed; closing audio stream..."); - PD_CloseAudioStream(aStream); - goto error; - } - *rwblPtr = aStream; - return paNoError; -error: - *rwblPtr = NULL; - return err; -} - -/************************************************************/ -PaError PD_CloseAudioStream(PABLIO_Stream *aStream) { - PaError err; - int bytesEmpty; - int byteSize = aStream->outFIFO.bufferSize; - /* If we are writing data, make sure we play everything written. */ - if (byteSize>0) { - bytesEmpty = PD_RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - while (bytesEmpty<byteSize) { - NPa_Sleep( 10 ); /* MSP */ - bytesEmpty = PD_RingBuffer_GetWriteAvailable( &aStream->outFIFO ); - } - } - err = Pa_StopStream(aStream->stream); if(err != paNoError) goto error; - err = Pa_CloseStream(aStream->stream); if(err != paNoError) goto error; - Pa_Terminate(); -error: - PABLIO_TermFIFO(&aStream->inFIFO); - PABLIO_TermFIFO(&aStream->outFIFO); - free(aStream); - return err; -} diff --git a/desiredata/src/s_audio_pablio.h b/desiredata/src/s_audio_pablio.h deleted file mode 100644 index 1a1ecb8d..00000000 --- a/desiredata/src/s_audio_pablio.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef _PD_PABLIO_H -#define _PD_PABLIO_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: s_audio_pablio.h,v 1.1.4.1.2.3 2006-01-24 01:29:54 xovo Exp $ - * PABLIO.h - * Portable Audio Blocking read/write utility. - * - * Author: Phil Burk, http://www.softsynth.com/portaudio/ - * - * Include file for PABLIO, the Portable Audio Blocking I/O Library. - * PABLIO is built on top of PortAudio, the Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <portaudio.h> -#include "s_audio_paring.h" -#include <string.h> - -typedef struct -{ - RingBuffer inFIFO; - RingBuffer outFIFO; - PaStream *stream; - int inbytesPerFrame; - int insamplesPerFrame; - int outbytesPerFrame; - int outsamplesPerFrame; -} -PABLIO_Stream; - -/* Values for flags for OpenAudioStream(). */ -#define PABLIO_READ (1<<0) -#define PABLIO_WRITE (1<<1) -#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE) -#define PABLIO_MONO (1<<2) -#define PABLIO_STEREO (1<<3) - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long PD_WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ); - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long PD_ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames ); - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long PD_GetAudioStreamWriteable( PABLIO_Stream *aStream ); - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long PD_GetAudioStreamReadable( PABLIO_Stream *aStream ); - -/************************************************************ - * Opens a PortAudio stream with default characteristics. - * Allocates PABLIO_Stream structure. - * - * flags parameter can be an ORed combination of: - * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE, - */ -PaError PD_OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, - PaSampleFormat format, int inchannels, - int outchannels, int framesperbuf, int nbuffers, - int indeviceno, int outdeviceno); /* MSP */ - -PaError PD_CloseAudioStream( PABLIO_Stream *aStream ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PD_PABLIO_H */ diff --git a/desiredata/src/s_audio_paring.c b/desiredata/src/s_audio_paring.c deleted file mode 100644 index dcdcce0e..00000000 --- a/desiredata/src/s_audio_paring.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * $Id: s_audio_paring.c,v 1.1.4.1.2.1.2.1 2007-07-31 00:10:37 matju Exp $ - * ringbuffer.c - * Ring Buffer utility.. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * modified 2002/07/13 by olaf.matthes@gmx.de to allow any number if channels - */ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include "s_audio_paring.h" -#include <string.h> - -/* Initialize FIFO. */ -long PD_RingBuffer_Init(RingBuffer *rbuf, long numBytes, void *dataPtr) { - rbuf->bufferSize = numBytes; - rbuf->buffer = (char *)dataPtr; - PD_RingBuffer_Flush( rbuf ); - return 0; -} -/*************************************************************************** -** Return number of bytes available for reading. */ -long PD_RingBuffer_GetReadAvailable(RingBuffer *rbuf) { - long ret = rbuf->writeIndex - rbuf->readIndex; - if (ret < 0) ret += 2 * rbuf->bufferSize; - if (ret < 0 || ret > rbuf->bufferSize) error("consistency check failed: PD_RingBuffer_GetReadAvailable"); - return ret; -} -/* Return number of bytes available for writing. */ -long PD_RingBuffer_GetWriteAvailable(RingBuffer *rbuf) { - return rbuf->bufferSize - PD_RingBuffer_GetReadAvailable(rbuf); -} - -/* Clear buffer. Should only be called when buffer is NOT being read. */ -void PD_RingBuffer_Flush(RingBuffer *rbuf) { - rbuf->writeIndex = rbuf->readIndex = 0; -} - -/* Get address of region(s) to which we can write data. If the region is contiguous, size2 will be zero. - If non-contiguous, size2 will be the size of second region. - Returns room available to be written or numBytes, whichever is smaller. */ -long PD_RingBuffer_GetWriteRegions(RingBuffer *rbuf, long numBytes, -void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2) { - long index; - long available = PD_RingBuffer_GetWriteAvailable(rbuf); - if (numBytes > available) numBytes = available; - /* Check to see if write is not contiguous. */ - index = rbuf->writeIndex; - while (index >= rbuf->bufferSize) index -= rbuf->bufferSize; - if ((index + numBytes) > rbuf->bufferSize) { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } else { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} - - -/*************************************************************************** -*/ -long PD_RingBuffer_AdvanceWriteIndex(RingBuffer *rbuf, long numBytes) { - long ret = rbuf->writeIndex + numBytes; - if (ret >= 2 * rbuf->bufferSize) ret -= 2 * rbuf->bufferSize; /* check for end of buffer */ - return rbuf->writeIndex = ret; -} - -/*************************************************************************** -** Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long PD_RingBuffer_GetReadRegions(RingBuffer *rbuf, long numBytes, -void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2) { - long index; - long available = PD_RingBuffer_GetReadAvailable(rbuf); - if (numBytes > available) numBytes = available; - /* Check to see if read is not contiguous. */ - index = rbuf->readIndex; - while (index >= rbuf->bufferSize) index -= rbuf->bufferSize; - if ((index + numBytes) > rbuf->bufferSize) { - /* Write data in two blocks that wrap the buffer. */ - long firstHalf = rbuf->bufferSize - index; - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = firstHalf; - *dataPtr2 = &rbuf->buffer[0]; - *sizePtr2 = numBytes - firstHalf; - } else { - *dataPtr1 = &rbuf->buffer[index]; - *sizePtr1 = numBytes; - *dataPtr2 = NULL; - *sizePtr2 = 0; - } - return numBytes; -} - -long PD_RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes ) { - long ret = (rbuf->readIndex + numBytes); - if( ret >= 2 * rbuf->bufferSize) ret -= 2 * rbuf->bufferSize; - return rbuf->readIndex = ret; -} - -/* Return bytes written. */ -long PD_RingBuffer_Write(RingBuffer *rbuf, const void *data, long numBytes) { - long size1, size2, numWritten; - void *data1, *data2; - numWritten = PD_RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); - if (size2 > 0) { - memcpy(data1, data, size1); - data = ((char *)data) + size1; - memcpy(data2, data, size2); - } else { - memcpy(data1, data, size1); - } - PD_RingBuffer_AdvanceWriteIndex( rbuf, numWritten ); - return numWritten; -} - -/* Return bytes read. */ -long PD_RingBuffer_Read(RingBuffer *rbuf, void *data, long numBytes) { - long size1, size2, numRead; - void *data1, *data2; - numRead = PD_RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); - if (size2 > 0) { - memcpy(data, data1, size1); - data = ((char *)data) + size1; - memcpy(data, data2, size2); - } else { - memcpy(data, data1, size1); - } - PD_RingBuffer_AdvanceReadIndex( rbuf, numRead ); - return numRead; -} diff --git a/desiredata/src/s_audio_paring.h b/desiredata/src/s_audio_paring.h deleted file mode 100644 index 5415f64a..00000000 --- a/desiredata/src/s_audio_paring.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef _PD_RINGBUFFER_H -#define _PD_RINGBUFFER_H -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * $Id: s_audio_paring.h,v 1.1.4.1.2.3 2006-01-24 01:29:54 xovo Exp $ - * ringbuffer.h - * Ring Buffer utility.. - * - * Author: Phil Burk, http://www.softsynth.com - * - * This program is distributed with the PortAudio Portable Audio Library. - * For more information see: http://www.audiomulch.com/portaudio/ - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> - -typedef struct -{ - long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */ -/* These are declared volatile because they are written by a different thread than the reader. */ - volatile long writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */ - volatile long readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */ - long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */ - long smallMask; /* Used for fitting indices to buffer. */ - char *buffer; -} -RingBuffer; -/* - * Initialize Ring Buffer. - * numBytes must be power of 2, returns -1 if not. - */ -long PD_RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr ); - -/* Clear buffer. Should only be called when buffer is NOT being read. */ -void PD_RingBuffer_Flush( RingBuffer *rbuf ); - -/* Return number of bytes available for writing. */ -long PD_RingBuffer_GetWriteAvailable( RingBuffer *rbuf ); -/* Return number of bytes available for read. */ -long PD_RingBuffer_GetReadAvailable( RingBuffer *rbuf ); -/* Return bytes written. */ -long PD_RingBuffer_Write( RingBuffer *rbuf, const void *data, long numBytes ); -/* Return bytes read. */ -long PD_RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes ); - -/* Get address of region(s) to which we can write data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be written or numBytes, whichever is smaller. -*/ -long PD_RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ); -long PD_RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes ); - -/* Get address of region(s) from which we can read data. -** If the region is contiguous, size2 will be zero. -** If non-contiguous, size2 will be the size of second region. -** Returns room available to be read or numBytes, whichever is smaller. -*/ -long PD_RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes, - void **dataPtr1, long *sizePtr1, - void **dataPtr2, long *sizePtr2 ); - -long PD_RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _PD_RINGBUFFER_H */ diff --git a/desiredata/src/s_audio_portaudio.c b/desiredata/src/s_audio_portaudio.c deleted file mode 100755 index dbb59982..00000000 --- a/desiredata/src/s_audio_portaudio.c +++ /dev/null @@ -1,413 +0,0 @@ -/* Copyright (c) 2001 Miller Puckette and others. - * Copyright (c) 2005-2006 Tim Blechmann - * supported by vibrez.net - * For information on usage and redistribution, and for a DISCLAIMER OF ALL - * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's - the main way in for Mac OS and, with Michael Casey's help, also into - ASIO in Windows. */ - -/* tb: requires portaudio >= V19 */ - -#include "desire.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <portaudio.h> -#include <errno.h> -#include "assert.h" -#ifdef MSW -# include <malloc.h> -# include <pa_asio.h> -#else -# include <alloca.h> -#endif -#include "pthread.h" -/* for M_PI */ -#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) -#define _USE_MATH_DEFINES -#endif -#include <math.h> -#define MAX_PA_CHANS 32 - -static int pa_inchans, pa_outchans; -static int pa_blocksize; - -static PaStream *pa_stream; -/* Initialize PortAudio */ -PaError pa_status = -1; -int pa_initialized = 0; - -void pa_initialize() { -// if (pa_initialized) return; - pa_status = Pa_Initialize(); - if (pa_status!=paNoError) { - error("Error number %d occured initializing portaudio: %s", pa_status, Pa_GetErrorText(pa_status)); - return; - } - pa_initialized = 1; -} - -static float* pa_inbuffer[MAX_PA_CHANS]; -static float* pa_outbuffer[MAX_PA_CHANS]; -static int pa_bufferpos; -static int pddev2padev(int pdindev,int isinput); -static int padev2pddev(int padev,int isinput); -int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, void *userData); - -static int pa_indev = -1, pa_outdev = -1; - -int pa_open_audio(int inchans, int outchans, int rate, int advance, -int indeviceno, int outdeviceno, int schedmode) { - PaError err; - const PaDeviceInfo *pdi,*pdo; - schedmode = 1; /* we don't support blocking io */ - pa_initialize(); - sys_setscheduler(schedmode); - /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */ - if ( inchans > MAX_PA_CHANS) {post( "input channels reduced to maximum %d", MAX_PA_CHANS); inchans = MAX_PA_CHANS;} - if (outchans > MAX_PA_CHANS) {post("output channels reduced to maximum %d", MAX_PA_CHANS); outchans = MAX_PA_CHANS;} - pdi = NULL; - if (inchans > 0) { - pa_indev = pddev2padev(indeviceno,1); - if(pa_indev >= 0) { - pdi = Pa_GetDeviceInfo(pa_indev); - if(pdi->maxInputChannels < inchans) inchans = pdi->maxInputChannels; - } - } - pdo = NULL; - if (outchans > 0) { - pa_outdev = pddev2padev(outdeviceno,0); - if(pa_outdev >= 0) { - pdo = Pa_GetDeviceInfo(pa_outdev); - if(pdo->maxOutputChannels < outchans) outchans = pdo->maxOutputChannels; - } - } - if (sys_verbose) { - post("input device %d, channels %d", pa_indev, inchans); - post("output device %d, channels %d", pa_outdev, outchans); - post("latency advance %d", advance); - } - if (inchans || outchans) { - int blocksize; - PaStreamParameters iparam,oparam; - /* initialize input */ - iparam.device = pa_indev; - iparam.channelCount = inchans; - iparam.sampleFormat = paFloat32 | paNonInterleaved; - iparam.suggestedLatency = advance * 0.001; - iparam.hostApiSpecificStreamInfo = NULL; - /* initialize output */ - oparam.device = pa_outdev; - oparam.channelCount = outchans; - oparam.sampleFormat = paFloat32 | paNonInterleaved; - oparam.suggestedLatency = advance * 0.001; - oparam.hostApiSpecificStreamInfo = NULL; - /* set block size */ - blocksize=64; - while ((float)blocksize/(float)rate*1000*2 < advance && blocksize==1024) blocksize *= 2; - pa_blocksize = blocksize; - /* initialize io buffer */ - for (int j=0; j != MAX_PA_CHANS;++j) { - if (pa_inbuffer[j]) freealignedbytes(pa_inbuffer[j], 0); - if (pa_outbuffer[j]) freealignedbytes(pa_outbuffer[j], 0); - pa_inbuffer[j] = (float *)getalignedbytes((blocksize + sys_dacblocksize)*sizeof(float)); - pa_outbuffer[j] = (float *)getalignedbytes((blocksize + sys_dacblocksize)*sizeof(float)); - } - pa_bufferpos = 0; - /* report to portaudio */ - err = Pa_OpenStream(&pa_stream, - (( pa_indev!=-1) ? &iparam : 0), - ((pa_outdev!=-1) ? &oparam : 0), - rate, pa_blocksize, paClipOff, /* tb: we should be faster ;-) */ process /* patestCallback */, NULL); - if (err == paNoError) { - const PaStreamInfo *streaminfo = Pa_GetStreamInfo(pa_stream); - t_atom atoms[4]; - t_symbol *pd = gensym("pd"); - sys_schedadvance = int(1e-6 * streaminfo->outputLatency); - - SETFLOAT(atoms, (float)indeviceno); - SETFLOAT(atoms+1, (float)inchans); - SETFLOAT(atoms+2, (float)rate); - SETFLOAT(atoms+3, (float)streaminfo->inputLatency * 1000.f); - typedmess(pd->s_thing, gensym("audiocurrentininfo"), 4, atoms); - - SETFLOAT(atoms, (float)outdeviceno); - SETFLOAT(atoms+1, (float)outchans); - SETFLOAT(atoms+2, (float)rate); - SETFLOAT(atoms+3, (float)streaminfo->outputLatency * 1000.f); - typedmess(pd->s_thing, gensym("audiocurrentoutinfo"), 4, atoms); - } - } else err = 0; - - if (err != paNoError) { - error("Error number %d occured opening portaudio stream: %s", err, Pa_GetErrorText(err)); - sys_inchannels = sys_outchannels = 0; - pa_indev = pa_outdev = -1; - pa_inchans = pa_outchans = 0; - return 1; - } else if (sys_verbose) post("... opened OK."); - pa_inchans = inchans; - pa_outchans = outchans; - - /* we might have adapted the channel count */ - sys_setchsr(inchans, outchans, rate, sys_dacblocksize); - err = Pa_StartStream(pa_stream); - if (err!=paNoError) { - post("Error number %d occured starting portaudio stream: %s", err, Pa_GetErrorText(err)); - sys_inchannels = sys_outchannels = 0; - return 1; - } - if(sys_verbose) post("successfully started"); - return 0; -} - -void sys_peakmeters(); -extern int sys_meters; /* true if we're metering */ - -void run_all_idle_callbacks(); -void sys_xrun_notification(); /* in m_sched.c */ -void sys_lock_timeout_notification(); - -int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, -PaStreamCallbackFlags statusFlags, void *userData) { - int timeout = int((float)frameCount / (float) sys_dacsr * 1e6); - if (statusFlags) sys_xrun_notification(); - if (sys_timedlock(timeout) == ETIMEDOUT) /* we're late */ { - sys_lock_timeout_notification(); - return 0; - } - for (int i=0; (unsigned)i < frameCount / sys_dacblocksize; ++i) { - for (int j=0; j < sys_inchannels; j++) { - t_sample *in = ((t_sample**)input)[j] + i * sys_dacblocksize; - copyvec(sys_soundin + j * sys_dacblocksize, in, sys_dacblocksize); - } - sched_tick(sys_time + sys_time_per_dsp_tick); - for (int j=0; j < sys_outchannels; j++) { - t_sample *out = ((t_sample**)output)[j] + i * sys_dacblocksize; - copyvec(out, sys_soundout + j * sys_dacblocksize, sys_dacblocksize); - } - if (sys_meters) sys_peakmeters(); - zerovec(sys_soundout, pa_outchans * sys_dacblocksize); - } - run_all_idle_callbacks(); - sys_unlock(); - return 0; -} - -static void pa_close_audio() { - if(sys_verbose) post("closing portaudio"); - if (pa_inchans || pa_outchans) { - if (pa_stream) { - int status = Pa_StopStream(pa_stream); - if (status) post("error closing audio: %d", status); - Pa_CloseStream(pa_stream); - pa_stream = NULL; - } - } - sys_setscheduler(0); - if(sys_verbose) post("portaudio closed"); - pa_inchans = pa_outchans = 0; - pa_indev = pa_outdev = -1; -} - -/* for blocked IO */ -static int pa_send_dacs() { - /* we don't support blocking i/o */ - return SENDDACS_NO; -} - -/* lifted from pa_devs.c in portaudio */ -static void pa_listdevs() { - PaError err; - pa_initialize(); - int numDevices = Pa_GetDeviceCount(); - if(numDevices < 0) { - error("ERROR: Pa_GetDeviceCount returned %d", numDevices); - err = numDevices; - goto error; - } - post("Audio Devices:"); - for(int i=0; i<numDevices; i++) { - const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i); - post ("device %s", pdi->name); - post("device %d:", i+1); - post(" %s;", pdi->name); - post("%d inputs, ", pdi->maxInputChannels); - post("%d outputs ", pdi->maxOutputChannels); - if (i == Pa_GetDefaultInputDevice()) post(" (Default Input)"); - if (i == Pa_GetDefaultOutputDevice()) post(" (Default Output)"); - post("%s",""); - } - post("%s",""); - return; - error: - error("Error #%d occurred while using the portaudio stream: %s\n", err, Pa_GetErrorText(err)); -} - -/* scanning for devices */ -static void pa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { - int nin = 0, nout = 0, ndev; - *canmulti = 1; /* one dev each for input and output */ - pa_initialize(); - ndev = Pa_GetDeviceCount(); - for (int i=0; i<ndev; i++) { - const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i); - if (pdi->maxInputChannels > 0 && nin < maxndev) { - PaHostApiIndex api = pdi->hostApi; - const PaHostApiInfo *info = Pa_GetHostApiInfo(api); - const char *apiName = info->name; - unsigned int apiNameLen = strlen(apiName); - strcpy(indevlist + nin * devdescsize, apiName); - indevlist[nin * devdescsize + apiNameLen] = '/'; - strcpy(indevlist + nin * devdescsize + apiNameLen + 1, pdi->name); - nin++; - } - if (pdi->maxOutputChannels > 0 && nout < maxndev) { - PaHostApiIndex api = pdi->hostApi; - const PaHostApiInfo *info = Pa_GetHostApiInfo(api); - const char *apiName = info->name; - unsigned int apiNameLen = strlen(apiName); - strcpy(outdevlist + nout * devdescsize, apiName); - outdevlist[nout * devdescsize + apiNameLen] = '/'; - strcpy(outdevlist + nout * devdescsize + apiNameLen + 1, pdi->name); - nout++; - } - } - *nindevs = nin; - *noutdevs = nout; -} - -void pa_getaudioininfo(t_float f) { - int i = pddev2padev((int)f,1); - const PaDeviceInfo *pdi; - pa_initialize(); - pdi = Pa_GetDeviceInfo(i); - if (pdi) { - t_symbol *selector = gensym("audioininfo"); - t_symbol *pd = gensym("pd"); - t_atom argv[4]; - SETFLOAT(argv, pdi->maxInputChannels); - SETFLOAT(argv+1, pdi->defaultSampleRate); - SETFLOAT(argv+2, pdi->defaultLowInputLatency*1000.f); - SETFLOAT(argv+3, pdi->defaultHighInputLatency*1000.f); - typedmess(pd->s_thing, selector, 4, argv); - } -} - -void pa_getaudiooutinfo(t_float f) { - int i = pddev2padev((int)f,0); - const PaDeviceInfo *pdi; - pa_initialize(); - pdi = Pa_GetDeviceInfo(i); - if (pdi) { - t_symbol *selector = gensym("audiooutinfo"); - t_symbol *pd = gensym("pd"); - t_atom argv[4]; - SETFLOAT(argv, pdi->maxOutputChannels); - SETFLOAT(argv+1, pdi->defaultSampleRate); - SETFLOAT(argv+2, pdi->defaultLowOutputLatency*1000.f); - SETFLOAT(argv+3, pdi->defaultHighOutputLatency*1000.f); - typedmess(pd->s_thing, selector, 4, argv); - } -} - -void pa_getcurrent_devices() { - t_symbol *pd = gensym("pd"); - t_symbol *selector = gensym("audiodevice"); - t_atom argv[2]; - SETFLOAT(argv, padev2pddev(pa_indev,1)); - SETFLOAT(argv+1, padev2pddev(pa_outdev,0)); - typedmess(pd->s_thing, selector, 2, argv); -} - -void pa_test_setting (int ac, t_atom *av) { - int indev = atom_getintarg(0, ac, av); - int outdev = atom_getintarg(1, ac, av); - int samplerate = atom_getintarg(2, ac, av); - int inchans = atom_getintarg(3, ac, av); - int outchans = atom_getintarg(4, ac, av); - int advance = atom_getintarg(5, ac, av); - t_symbol *pd = gensym("pd"); - t_symbol *selector = gensym("testaudiosettingresult"); - t_atom argv[1]; - pa_initialize(); - indev = pddev2padev(indev,1); - outdev = pddev2padev(outdev,0); - if (pa_indev==-1 && pa_outdev==-1) { - int ret; - PaStreamParameters iparam, oparam; - iparam.device = indev; - iparam.channelCount = inchans; - iparam.sampleFormat = paFloat32 | paNonInterleaved; - iparam.suggestedLatency = advance * 0.001; - iparam.hostApiSpecificStreamInfo = NULL; - oparam.device = outdev; - oparam.channelCount = outchans; - oparam.sampleFormat = paFloat32 | paNonInterleaved; - oparam.suggestedLatency = advance * 0.001; - oparam.hostApiSpecificStreamInfo = NULL; - ret = Pa_IsFormatSupported(&iparam, &oparam, samplerate); - SETFLOAT(argv, ret == paNoError?1:0); - typedmess(pd->s_thing, selector, 1, argv); - } -} - -static int pddev2padev(int pddev,int input) { - pa_initialize(); - for (int j=0, devno=0; j < Pa_GetDeviceCount(); j++) { - const PaDeviceInfo *info = Pa_GetDeviceInfo(j); - int maxchans = input?info->maxInputChannels:info->maxOutputChannels; - if (maxchans > 0) { - if (devno == pddev) return j; - devno++; - } - } - return -1; -} - -static int padev2pddev(int padev,int input) { - int count = Pa_GetDeviceCount(); - for (int j=0, devno=0; j < count; j++) { - const PaDeviceInfo *info = Pa_GetDeviceInfo(j); - int chans = input?info->maxInputChannels:info->maxOutputChannels; - if (chans > 0) { - if(j == padev) return devno; - devno++; - } - } - return -1; // no found -} - -void pa_get_asio_latencies(t_float f) { - int index = pddev2padev((int)f,0); - const PaDeviceInfo *pdi = Pa_GetDeviceInfo(index); - const PaHostApiInfo *phi = Pa_GetHostApiInfo(pdi->hostApi); - if (phi->type != paASIO) { - post("device not an asio device"); - return; - } -#ifdef WIN32 - else { - long minlat, maxlat, preflat, gran; - t_atom argv[4]; - t_symbol *selector = gensym("asiolatency"); - t_symbol *pd = gensym("pd"); - PaAsio_GetAvailableLatencyValues(index, &minlat, &maxlat, &preflat, &gran); - SETFLOAT(argv, (float) minlat); - SETFLOAT(argv + 1, (float) maxlat); - SETFLOAT(argv + 2, (float) preflat); - SETFLOAT(argv + 3, (float) gran); - typedmess(pd->s_thing, selector, 4, argv); - } -#endif -} - -t_audioapi pa_api = { - 0 /* pa_open_audio */, - pa_close_audio, - pa_send_dacs, - pa_getdevs, -}; diff --git a/desiredata/src/s_inter.c b/desiredata/src/s_inter.c deleted file mode 100644 index 7c9919ef..00000000 --- a/desiredata/src/s_inter.c +++ /dev/null @@ -1,736 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* Pd side of the Pd/Pd-gui interface. Also, some system interface routines -that didn't really belong anywhere. */ - -#define WATCHDOGTHREAD - -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include "pthread.h" -#include <sstream> -#ifdef UNISTD -#include <unistd.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <netdb.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <sys/resource.h> -#endif -#ifdef HAVE_BSTRING_H -#include <bstring.h> -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -#include <io.h> -#include <fcntl.h> -#include <process.h> -#include <winsock.h> -#include <windows.h> -#ifdef _MSC_VER -typedef int pid_t; -#endif -typedef int socklen_t; -#define EADDRINUSE WSAEADDRINUSE -#endif - -#include <stdarg.h> -#include <signal.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> - -#ifndef SIGIOT -#define SIGIOT SIGABRT -#endif - -#ifdef __APPLE__ -#include <sys/types.h> -#include <sys/stat.h> -#include <pthread.h> -#else -#include <stdlib.h> -#endif - -#define DEBUG_MESSUP 1 /* messages up from pd to pd-gui */ -#define DEBUG_MESSDOWN 2 /* messages down from pd-gui to pd */ - -/* T.Grill - make it a _little_ more adaptable... */ -#ifndef PDBINDIR -#define PDBINDIR "bin/" -#endif - -#ifndef WISHAPP -#define WISHAPP "wish84.exe" -#endif - -#ifdef __linux__ -#define LOCALHOST "127.0.0.1" -#else -#define LOCALHOST "localhost" -#endif - -struct t_fdpoll { - int fdp_fd; - t_fdpollfn fdp_fn; - void *fdp_ptr; -}; - -#define INBUFSIZE 16384 - -extern int sys_guisetportnumber; -static int sys_nfdpoll; -static t_fdpoll *sys_fdpoll; -static int sys_maxfd; -t_text *sys_netreceive; -static t_binbuf *inbinbuf; -t_socketreceiver *sys_socketreceiver; -extern int sys_addhist(int phase); - -/* ----------- functions for timing, signals, priorities, etc --------- */ - -#ifdef _WIN32 -static LARGE_INTEGER nt_inittime; -static double nt_freq = 0; - -static void sys_initntclock() { - LARGE_INTEGER f1; - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - if (!QueryPerformanceFrequency(&f1)) { - fprintf(stderr, "pd: QueryPerformanceFrequency failed\n"); - f1.QuadPart = 1; - } - nt_freq = f1.QuadPart; - nt_inittime = now; -} - -#if 0 -/* this is a version you can call if you did the QueryPerformanceCounter - call yourself. Necessary for time tagging incoming MIDI at interrupt - level, for instance; but we're not doing that just now. */ - -double nt_tixtotime(LARGE_INTEGER *dumbass) { - if (nt_freq == 0) sys_initntclock(); - return (((double)(dumbass->QuadPart - nt_inittime.QuadPart)) / nt_freq); -} -#endif -#endif /* _WIN32 */ - - /* get "real time" in seconds; take the - first time we get called as a reference time of zero. */ -double sys_getrealtime() { -#ifndef _WIN32 - static struct timeval then; - struct timeval now; - gettimeofday(&now, 0); - if (then.tv_sec == 0 && then.tv_usec == 0) then = now; - return (now.tv_sec - then.tv_sec) + (1./1000000.) * (now.tv_usec - then.tv_usec); -#else - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - if (nt_freq == 0) sys_initntclock(); - return double(now.QuadPart - nt_inittime.QuadPart) / nt_freq; -#endif -} - -int sys_pollsockets () { - struct timeval timout; - int didsomething = 0; - fd_set readset, writeset, exceptset; - timout.tv_sec = 0; - timout.tv_usec = 0; - FD_ZERO(&writeset); - FD_ZERO(&readset); - FD_ZERO(&exceptset); - t_fdpoll *fp = sys_fdpoll; - for (int i=sys_nfdpoll; i--; fp++) FD_SET(fp->fdp_fd, &readset); - select(sys_maxfd+1, &readset, &writeset, &exceptset, &timout); - for (int i=0; i<sys_nfdpoll; i++) if (FD_ISSET(sys_fdpoll[i].fdp_fd, &readset)) { - sys_fdpoll[i].fdp_fn(sys_fdpoll[i].fdp_ptr, sys_fdpoll[i].fdp_fd); - didsomething = 1; - } - return didsomething; -} - -void sys_microsleep(int microsec) { - /* Tim says: sleep granularity on "modern" operating systems is only 1ms??? - - linux: we might be better with the high precision posix timer kernel patches ... - - windows: win9x doesn't implement a SwitchToThread function, so we can't sleep for small timeslices - - osx: ??? - */ - if (!sys_callbackscheduler && microsec < 1000) { - if (500 < microsec) microsec = 1000; else return; - } -#ifndef MSW - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = microsec; - select(0,0,0,0,&timeout); - -#else - Sleep(microsec/1000); -#endif - /* a solution for lower timeslices might be a busysleep but this might - block a low-priority thread and won't work for win9x -#define _WIN32_WINNT 0x0400 - double end = sys_getrealtime() + (double)microsec * 1e-6; - do { -#ifdef MSW - SwitchToThread(); -#else - sched_yield(); -#endif - } - while(sys_getrealtime() < end); - */ -} - -#ifdef UNISTD -typedef void (*sighandler_t)(int); - -static void sys_signal(int signo, sighandler_t sigfun) { - struct sigaction action; - action.sa_flags = 0; - action.sa_handler = sigfun; - memset(&action.sa_mask, 0, sizeof(action.sa_mask)); -#if 0 /* GG says: don't use that */ - action.sa_restorer = 0; -#endif - if (sigaction(signo, &action, 0) < 0) perror("sigaction"); - -} - -static void sys_exithandler(int n) { - static int trouble = 0; - if (!trouble) { - trouble = 1; - fprintf(stderr, "Pd: signal %d\n", n); - sys_bail(1); - } else sys_bail(0); -} - -static void sys_alarmhandler(int n) { - fprintf(stderr, "Pd: system call timed out\n"); -} - -/* what is this for?? */ -static void sys_huphandler(int n) { - struct timeval timout; - timout.tv_sec = 0; - timout.tv_usec = 30000; - select(1, 0, 0, 0, &timout); -} - -void sys_setalarm(int microsec) { - struct itimerval it; - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 0; - it.it_value.tv_sec = microsec/1000000; - it.it_value.tv_usec = microsec%1000000; - sys_signal(SIGALRM, microsec ? sys_alarmhandler : SIG_IGN); - setitimer(ITIMER_REAL, &it, 0); -} - -#endif - -#if defined(__linux) || defined(__APPLE__) -#if (_POSIX_PRIORITY_SCHEDULING - 0) >= 200112L || (_POSIX_MEMLOCK - 0) >= 200112L -#include <sched.h> -#endif -#if (_POSIX_MEMLOCK - 0) >= 200112L -#include <sys/resource.h> -#endif -void sys_set_priority(int higher) { -#if (_POSIX_PRIORITY_SCHEDULING - 0) >= 200112L - struct sched_param par; -#ifdef USEAPI_JACK - int p1 = sched_get_priority_min(SCHED_FIFO); - int p3 = (higher ? p1 + 7 : p1 + 5); -#else - int p2 = sched_get_priority_max(SCHED_FIFO); - int p3 = (higher ? p2 - 1 : p2 - 3); -#endif - par.sched_priority = p3; - if (sched_setscheduler(0,SCHED_FIFO,&par) != -1) - fprintf(stderr, "priority %d scheduling enabled.\n", p3); -#endif -#if (_POSIX_MEMLOCK - 0) >= 200112L - /* tb: force memlock to physical memory { */ - struct rlimit mlock_limit; - mlock_limit.rlim_cur=0; - /* tb: only if we are really root we can set the hard limit */ - mlock_limit.rlim_max = getuid() ? 100 : 0; - setrlimit(RLIMIT_MEMLOCK,&mlock_limit); - /* } tb */ - if (mlockall(MCL_FUTURE) != -1) fprintf(stderr, "memory locking enabled.\n"); -#endif -} -#endif /* __linux__ */ - -#ifdef IRIX /* hack by <olaf.matthes@gmx.de> at 2003/09/21 */ - -#if (_POSIX_PRIORITY_SCHEDULING - 0) >= 200112L || (_POSIX_MEMLOCK - 0) >= 200112L -#include <sched.h> -#endif - -void sys_set_priority(int higher) { -#if (_POSIX_PRIORITY_SCHEDULING - 0) >= 200112L - struct sched_param par; - /* Bearing the table found in 'man realtime' in mind, I found it a */ - /* good idea to use 192 as the priority setting for Pd. Any thoughts? */ - if (higher) par.sched_priority = 250; /* priority for watchdog */ - else par.sched_priority = 192; /* priority for pd (DSP) */ - if (sched_setscheduler(0, SCHED_FIFO, &par) != -1) - fprintf(stderr, "priority %d scheduling enabled.\n", par.sched_priority); -#endif - -#if (_POSIX_MEMLOCK - 0) >= 200112L - if (mlockall(MCL_FUTURE) != -1) fprintf(stderr, "memory locking enabled.\n"); -#endif -} -/* end of hack */ -#endif /* IRIX */ - -/* ------------------ receiving incoming messages over sockets ------------- */ - -void sys_sockerror(const char *s) { -#ifdef _WIN32 - int err = WSAGetLastError(); - if (err == 10054) return; - else if (err == 10044) { - fprintf(stderr, "Warning: you might not have TCP/IP \"networking\" turned on\n"); - fprintf(stderr, "which is needed for Pd to talk to its GUI layer.\n"); - } -#else - int err = errno; -#endif /* _WIN32 */ - fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); -} - -void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr) { - int nfd = sys_nfdpoll; - int size = nfd * sizeof(t_fdpoll); - sys_fdpoll = (t_fdpoll *)t_resizebytes(sys_fdpoll, size, size + sizeof(t_fdpoll)); - t_fdpoll *fp = sys_fdpoll + nfd; - fp->fdp_fd = fd; - fp->fdp_fn = fn; - fp->fdp_ptr = ptr; - sys_nfdpoll = nfd + 1; - if (fd >= sys_maxfd) sys_maxfd = fd + 1; -} - -void sys_rmpollfn(int fd) { - int nfd = sys_nfdpoll; - int size = nfd * sizeof(t_fdpoll); - t_fdpoll *fp = sys_fdpoll; - for (int i=nfd; i--; fp++) { - if (fp->fdp_fd == fd) { - while (i--) { - fp[0] = fp[1]; - fp++; - } - sys_fdpoll = (t_fdpoll *)t_resizebytes(sys_fdpoll, size, size - sizeof(t_fdpoll)); - sys_nfdpoll = nfd - 1; - return; - } - } - post("warning: %d removed from poll list but not found", fd); -} - -t_socketreceiver *socketreceiver_new(t_pd *owner, int fd, t_socketnotifier notifier, -t_socketreceivefn socketreceivefn, int udp) { - t_socketreceiver *x = (t_socketreceiver *)getbytes(sizeof(*x)); - x->inhead = x->intail = 0; - x->owner = owner; - x->notifier = notifier; - x->socketreceivefn = socketreceivefn; - x->udp = udp; - x->fd = fd; - x->obuf = 0; - x->next = 0; - x->inbuf = (char *)malloc(INBUFSIZE); - if (!x->inbuf) bug("t_socketreceiver"); - return x; -} - -void socketreceiver_free(t_socketreceiver *x) {free(x->inbuf); free(x);} - -/* this is in a separately called subroutine so that the buffer isn't - sitting on the stack while the messages are getting passed. */ -static int socketreceiver_doread(t_socketreceiver *x) { - char messbuf[INBUFSIZE], *bp = messbuf; - int inhead = x->inhead; - int intail = x->intail; - char *inbuf = x->inbuf; - if (intail == inhead) return 0; - for (int i=intail; i!=inhead; i=(i+1)&(INBUFSIZE-1)) { - /* ";" not preceded by "\" is a message boundary in current syntax. - in future syntax it might become more complex. */ - char c = *bp++ = inbuf[i]; - if (c == ';' && (!i || inbuf[i-1] != '\\')) { - intail = (i+1)&(INBUFSIZE-1); - binbuf_text(inbinbuf, messbuf, bp - messbuf); - x->inhead = inhead; - x->intail = intail; - return 1; - } - } - return 0; -} - -static void socketreceiver_getudp(t_socketreceiver *x, int fd) { - char buf[INBUFSIZE+1]; - int ret = recv(fd, buf, INBUFSIZE, 0); - if (ret < 0) { - sys_sockerror("recv"); - sys_rmpollfn(fd); - sys_closesocket(fd); - } else if (ret > 0) { - buf[ret] = 0; - if (buf[ret-1] == '\n') { - char *semi = strchr(buf, ';'); - if (semi) *semi = 0; - binbuf_text(inbinbuf, buf, strlen(buf)); - outlet_setstacklim(); - x->socketreceivefn(x->owner, inbinbuf); - } else {/*bad buffer ignored */} - } -} - -void sys_exit(); - -void socketreceiver_read(t_socketreceiver *x, int fd) { - if (x->udp) {socketreceiver_getudp(x, fd); return;} - /* else TCP */ - int readto = x->inhead >= x->intail ? INBUFSIZE : x->intail-1; - /* the input buffer might be full. If so, drop the whole thing */ - if (readto == x->inhead) { - fprintf(stderr, "pd: dropped message from gui\n"); - x->inhead = x->intail = 0; - readto = INBUFSIZE; - } else { - int ret = recv(fd, x->inbuf+x->inhead, readto-x->inhead, 0); - if (ret<=0) { - if (ret<0) sys_sockerror("recv"); else post("EOF on socket %d", fd); - if (x->notifier) x->notifier(x->owner); - sys_rmpollfn(fd); - sys_closesocket(fd); - return; - } - x->inhead += ret; - if (x->inhead >= INBUFSIZE) x->inhead = 0; - while (socketreceiver_doread(x)) { - outlet_setstacklim(); - x->socketreceivefn(x->owner, inbinbuf); - } - } -} - -void sys_closesocket(int fd) { -#ifdef UNISTD - close(fd); -#endif -#ifdef _WIN32 - closesocket(fd); -#endif /* _WIN32 */ -} - -/* ---------------------- sending messages to the GUI ------------------ */ -#define GUI_ALLOCCHUNK 8192 -#define GUI_UPDATESLICE 512 /* how much we try to do in one idle period */ -#define GUI_BYTESPERPING 1024 /* how much we send up per ping */ - -static void sys_trytogetmoreguibuf(t_socketreceiver *self, int newsize) { - self->osize = newsize; - self->obuf = (char *)realloc(self->obuf, newsize); -} - -#undef max /* for msys compat */ -int max(int a, int b) { return ((a)>(b)?(a):(b)); } - -std::ostringstream lost_posts; - -void sys_vgui(const char *fmt, ...) { - t_socketreceiver *self = sys_socketreceiver; - va_list ap; - va_start(ap, fmt); - if (!self) {voprintf(lost_posts,fmt,ap); va_end(ap); return;} - if (!self->obuf) { - self->obuf = (char *)malloc(GUI_ALLOCCHUNK); - self->osize = GUI_ALLOCCHUNK; - self->ohead = self->otail = 0; - } - if (self->ohead > self->osize - GUI_ALLOCCHUNK/2) - sys_trytogetmoreguibuf(self,self->osize + GUI_ALLOCCHUNK); - int msglen = vsnprintf(self->obuf+self->ohead, self->osize-self->ohead, fmt, ap); - va_end(ap); - if(msglen < 0) {fprintf(stderr, "Pd: buffer space wasn't sufficient for long GUI string\n"); return;} - if (msglen >= self->osize - self->ohead) { - int msglen2, newsize = self->osize+1+max(msglen,GUI_ALLOCCHUNK); - sys_trytogetmoreguibuf(self,newsize); - va_start(ap, fmt); - msglen2 = vsnprintf(self->obuf+self->ohead, self->osize-self->ohead, fmt, ap); - va_end(ap); - if (msglen2 != msglen) bug("sys_vgui"); - if (msglen >= self->osize-self->ohead) msglen = self->osize-self->ohead; - } - self->ohead += msglen; - self->bytessincelastping += msglen; -} - -void sys_gui(const char *s) {sys_vgui("%s", s);} - -static int sys_flushtogui(t_socketreceiver *self) { - int writesize = self->ohead-self->otail; - if (!writesize) return 0; - int nwrote = send(self->fd, self->obuf+self->otail, writesize, 0); - if (nwrote < 0) { - perror("pd-to-gui socket"); - sys_bail(1); - } else if (!nwrote) { - return 0; - } else if (nwrote >= self->ohead-self->otail) { - self->ohead = self->otail = 0; - } else if (nwrote) { - self->otail += nwrote; - if (self->otail > self->osize>>2) { - memmove(self->obuf, self->obuf+self->otail, self->ohead-self->otail); - self->ohead -= self->otail; - self->otail = 0; - } - } - return 1; -} - -void glob_ping(t_pd *dummy) {t_socketreceiver *self = sys_socketreceiver; self->waitingforping = 0;} - -int sys_pollgui() { - if (sys_socketreceiver) sys_flushtogui(sys_socketreceiver); - return sys_pollsockets(); -} - -/* --------------------- starting up the GUI connection ------------- */ - -#ifdef __linux__ -void glob_watchdog(t_pd *dummy) { -#ifndef WATCHDOGTHREAD - if (write(sys_watchfd, "\n", 1) < 1) { - fprintf(stderr, "pd: watchdog process died\n"); - sys_bail(1); - } -#endif -} -#endif - -static void sys_setsignals() { -#ifdef UNISTD - signal(SIGHUP, sys_huphandler); - signal(SIGINT, sys_exithandler); - signal(SIGQUIT, sys_exithandler); - signal(SIGILL, sys_exithandler); - signal(SIGIOT, sys_exithandler); - signal(SIGFPE, SIG_IGN); -/* signal(SIGILL, sys_exithandler); - signal(SIGBUS, sys_exithandler); - signal(SIGSEGV, sys_exithandler); */ - signal(SIGPIPE, SIG_IGN); - signal(SIGALRM, SIG_IGN); -/* GG says: don't set SIGSTKFLT */ -#endif -} - -//t_pd *pd_new3(const char *s); - -extern "C" t_text *netreceive_new(t_symbol *compatflag, t_floatarg fportno, t_floatarg udpflag); -static int sys_start_watchdog_thread(); -static void sys_setpriority(); -extern t_text *manager; - -int sys_startgui() { -#ifdef _WIN32 - short version = MAKEWORD(2, 0); - WSADATA nobby; - if (WSAStartup(version, &nobby)) sys_sockerror("WSAstartup"); -#endif /* _WIN32 */ - /* create an empty FD poll list */ - sys_fdpoll = (t_fdpoll *)t_getbytes(0); - sys_nfdpoll = 0; - inbinbuf = binbuf_new(); - sys_setsignals(); - sys_netreceive = netreceive_new(&s_,sys_guisetportnumber,0); -// fprintf(stderr,"sys_netreceive=%p\n",sys_netreceive); - if (!sys_netreceive) return 0; -// obj_connect(sys_netreceive,0,(t_text *)pd_new3("print left"),0); -// obj_connect(sys_netreceive,1,(t_text *)pd_new3("print right"),0); - obj_connect(sys_netreceive,0,manager,0); -#if defined(__linux__) || defined(IRIX) -/* now that we've spun off the child process we can promote our process's - priority, if we can and want to. If not specfied (-1), we check root - status. This misses the case where we might have permission from a - "security module" (linux 2.6) -- I don't know how to test for that. - The "-rt" flag must be set in that case. */ - if (sys_hipriority == -1) sys_hipriority = !getuid() || !geteuid(); -#endif - if (sys_hipriority) sys_setpriority(); -#ifndef MSW - setuid(getuid()); -#endif /* MSW */ - return 0; -} - -/* To prevent lockup, we fork off a watchdog process with higher real-time - priority than ours. The GUI has to send a stream of ping messages to the - watchdog THROUGH the Pd process which has to pick them up from the GUI - and forward them. If any of these things aren't happening the watchdog - starts sending "stop" and "cont" signals to the Pd process to make it - timeshare with the rest of the system. (Version 0.33P2 : if there's no - GUI, the watchdog pinging is done from the scheduler idle routine in this - process instead.) */ -void sys_setpriority() { -#if defined(__linux__) || defined(IRIX) -#ifndef WATCHDOGTHREAD - int pipe9[2]; - if (pipe(pipe9) < 0) { - setuid(getuid()); - sys_sockerror("pipe"); - return 1; - } - int watchpid = fork(); - if (watchpid < 0) { - setuid(getuid()); - if (errno) perror("sys_startgui"); else fprintf(stderr, "sys_startgui failed\n"); - return 1; - } else if (!watchpid) { /* we're the child */ - sys_set_priority(1); - setuid(getuid()); - if (pipe9[1]) { - dup2(pipe9[0], 0); - close(pipe9[0]); - } - close(pipe9[1]); - sprintf(cmdbuf, "%s/pd-watchdog\n", guidir); - if (sys_verbose) fprintf(stderr, "%s", cmdbuf); - execl("/bin/sh", "sh", "-c", cmdbuf, (char*)0); - perror("pd: exec"); - _exit(1); - } else { /* we're the parent */ - sys_set_priority(0); - setuid(getuid()); - close(pipe9[0]); - sys_watchfd = pipe9[1]; - /* We also have to start the ping loop in the GUI; this is done later when the socket is open. */ - } -#else - sys_start_watchdog_thread(); - sys_set_priority(0); -#endif -#endif /* __linux__ */ -#ifdef MSW - if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) - fprintf(stderr, "pd: couldn't set high priority class\n"); -#endif -#ifdef __APPLE__ - if (sys_hipriority) { - struct sched_param param; - int policy = SCHED_RR; - param.sched_priority = 80; /* adjust 0 : 100 */ - int err = pthread_setschedparam(pthread_self(), policy, ¶m); - if (err) post("warning: high priority scheduling failed"); - } -#endif /* __APPLE__ */ - if (!sys_nogui) { - /* here is where we start the pinging. */ -#if defined(__linux__) || defined(IRIX) -#ifndef WATCHDOGTHREAD - if (sys_hipriority) sys_gui("pdtk_watchdog\n"); -#endif -#endif - } -} - -/* This is called when something bad has happened, like a segfault. -Call glob_quit() below to exit cleanly. -LATER try to save dirty documents even in the bad case. */ -void sys_bail(int n) { - static int reentered = 0; - if (reentered) _exit(1); - reentered = 1; - fprintf(stderr, "closing audio...\n"); - sys_close_audio(); - fprintf(stderr, "closing MIDI...\n"); - sys_close_midi(); - fprintf(stderr, "... done.\n"); - exit(n); -} - -extern "C" void glob_closeall(void *dummy, t_floatarg fforce); - -void glob_quit(void *dummy) { - glob_closeall(0, 1); - sys_bail(0); -} - -static pthread_t watchdog_id; -static pthread_t main_pd_thread; -static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER; -static void *watchdog_thread(void *); - -/* start a high priority watchdog thread */ -#ifndef MSW -static int sys_start_watchdog_thread() { - pthread_attr_t w_attr; - main_pd_thread = pthread_self(); - pthread_attr_init(&w_attr); - pthread_attr_setschedpolicy(&w_attr, SCHED_FIFO); /* use rt scheduling */ - int status = pthread_create(&watchdog_id, &w_attr, (void*(*)(void*)) watchdog_thread, NULL); - return status; /* what is this function supposed to return anyway? it tried returning void though declared as int */ -} -#endif -#ifdef MSW -int gettimeofday (struct timeval *tv, void *tz); -#endif - -static t_int* watchdog_callback(t_int *dummy) { - /* signal the condition */ - pthread_cond_signal(&watchdog_cond); - return 0; -} - -/* this watchdog thread registers an idle callback once a minute - if the idle callback isn't excecuted within one minute, we're probably - blocking the system. - kill the whole process! -*/ - -static void *watchdog_thread(void *dummy) { - sys_set_priority(1); - post("watchdog thread started"); - sys_microsleep(60*1000*1000); /* wait 60 seconds ... hoping that everything is set up */ - post("watchdog thread active"); - while (1) { - struct timespec timeout; - struct timeval now; - int status; - gettimeofday(&now,0); - timeout.tv_sec = now.tv_sec + 15; /* timeout: 15 seconds */ - timeout.tv_nsec = now.tv_usec * 1000; - sys_callback((t_int(*)(t_int*))watchdog_callback, 0, 0); - status = pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex, &timeout); - if (status) { -#if defined(__linux__) || defined(IRIX) - fprintf(stderr, "watchdog killing"); - kill(0,9); /* kill parent thread */ -#endif - } - sys_microsleep(15*1000*1000); /* and sleep for another 15 seconds */ - } - return 0; /* avoid warning */ -} diff --git a/desiredata/src/s_loader.c b/desiredata/src/s_loader.c deleted file mode 100644 index 2754069b..00000000 --- a/desiredata/src/s_loader.c +++ /dev/null @@ -1,183 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -#ifdef DL_OPEN -#include <dlfcn.h> -#endif -#ifdef UNISTD -#include <stdlib.h> -#include <unistd.h> -#endif -#ifdef MSW -#include <io.h> -#include <windows.h> -#endif -#ifdef __APPLE__ -#include <mach-o/dyld.h> -#endif -#include <string.h> -#define PD_PLUSPLUS_FACE -#include "desire.h" -using namespace desire; -#include <stdio.h> -#include <sstream> -using namespace std; - -typedef void (*t_xxx)(); - -/* naming convention for externs. The names are kept distinct for those -who wich to make "fat" externs compiled for many platforms. Less specific -fallbacks are provided, primarily for back-compatibility; these suffice if -you are building a package which will run with a single set of compiled -objects. The specific name is the letter b, l, d, or m for BSD, linux, -darwin, or microsoft, followed by a more specific string, either "fat" for -a fat binary or an indication of the instruction set. */ - -#ifdef __FreeBSD__ -static char sys_dllextent[] = ".b_i386", sys_dllextent2[] = ".pd_freebsd"; -#endif -#ifdef __linux__ -#ifdef __ia64__ -static char sys_dllextent[] = ".l_ia64", sys_dllextent2[] = ".pd_linux"; -#else -static char sys_dllextent[] = ".l_i386", sys_dllextent2[] = ".pd_linux"; -#endif -#endif -#ifdef __APPLE__ -#ifndef MACOSX3 -static char sys_dllextent[] = ".d_fat", sys_dllextent2[] = ".pd_darwin"; -#else -static char sys_dllextent[] = ".d_ppc", sys_dllextent2[] = ".pd_darwin"; -#endif -#endif -#ifdef MSW -static char sys_dllextent[] = ".m_i386", sys_dllextent2[] = ".dll"; -#endif - -/* maintain list of loaded modules to avoid repeating loads */ -struct t_loadlist { - t_loadlist *ll_next; - t_symbol *ll_name; -}; - -static t_loadlist *sys_loaded; -/* return true if already loaded */ -int sys_onloadlist(char *classname) { - t_symbol *s = gensym(classname); - t_loadlist *ll; - for (ll = sys_loaded; ll; ll = ll->ll_next) - if (ll->ll_name == s) - return 1; - return 0; -} - -/* add to list of loaded modules */ -void sys_putonloadlist(char *classname) { - t_loadlist *ll = (t_loadlist *)getbytes(sizeof(*ll)); - ll->ll_name = gensym(classname); - ll->ll_next = sys_loaded; - sys_loaded = ll; - /* post("put on list %s", classname); */ -} - -static char *make_setup_name(const char *s) { - bool hexmunge=0; - ostringstream buf; - for (; *s; s++) { - char c = *s; - if ((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z' )|| c == '_') { - buf << c; - } else if (c=='~' && s[1]==0) { /* trailing tilde becomes "_tilde" */ - buf << "_tilde"; - } else { /* anything you can't put in a C symbol is sprintf'ed in hex */ - // load_object: symbol "setup_0xbf861ee4" not found - oprintf(buf,"0x%02x",c); - hexmunge = 1; - } - } - char *r; - if (hexmunge) asprintf(&r,"setup_%s",buf.str().data()); - else asprintf(&r,"%s_setup",buf.str().data()); - return r; -} - -static int sys_do_load_lib(t_canvas *canvas, char *objectname) { - char *filename=0, *dirbuf, *classname, *nameptr; - t_xxx makeout = NULL; - int fd; - if ((classname = strrchr(objectname, '/'))) classname++; else classname = objectname; - if (sys_onloadlist(objectname)) {post("%s: already loaded", objectname); return 1;} - char *symname = make_setup_name(classname); - /* try looking in the path for (objectname).(sys_dllextent) ... */ - fd = canvas_open2(canvas, objectname, sys_dllextent , &dirbuf, &nameptr, 1); if (fd>=0) goto gotone; - /* same, with the more generic sys_dllextent2 */ - fd = canvas_open2(canvas, objectname, sys_dllextent2, &dirbuf, &nameptr, 1); if (fd>=0) goto gotone; - /* next try (objectname)/(classname).(sys_dllextent) ... */ - asprintf(&filename,"%s/%s",objectname,classname); - fd = canvas_open2(canvas, filename, sys_dllextent , &dirbuf, &nameptr, 1); if (fd>=0) goto gotone; - fd = canvas_open2(canvas, filename, sys_dllextent2, &dirbuf, &nameptr, 1); if (fd>=0) goto gotone; - return 0; -gotone: - close(fd); - class_set_extern_dir(gensym(dirbuf)); - /* rebuild the absolute pathname */ - free(filename); - /* extra nulls are a workaround for a dlopen bug */ - asprintf(&filename,"%s/%s%c%c%c%c",dirbuf,nameptr,0,0,0,0); -// filename = realloc(filename,); -#ifdef DL_OPEN - void *dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); - if (!dlobj) {post("%s: %s", filename, dlerror()); goto forgetit;} - makeout = (t_xxx)dlsym(dlobj, symname); -#endif -#ifdef MSW - sys_bashfilename(filename, filename); - HINSTANCE ntdll = LoadLibrary(filename); - if (!ntdll) {post("%s: couldn't load", filename); goto forgetit;} - makeout = (t_xxx)GetProcAddress(ntdll,"ntdll"); -#endif - if (!makeout) {post("%s: can't find symbol '%s' in library", filename, symname); goto forgetit;} - makeout(); - class_set_extern_dir(&s_); - sys_putonloadlist(objectname); - free(filename); free(symname); - return 1; -forgetit: - class_set_extern_dir(&s_); - free(filename); free(symname); free(dirbuf); - return 0; -} - -/* callback type definition */ -typedef int (*t_loader)(t_canvas *canvas, char *classname); - -/* linked list of loaders */ -struct t_loader_queue { - t_loader loader; - t_loader_queue *next; -}; - -static t_loader_queue loaders = {sys_do_load_lib, NULL}; - -/* register class loader function */ -void sys_register_loader(t_loader loader) { - t_loader_queue *q = &loaders; - while (1) { - if (q->next) q = q->next; - else { - q->next = (t_loader_queue *)getbytes(sizeof(t_loader_queue)); - q->next->loader = loader; - q->next->next = NULL; - break; - } - } -} - -int sys_load_lib(t_canvas *canvas, char *classname) { - int dspstate = canvas_suspend_dsp(); - int ok = 0; - for(t_loader_queue *q = &loaders; q; q = q->next) if ((ok = q->loader(canvas, classname))) break; - canvas_resume_dsp(dspstate); - return ok; -} diff --git a/desiredata/src/s_main.c b/desiredata/src/s_main.c deleted file mode 100644 index 114305ae..00000000 --- a/desiredata/src/s_main.c +++ /dev/null @@ -1,615 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* Zmlnig added advanced multidevice-support (2001) */ - -#include "desire.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <limits.h> -#include <string.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sstream> - -#ifdef __CYGWIN__ -#define UNISTD -#endif -#ifdef UNISTD -#include <unistd.h> -#endif -#ifdef MSW -#include <io.h> -#include <windows.h> -#include <winbase.h> -#endif - -#ifdef DAZ -#define _MM_DENORM_ZERO_ON 0x0040 -#include <xmmintrin.h> -#endif - -extern "C" void pd_init(); -extern "C" int sys_argparse(int argc, char **argv); -void sys_findprogdir(char *progname); -int sys_startgui(); -void sys_init_idle_callbacks(); -extern "C" int sys_rcfile(); -extern int m_scheduler(); -void sys_addhelppath(char *p); -void alsa_adddev(char *name); -extern "C" int sys_parsercfile(char*filename); - -#ifdef THREADED_SF -void sys_start_sfthread(); -#endif /* THREDED_SF */ - -char pd_version[] = "DesireData 2009.04.24"; -char pd_compiletime[] = __TIME__; -char pd_compiledate[] = __DATE__; - -int sys_verbose; -int sys_noloadbang; -int sys_hipriority = -1; /* -1 = don't care; 0 = no; 1 = yes */ -int sys_guisetportnumber = 5400; - -int sys_defeatrt; -t_symbol *sys_flags; - -char *sys_guicmd; -t_symbol *sys_libdir; -t_namelist *sys_externlist =0; -t_namelist *sys_openlist =0; -t_namelist *sys_messagelist=0; -static int sys_version; - -int sys_nmidiout = 1; -#ifdef MSW -int sys_nmidiin = 0; -#else -int sys_nmidiin = 1; -#endif -int sys_midiindevlist[MAXMIDIINDEV] = {1}; -int sys_midioutdevlist[MAXMIDIOUTDEV] = {1}; - -static int sys_main_srate; -static int sys_main_dacblocksize = DEFDACBLKSIZE; -static int sys_main_advance; - -/* jsarlo { */ -int sys_externalschedlib; -char *sys_externalschedlibname; -int sys_extraflags; -char *sys_extraflagsstring; -/* } jsarlo */ - -/* IOhannes { */ -/* here the "-1" counts signify that the corresponding vector hasn't been - specified in command line arguments; sys_open_audio will detect this and fill things in. */ -static int sys_nsoundin = -1; static int sys_soundindevlist[MAXAUDIOINDEV]; -static int sys_nsoundout = -1; static int sys_soundoutdevlist[MAXAUDIOOUTDEV]; -static int sys_nchin = -1; static int sys_chinlist[MAXAUDIOINDEV]; -static int sys_nchout = -1; static int sys_choutlist[MAXAUDIOOUTDEV]; -/* } IOhannes */ - -/* jsarlo { */ -t_sample *get_sys_soundout() {return sys_soundout;} -t_sample *get_sys_soundin() {return sys_soundin;} -int * get_sys_main_advance() {return &sys_main_advance;} -double * get_sys_time_per_dsp_tick() {return &sys_time_per_dsp_tick;} -int * get_sys_schedblocksize() {return &sys_schedblocksize;} -double * get_sys_time() {return &sys_time;} -float * get_sys_dacsr() {return &sys_dacsr;} -int * get_sys_sleepgrain() {return &sys_sleepgrain;} -int * get_sys_schedadvance() {return &sys_schedadvance;} -/* } jsarlo */ - -static void sys_afterargparse(); - -/* this is called from main() in s_entry.c */ -extern "C" int sys_main(int argc, char **argv) { - int noprefs = 0; - class_table = new t_hash<t_symbol*,t_class*>(127); - /* jsarlo { */ - sys_externalschedlib = 0; - sys_extraflags = 0; - /* } jsarlo */ -#ifdef DEBUG - fprintf(stderr, "Pd: COMPILED FOR DEBUGGING\n"); -#endif - pd_init(); /* start the message system */ - sys_findprogdir(argv[0]); /* set sys_progname, guipath */ - /* tb: command line flag to defeat preset loading */ - for (int i=0; i<argc; i++) if (!strcmp(argv[i],"-noprefs") || !strcmp(argv[i],"-rcfile")) noprefs = 1; - if (!noprefs) sys_rcfile(); /* parse the startup file */ - /* initalize idle callbacks before starting the gui */ - sys_init_idle_callbacks(); - /* } tb */ - if (sys_argparse(argc-1, argv+1)) return 1; /* parse cmd line */ - sys_afterargparse(); /* post-argparse settings */ - if (sys_verbose || sys_version) fprintf(stderr, "%s, compiled %s %s\n", pd_version, pd_compiletime, pd_compiledate); - if (sys_version) return 0; /* if we were just asked our version, exit here. */ - if (sys_startgui()) return 1; /* start the gui */ - /* tb: { start the soundfiler helper thread */ -#ifdef THREADED_SF - sys_start_sfthread(); -#endif /* THREDED_SF */ - /* try to set ftz and daz */ -#ifdef DAZ - _mm_setcsr(_MM_FLUSH_ZERO_ON | _MM_MASK_UNDERFLOW | _mm_getcsr()); - _mm_setcsr(_MM_DENORM_ZERO_ON | _mm_getcsr()); -#endif /* DAZ */ - /* } tb */ - /* jsarlo { */ - if (sys_externalschedlib) { -#ifdef MSW - typedef int (*t_externalschedlibmain)(char *); - t_externalschedlibmain externalmainfunc; - HINSTANCE ntdll; - char *filename; - asprintf(&filename,"%s.dll", sys_externalschedlibname); - sys_bashfilename(filename, filename); - ntdll = LoadLibrary(filename); - if (!ntdll) { - post("%s: couldn't load external scheduler lib ", filename); - free(filename); - return 0; - } - free(filename); - externalmainfunc = (t_externalschedlibmain)GetProcAddress(ntdll,"main"); - return externalmainfunc(sys_extraflagsstring); -#else - return 0; -#endif - } - /* open audio and MIDI */ - sys_reopen_midi(); - sys_reopen_audio(); - /* run scheduler until it quits */ - int r = m_scheduler(); - fprintf(stderr,"%s",lost_posts.str().data()); // this could be useful if anyone ever called sys_exit - return r; -} - -static const char *(usagemessage[]) = { -"usage: pd [-flags] [file]...","", -"audio configuration flags:", -"-r <n> -- specify sample rate", -"-audioindev ... -- audio in devices; e.g., \"1,3\" for first and third", -"-audiooutdev ... -- audio out devices (same)", -"-audiodev ... -- specify input and output together", -"-inchannels ... -- audio input channels (by device, like \"2\" or \"16,8\")", -"-outchannels ... -- number of audio out channels (same)", -"-channels ... -- specify both input and output channels", -"-audiobuf <n> -- specify size of audio buffer in msec", -"-blocksize <n> -- specify audio I/O block size in sample frames", -"-dacblocksize <n>-- specify audio dac~block size in samples", -"-sleepgrain <n> -- specify number of milliseconds to sleep when idle", -"-cb_scheduler -- use callback-based scheduler (jack and native asio only)", -"-nodac -- suppress audio output", -"-noadc -- suppress audio input", -"-noaudio -- suppress audio input and output (-nosound is synonym)", - -#define NOT_HERE "(support not compiled in)" - -#ifdef USEAPI_OSS -"-oss -- use OSS audio API", -"-32bit ---- allow 32 bit OSS audio (for RME Hammerfall)", -#else -"-oss -- OSS "NOT_HERE, -"-32bit ---- allow 32 bit OSS audio "NOT_HERE, -#endif - -#ifdef USEAPI_ALSA -"-alsa -- use ALSA audio API", -"-alsaadd <name> -- add an ALSA device name to list", -#else -"-alsa -- use ALSA audio API "NOT_HERE, -"-alsaadd <name> -- add an ALSA device name to list "NOT_HERE, -#endif - -#ifdef USEAPI_JACK -"-jack -- use JACK audio API", -#else -"-jack -- use JACK audio API "NOT_HERE, -#endif - -#ifdef USEAPI_ASIO - "-asio_native -- use native ASIO API", -#else - "-asio_native -- use native ASIO API "NOT_HERE, -#endif - -#ifdef USEAPI_PORTAUDIO -"-pa -- use Portaudio API", -"-asio -- synonym for -pa - use ASIO via Portaudio", -#else -"-pa -- use Portaudio API "NOT_HERE, -"-asio -- synonym for -pa - use ASIO via Portaudio "NOT_HERE, -#endif - -#ifdef USEAPI_MMIO -"-mmio -- use MMIO audio API", -#else -"-mmio -- use MMIO audio API "NOT_HERE, -#endif -#ifdef API_DEFSTRING -" (default audio API for this platform: "API_DEFSTRING")","", -#endif - -"MIDI configuration flags:", -"-midiindev ... -- midi in device list; e.g., \"1,3\" for first and third", -"-midioutdev ... -- midi out device list, same format", -"-mididev ... -- specify -midioutdev and -midiindev together", -"-nomidiin -- suppress MIDI input", -"-nomidiout -- suppress MIDI output", -"-nomidi -- suppress MIDI input and output", -#ifdef USEAPI_ALSA -"-alsamidi -- use ALSA midi API", -#else -"-alsamidi -- use ALSA midi API "NOT_HERE, -#endif - -"","other flags:", -"-rcfile <file> -- read this rcfile instead of default", -"-noprefs -- suppress loading preferences on startup", -"-path <path> -- add to file search path", -"-nostdpath -- don't search standard (\"extra\") directory", -"-stdpath -- search standard directory (true by default)", -"-helppath <path> -- add to help file search path", -"-open <file> -- open file(s) on startup", -"-lib <file> -- load object library(s)", -"-verbose -- extra printout on startup and when searching for files", -"-version -- don't run Pd; just print out which version it is", -"-d <n> -- specify debug level", -"-noloadbang -- suppress all loadbangs", -"-stdout -- send printout to standard output (1>) instead of GUI", -"-stderr -- send printout to standard error (2>) instead of GUI", -"-guiport <n> -- set port that the GUI should connect to", -"-send \"msg...\" -- send a message at startup, after patches are loaded", -#ifdef UNISTD -"-rt or -realtime -- use real-time priority", -"-nrt -- don't use real-time priority", -#else -"-rt or -realtime -- use real-time priority "NOT_HERE, -"-nrt -- don't use real-time priority "NOT_HERE, -#endif -}; - -static void sys_parsedevlist(int *np, int *vecp, int max, char *str) { - int n = 0; - while (n < max) { - if (!*str) break; - else { - char *endp; - vecp[n] = strtol(str, &endp, 10); - if (endp == str) break; - n++; - if (!endp) break; - str = endp + 1; - } - } - *np = n; -} - -#ifndef INSTALL_PREFIX -#define INSTALL_PREFIX "." -#endif - -/* this routine tries to figure out where to find the auxilliary files Pd will need to run. - This is either done by looking at the command line invokation for Pd, or if that fails, - by consulting the variable INSTALL_PREFIX. In MSW, we don't try to use INSTALL_PREFIX. */ -void sys_findprogdir(char *progname) { - char *lastslash; -#ifdef UNISTD - struct stat statbuf; -#endif - /* find out by what string Pd was invoked; put answer in "sbuf". */ - char *sbuf; -#ifdef MSW - int len = GetModuleFileName(NULL, sbuf, 0); - sbuf = (char *)malloc(len+1); - GetModuleFileName(NULL, sbuf, len); - sbuf[len] = 0; - sys_unbashfilename(sbuf,sbuf); -#endif /* MSW */ -#ifdef UNISTD - sbuf = strdup(progname); -#endif - lastslash = strrchr(sbuf, '/'); - char *sbuf2; - if (lastslash) { - /* bash last slash to zero so that sbuf is directory pd was in, e.g., ~/pd/bin */ - *lastslash = 0; - /* go back to the parent from there, e.g., ~/pd */ - lastslash = strrchr(sbuf, '/'); - if (lastslash) { - asprintf(&sbuf2, "%.*s", lastslash-sbuf, sbuf); - } else sbuf2 = strdup(".."); - } else { /* no slashes found. Try INSTALL_PREFIX. */ - sbuf2 = strdup(INSTALL_PREFIX); - } -#ifdef MSW - sys_libdir = gensym(sbuf2); -#else - sys_libdir = stat(sbuf, &statbuf)>=0 ? symprintf("%s/lib/pd",sbuf2) : gensym(sbuf2); -#endif - free(sbuf); - post("sys_libdir = %s",sys_libdir->name); -} - -#ifdef MSW -static int sys_mmio = 1; -#else -static int sys_mmio = 0; -#endif - -#undef NOT_HERE -#define NOT_HERE fprintf(stderr,"option %s not compiled into this pd\n", *argv) - -#define ARG(name,count) (!strcmp(*argv,(name)) && argc>=(count)) -#define NEXT(count) argc -= (count), argv += (count); continue; - -int sys_argparse(int argc, char **argv) { - while ((argc > 0) && **argv == '-') { - if (ARG("-r",2)) { - if (sscanf(argv[1], "%d", &sys_main_srate)<1) goto usage; - NEXT(2); - } - if (ARG("-inchannels",2)) { /* IOhannes */ - sys_parsedevlist(&sys_nchin, sys_chinlist, MAXAUDIOINDEV, argv[1]); - if (!sys_nchin) goto usage; - NEXT(2); - } - if (ARG("-outchannels",2)) { /* IOhannes */ - sys_parsedevlist(&sys_nchout, sys_choutlist, MAXAUDIOOUTDEV, argv[1]); - if (!sys_nchout) goto usage; - NEXT(2); - } - if (ARG("-channels",2)) { - sys_parsedevlist(&sys_nchin, sys_chinlist,MAXAUDIOINDEV, argv[1]); - sys_parsedevlist(&sys_nchout, sys_choutlist,MAXAUDIOOUTDEV, argv[1]); - if (!sys_nchout) goto usage; - NEXT(2); - } - if (ARG("-soundbuf",2) || ARG("-audiobuf",2)) { - sys_main_advance = atoi(argv[1]); - NEXT(2); - } - if (ARG("-blocksize",2)) {sys_setblocksize(atoi(argv[1])); NEXT(2);} - if (ARG("-dacblocksize",2)) { - if (sscanf(argv[1], "%d", &sys_main_dacblocksize)<1) goto usage; - NEXT(2); - } - if (ARG("-sleepgrain",2)) {sys_sleepgrain = int(1000 * atof(argv[1])); NEXT(2);} - - /* from tim */ - if (ARG("-cb_scheduler",1)) {sys_setscheduler(1); NEXT(1);} - - /* IOhannes */ - if (ARG("-nodac",1)) {sys_nsoundout= sys_nchout = 0; NEXT(1);} - if (ARG("-noadc",1)) {sys_nsoundin = sys_nchin = 0; NEXT(1);} - if (ARG("-nosound",1) || ARG("-noaudio",1)) { - sys_nsoundin=sys_nsoundout = 0; - sys_nchin = sys_nchout = 0; - NEXT(1); - } - - /* many options for selecting audio api */ - if (ARG("-oss",1)) { -#ifdef USEAPI_OSS - sys_set_audio_api(API_OSS); -#else - NOT_HERE; -#endif - NEXT(1); - } - if (ARG("-32bit",1)) { -#ifdef USEAPI_OSS - sys_set_audio_api(API_OSS); - oss_set32bit(); -#else - NOT_HERE; -#endif - NEXT(1); - } - if (ARG("-alsa",1)) { -#ifdef USEAPI_ALSA - sys_set_audio_api(API_ALSA); -#else - NOT_HERE; -#endif - NEXT(1); - } - if (ARG("-alsaadd",2)) { -#ifdef USEAPI_ALSA - if (argc>1) alsa_adddev(argv[1]); else goto usage; -#else - NOT_HERE; -#endif - NEXT(2); - } - if (ARG("-alsamidi",1)) { -#ifdef USEAPI_ALSA - sys_set_midi_api(API_ALSA); -#else - NOT_HERE; -#endif - NEXT(1); - } - if (ARG("-jack",1)) { -#ifdef USEAPI_JACK - sys_set_audio_api(API_JACK); -#else - NOT_HERE; -#endif - NEXT(1); - } - if (ARG("-pa",1) || ARG("-portaudio",1) || ARG("-asio",1)) { -#ifdef USEAPI_PORTAUDIO - sys_set_audio_api(API_PORTAUDIO); -#else - NOT_HERE; -#endif - sys_mmio = 0; - argc--; argv++; - } - if (ARG("-asio_native",1)) { -#ifdef USEAPI_ASIO - sys_set_audio_api(API_ASIO); -#else - NOT_HERE; -#endif - sys_mmio = 0; - argc--; argv++; - } - if (ARG("-mmio",1)) { -#ifdef USEAPI_MMIO - sys_set_audio_api(API_MMIO); -#else - NOT_HERE; -#endif - sys_mmio = 1; - NEXT(1); - } - - if (ARG("-nomidiin", 1)) {sys_nmidiin = 0; NEXT(1);} - if (ARG("-nomidiout",1)) {sys_nmidiout = 0; NEXT(1);} - if (ARG("-nomidi",1)) {sys_nmidiin = sys_nmidiout = 0; NEXT(1);} - if (ARG("-midiindev",2)) { - sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV, argv[1]); - if (!sys_nmidiin) goto usage; - NEXT(2); - } - if (ARG("-midioutdev",2)) { - sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV, argv[1]); - if (!sys_nmidiout) goto usage; - NEXT(2); - } - if (ARG("-mididev",2)) { - sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV, argv[1]); - sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV, argv[1]); - if (!sys_nmidiout) goto usage; - NEXT(2); - } - if (ARG("-nostdpath",1)) {sys_usestdpath = 0; NEXT(1);} - if (ARG("-stdpath",1)) {sys_usestdpath = 1; NEXT(1);} - if (ARG("-path",2)) {sys_searchpath = namelist_append_files(sys_searchpath,argv[1]); NEXT(2);} - if (ARG("-helppath",2)) {sys_helppath = namelist_append_files(sys_helppath, argv[1]); NEXT(2);} - if (ARG("-open",2)) {sys_openlist = namelist_append_files(sys_openlist, argv[1]); NEXT(2);} - if (ARG("-lib",2)) {sys_externlist = namelist_append_files(sys_externlist,argv[1]); NEXT(2);} - if (ARG("-font",2)) { - fprintf(stderr,"Warning: -font ignored by DesireData; use .ddrc instead\n"); - //sys_defaultfont = sys_nearestfontsize(atoi(argv[1])); - NEXT(2); - } - if (ARG("-typeface",2)) { /* tim */ - fprintf(stderr,"Warning: -typeface ignored by DesireData; use .ddrc instead\n"); - NEXT(2); - } - if (ARG("-noprefs",1)) {NEXT(1);} /* tim: skip flag, we already parsed it */ - /* jmz: read an alternative rcfile { */ - if (ARG("-rcfile",2)) {sys_parsercfile(argv[1]); NEXT(2);} /* recursively */ - /* } jmz */ - if (ARG("-verbose",1)) {sys_verbose++; NEXT(1);} - if (ARG("-version",1)) {sys_version = 1; NEXT(1);} - if (ARG("-noloadbang",1)) {sys_noloadbang = 1; NEXT(1);} - if (ARG("-nogui",1)) { - fprintf(stderr,"Warning: -nogui is obsolete: nowadays it does just like -stderr instead\n"); - sys_printtofh = stderr; NEXT(1);} - if (ARG("-guiport",2)) { - if (sscanf(argv[1], "%d", &sys_guisetportnumber)<1) goto usage; - NEXT(2); - } - if (ARG("-stdout",1)) {sys_printtofh = stdout; NEXT(1);} - if (ARG("-stderr",1)) {sys_printtofh = stderr; NEXT(1);} - if (ARG("-guicmd",2)) {fprintf(stderr,"Warning: -guicmd ignored"); NEXT(2);} - if (ARG("-send",2)) {sys_messagelist = namelist_append(sys_messagelist,argv[1],1); NEXT(2);} - /* jsarlo { */ - if (ARG("-schedlib",2)) { - sys_externalschedlib = 1; - sys_externalschedlibname = strdup(argv[1]); - NEXT(2); - } - if (ARG("-extraflags",2)) { - sys_extraflags = 1; - sys_extraflagsstring = strdup(argv[1]); - NEXT(2); - } - /* } jsarlo */ -#ifdef UNISTD - if (ARG("-rt",1) || ARG("-realtime",1)) {sys_hipriority = 1; NEXT(1);} - if (ARG("-nrt",1)) {sys_hipriority = 0; NEXT(1);} -#endif - if (ARG("-soundindev",2) || ARG("-audioindev",2)) { /* IOhannes */ - sys_parsedevlist(&sys_nsoundin, sys_soundindevlist, MAXAUDIOINDEV, argv[1]); - if (!sys_nsoundin) goto usage; - NEXT(2); - } - if (ARG("-soundoutdev",2) || ARG("-audiooutdev",2)) { /* IOhannes */ - sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist, MAXAUDIOOUTDEV, argv[1]); - if (!sys_nsoundout) goto usage; - NEXT(2); - } - if (ARG("-sounddev",2) || ARG("-audiodev",2)) { - sys_parsedevlist(&sys_nsoundin, sys_soundindevlist, MAXAUDIOINDEV, argv[1]); - sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist, MAXAUDIOOUTDEV, argv[1]); - if (!sys_nsoundout) goto usage; - NEXT(2); - } - usage: - if (argc) fprintf(stderr, "Can't handle option '%s'.\n",*argv); - for (size_t i=0; i < sizeof(usagemessage)/sizeof(*usagemessage); i++) - fprintf(stderr, "%s\n", usagemessage[i]); - return 1; - } - for (; argc > 0; argc--, argv++) sys_openlist = namelist_append_files(sys_openlist, *argv); - return 0; -} - -int sys_getblksize() {return sys_dacblocksize;} - -/* stuff to do, once, after calling sys_argparse() -- which may itself - be called more than once (first from "settings, second from .pdrc, then - from command-line arguments */ -static void sys_afterargparse() { - char *sbuf; - t_audiodevs audio_in, audio_out; - int nchindev, nchoutdev, rate, dacblksize, advance, scheduler; - int nmidiindev = 0, midiindev[MAXMIDIINDEV]; - int nmidioutdev = 0, midioutdev[MAXMIDIOUTDEV]; - /* add "extra" library to path */ - asprintf(&sbuf,"%s/extra",sys_libdir->name); - sys_setextrapath(sbuf); - free(sbuf); - asprintf(&sbuf,"%s/doc/5.reference",sys_libdir->name); - sys_helppath = namelist_append_files(sys_helppath, sbuf); - free(sbuf); - /* correct to make audio and MIDI device lists zero based. On MMIO, however, "1" really means the second device - the first one is "mapper" which is was not included when the command args were set up, so we leave it that way for compatibility. */ - if (!sys_mmio) { - for (int i=0; i<sys_nsoundin ; i++) sys_soundindevlist[i]--; - for (int i=0; i<sys_nsoundout; i++) sys_soundoutdevlist[i]--; - } - for (int i=0; i<sys_nmidiin; i++) sys_midiindevlist[i]--; - for (int i=0; i<sys_nmidiout; i++) sys_midioutdevlist[i]--; - /* get the current audio parameters. These are set by the preferences mechanism (sys_loadpreferences()) or - else are the default. Overwrite them with any results of argument parsing, and store them again. */ - sys_get_audio_params(&audio_in, &audio_out, &rate, &dacblksize, &advance, &scheduler); - nchindev = sys_nchin>=0 ? sys_nchin : audio_in.ndev; - nchoutdev = sys_nchout>=0 ? sys_nchout : audio_out.ndev; - if (sys_nchin >=0) {for (int i=0; i< nchindev; i++) audio_in.chdev[i] = sys_chinlist[i];} - if (sys_nchout>=0) {for (int i=0; i<nchoutdev; i++) audio_out.chdev[i] = sys_choutlist[i];} - if (sys_nsoundin >=0) {audio_in.ndev = sys_nsoundin; for (int i=0; i< audio_in.ndev; i++) audio_in.dev[i] = sys_soundindevlist[i];} - if (sys_nsoundout>=0) {audio_out.ndev = sys_nsoundout;for (int i=0; i<audio_out.ndev; i++) audio_out.dev[i] = sys_soundoutdevlist[i];} - if (sys_nmidiin >=0) {nmidiindev = sys_nmidiin; for (int i=0; i< nmidiindev; i++) midiindev[i] = sys_midiindevlist[i];} - if (sys_nmidiout>=0) {nmidioutdev = sys_nmidiout; for (int i=0; i< nmidioutdev; i++) midioutdev[i] = sys_midioutdevlist[i];} - if (sys_main_advance) advance = sys_main_advance; - if (sys_main_srate) rate = sys_main_srate; - if (sys_main_dacblocksize) dacblksize = sys_main_dacblocksize; - sys_open_audio(audio_in.ndev, audio_in.dev, nchindev, audio_in.chdev, - audio_out.ndev, audio_out.dev, nchoutdev, audio_out.chdev, rate, dacblksize, advance, scheduler, 0); - sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0); -} diff --git a/desiredata/src/s_midi.c b/desiredata/src/s_midi.c deleted file mode 100644 index 520e0c2f..00000000 --- a/desiredata/src/s_midi.c +++ /dev/null @@ -1,562 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* Clock functions (which should move, but where?) and MIDI queueing */ - -#define PD_PLUSPLUS_FACE -#include "desire.h" -#ifdef UNISTD -#include <unistd.h> -#include <sys/time.h> -#ifdef HAVE_BSTRING_H -#include <bstring.h> -#endif -#endif -#ifdef MSW -#include <winsock.h> -#include <sys/types.h> -#include <sys/timeb.h> -#include <wtypes.h> -#endif -#include <string.h> -#include <stdio.h> -#include <signal.h> - -struct t_midiqelem { - double time; - int portno; - unsigned char onebyte; - unsigned char byte1; - unsigned char byte2; - unsigned char byte3; -}; - -#define MIDIQSIZE 1024 - -t_midiqelem midi_outqueue[MIDIQSIZE]; -int midi_outhead, midi_outtail; -t_midiqelem midi_inqueue[MIDIQSIZE]; -int midi_inhead, midi_intail; -static double sys_midiinittime; - -#ifndef API_DEFAULT -#define API_DEFAULT 0 -#endif -int sys_midiapi = API_DEFAULT; - -/* this is our current estimate for at what "system" real time the - current logical time's output should occur. */ -static double sys_dactimeminusrealtime; -/* same for input, should be schduler advance earlier. */ -static double sys_adctimeminusrealtime; - -static double sys_newdactimeminusrealtime = -1e20; -static double sys_newadctimeminusrealtime = -1e20; -static double sys_whenupdate; - -void sys_initmidiqueue() { - sys_midiinittime = clock_getlogicaltime(); - sys_dactimeminusrealtime = sys_adctimeminusrealtime = 0; -} - -/* this is called from the OS dependent code from time to time when we - think we know the delay (outbuftime) in seconds, at which the last-output - audio sample will go out the door. */ -void sys_setmiditimediff(double inbuftime, double outbuftime) { - double dactimeminusrealtime = .001 * clock_gettimesince(sys_midiinittime) - outbuftime - sys_getrealtime(); - double adctimeminusrealtime = .001 * clock_gettimesince(sys_midiinittime) + inbuftime - sys_getrealtime(); - if (dactimeminusrealtime > sys_newdactimeminusrealtime) sys_newdactimeminusrealtime = dactimeminusrealtime; - if (adctimeminusrealtime > sys_newadctimeminusrealtime) sys_newadctimeminusrealtime = adctimeminusrealtime; - if (sys_getrealtime() > sys_whenupdate) { - sys_dactimeminusrealtime = sys_newdactimeminusrealtime; - sys_adctimeminusrealtime = sys_newadctimeminusrealtime; - sys_newdactimeminusrealtime = -1e20; - sys_newadctimeminusrealtime = -1e20; - sys_whenupdate = sys_getrealtime() + 1; - } -} - -/* return the logical time of the DAC sample we believe is currently going out, based on how much "system time" - has elapsed since the last time sys_setmiditimediff got called. */ -static double sys_getmidioutrealtime() {return sys_getrealtime() + sys_dactimeminusrealtime;} -static double sys_getmidiinrealtime () {return sys_getrealtime() + sys_adctimeminusrealtime;} - -static void sys_putnext () { - t_midiqelem &m = midi_outqueue[midi_outtail]; - int portno = m.portno; -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) { - if (m.onebyte) sys_alsa_putmidibyte(portno, m.byte1); - else sys_alsa_putmidimess(portno, m.byte1, m.byte2, m.byte3); - } else -#endif /* ALSA */ - { - if (m.onebyte) sys_putmidibyte(portno, m.byte1); - else sys_putmidimess(portno, m.byte1, m.byte2, m.byte3); - } - midi_outtail = (midi_outtail + 1 == MIDIQSIZE ? 0 : midi_outtail + 1); -} - -/* #define TEST_DEJITTER */ - -void sys_pollmidioutqueue() { -#ifdef TEST_DEJITTER - static int db = 0; -#endif - double midirealtime = sys_getmidioutrealtime(); -#ifdef TEST_DEJITTER - if (midi_outhead == midi_outtail) db = 0; -#endif - while (midi_outhead != midi_outtail) { -#ifdef TEST_DEJITTER - if (!db) { - post("out: del %f, midiRT %f logicaltime %f, RT %f dacminusRT %f", - (midi_outqueue[midi_outtail].time - midirealtime), - midirealtime, .001 * clock_gettimesince(sys_midiinittime), - sys_getrealtime(), sys_dactimeminusrealtime); - db = 1; - } -#endif - if (midi_outqueue[midi_outtail].time <= midirealtime) - sys_putnext(); - else break; - } -} - -static void sys_queuemidimess(int portno, int onebyte, int a, int b, int c) { - int newhead = midi_outhead +1; - if (newhead == MIDIQSIZE) newhead = 0; - /* if FIFO is full flush an element to make room */ - if (newhead == midi_outtail) sys_putnext(); - t_midiqelem m = midi_outqueue[midi_outhead]; - m.portno = portno; - m.onebyte = onebyte; - m.byte1 = a; - m.byte2 = b; - m.byte3 = c; - m.time = .001 * clock_gettimesince(sys_midiinittime); - midi_outhead = newhead; - sys_pollmidioutqueue(); -} - -#define MIDI_NOTEON 144 -#define MIDI_POLYAFTERTOUCH 160 -#define MIDI_CONTROLCHANGE 176 -#define MIDI_PROGRAMCHANGE 192 -#define MIDI_AFTERTOUCH 208 -#define MIDI_PITCHBEND 224 - -void outmidi_noteon(int portno, int channel, int pitch, int velo) { - if (pitch < 0) pitch = 0; else if (pitch > 127) pitch = 127; - if (velo < 0) velo = 0; else if (velo > 127) velo = 127; - sys_queuemidimess(portno, 0, MIDI_NOTEON + (channel & 0xf), pitch, velo); -} - -void outmidi_controlchange(int portno, int channel, int ctl, int value) { - if (ctl < 0) ctl = 0; else if (ctl > 127) ctl = 127; - if (value < 0) value = 0; else if (value > 127) value = 127; - sys_queuemidimess(portno, 0, MIDI_CONTROLCHANGE + (channel & 0xf), - ctl, value); -} - -void outmidi_programchange(int portno, int channel, int value) { - if (value < 0) value = 0; else if (value > 127) value = 127; - sys_queuemidimess(portno, 0, MIDI_PROGRAMCHANGE + (channel & 0xf), value, 0); -} - -void outmidi_pitchbend(int portno, int channel, int value) { - if (value < 0) value = 0; else if (value > 16383) value = 16383; - sys_queuemidimess(portno, 0, MIDI_PITCHBEND + (channel & 0xf), (value & 127), ((value>>7) & 127)); -} - -void outmidi_aftertouch(int portno, int channel, int value) { - if (value < 0) value = 0; else if (value > 127) value = 127; - sys_queuemidimess(portno, 0, MIDI_AFTERTOUCH + (channel & 0xf), value, 0); -} - -void outmidi_polyaftertouch(int portno, int channel, int pitch, int value) { - if (pitch < 0) pitch = 0; else if (pitch > 127) pitch = 127; - if (value < 0) value = 0; else if (value > 127) value = 127; - sys_queuemidimess(portno, 0, MIDI_POLYAFTERTOUCH + (channel & 0xf), pitch, value); -} - -void outmidi_byte(int portno, int value) { -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) sys_alsa_putmidibyte(portno, value); else -#endif - sys_putmidibyte(portno, value); -} - -void outmidi_mclk(int portno) {sys_queuemidimess(portno, 1, 0xf8, 0,0);} - -/* ------------------------- MIDI input queue handling ------------------ */ -typedef struct midiparser { - int mp_status; - int mp_gotbyte1; - int mp_byte1; -} t_midiparser; - -#define MIDINOTEOFF 0x80 /* 2 following 'data bytes' */ -#define MIDINOTEON 0x90 /* 2 */ -#define MIDIPOLYTOUCH 0xa0 /* 2 */ -#define MIDICONTROLCHANGE 0xb0 /* 2 */ -#define MIDIPROGRAMCHANGE 0xc0 /* 1 */ -#define MIDICHANNELTOUCH 0xd0 /* 1 */ -#define MIDIPITCHBEND 0xe0 /* 2 */ -#define MIDISTARTSYSEX 0xf0 /* (until F7) */ -#define MIDITIMECODE 0xf1 /* 1 */ -#define MIDISONGPOS 0xf2 /* 2 */ -#define MIDISONGSELECT 0xf3 /* 1 */ -#define MIDIRESERVED1 0xf4 /* ? */ -#define MIDIRESERVED2 0xf5 /* ? */ -#define MIDITUNEREQUEST 0xf6 /* 0 */ -#define MIDIENDSYSEX 0xf7 /* 0 */ -#define MIDICLOCK 0xf8 /* 0 */ -#define MIDITICK 0xf9 /* 0 */ -#define MIDISTART 0xfa /* 0 */ -#define MIDICONT 0xfb /* 0 */ -#define MIDISTOP 0xfc /* 0 */ -#define MIDIACTIVESENSE 0xfe /* 0 */ -#define MIDIRESET 0xff /* 0 */ - -static void sys_dispatchnextmidiin() { - static t_midiparser parser[MAXMIDIINDEV], *parserp; - int portno = midi_inqueue[midi_intail].portno, byte = midi_inqueue[midi_intail].byte1; - if (!midi_inqueue[midi_intail].onebyte) bug("sys_dispatchnextmidiin"); - if (portno < 0 || portno >= MAXMIDIINDEV) bug("sys_dispatchnextmidiin 2"); - parserp = parser + portno; - outlet_setstacklim(); - if (byte >= 0xf8) { - inmidi_realtimein(portno, byte); - } else { - inmidi_byte(portno, byte); - if (byte & 0x80) { - if (byte == MIDITUNEREQUEST || byte == MIDIRESERVED1 || byte == MIDIRESERVED2) { - parserp->mp_status = 0; - } else if (byte == MIDISTARTSYSEX) { - inmidi_sysex(portno, byte); - parserp->mp_status = byte; - } else if (byte == MIDIENDSYSEX) { - inmidi_sysex(portno, byte); - parserp->mp_status = 0; - } else { - parserp->mp_status = byte; - } - parserp->mp_gotbyte1 = 0; - } else { - int cmd = (parserp->mp_status >= 0xf0 ? parserp->mp_status : - (parserp->mp_status & 0xf0)); - int chan = (parserp->mp_status & 0xf); - int byte1 = parserp->mp_byte1, gotbyte1 = parserp->mp_gotbyte1; - switch (cmd) { - case MIDINOTEOFF: - if (gotbyte1) inmidi_noteon(portno, chan, byte1, 0), parserp->mp_gotbyte1 = 0; - else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1; - break; - case MIDINOTEON: - if (gotbyte1) inmidi_noteon(portno, chan, byte1, byte), parserp->mp_gotbyte1 = 0; - else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1; - break; - case MIDIPOLYTOUCH: - if (gotbyte1) inmidi_polyaftertouch(portno, chan, byte1, byte), parserp->mp_gotbyte1 = 0; - else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1; - break; - case MIDICONTROLCHANGE: - if (gotbyte1) inmidi_controlchange(portno, chan, byte1, byte), parserp->mp_gotbyte1 = 0; - else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1; - break; - case MIDIPROGRAMCHANGE: - inmidi_programchange(portno, chan, byte); - break; - case MIDICHANNELTOUCH: - inmidi_aftertouch(portno, chan, byte); - break; - case MIDIPITCHBEND: - if (gotbyte1) inmidi_pitchbend(portno, chan, ((byte << 7) + byte1)), parserp->mp_gotbyte1 = 0; - else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1; - break; - case MIDISTARTSYSEX: - inmidi_sysex(portno, byte); - break; - /* other kinds of messages are just dropped here. We'll - need another status byte before we start letting MIDI in - again (no running status across "system" messages). */ - case MIDITIMECODE: break; /* 1 data byte*/ - case MIDISONGPOS: break; /* 2 */ - case MIDISONGSELECT: break; /* 1 */ - } - } - } - midi_intail = (midi_intail + 1 == MIDIQSIZE ? 0 : midi_intail + 1); -} - -void sys_pollmidiinqueue() { -#ifdef TEST_DEJITTER - static int db = 0; -#endif - double logicaltime = .001 * clock_gettimesince(sys_midiinittime); -#ifdef TEST_DEJITTER - if (midi_inhead == midi_intail) - db = 0; -#endif - while (midi_inhead != midi_intail) { -#ifdef TEST_DEJITTER - if (!db) { - post("in del %f, logicaltime %f, RT %f adcminusRT %f", - (midi_inqueue[midi_intail].time - logicaltime), - logicaltime, sys_getrealtime(), sys_adctimeminusrealtime); - db = 1; - } -#endif -#if 0 - if (midi_inqueue[midi_intail].time <= logicaltime - 0.007) - post("late %f", 1000 * (logicaltime - midi_inqueue[midi_intail].time)); -#endif - if (midi_inqueue[midi_intail].time <= logicaltime) { -#if 0 - post("diff %f", 1000* (logicaltime - midi_inqueue[midi_intail].time)); -#endif - sys_dispatchnextmidiin(); - } - else break; - } -} - - /* this should be called from the system dependent MIDI code when a byte - comes in, as a result of our calling sys_poll_midi. We stick it on a - timetag queue and dispatch it at the appropriate logical time. */ - - -void sys_midibytein(int portno, int byte) { - static int warned = 0; - int newhead = midi_inhead+1; - if (newhead == MIDIQSIZE) newhead = 0; - /* if FIFO is full flush an element to make room */ - if (newhead == midi_intail) { - if (!warned) { - post("warning: MIDI timing FIFO overflowed"); - warned = 1; - } - sys_dispatchnextmidiin(); - } - midi_inqueue[midi_inhead].portno = portno; - midi_inqueue[midi_inhead].onebyte = 1; - midi_inqueue[midi_inhead].byte1 = byte; - midi_inqueue[midi_inhead].time = sys_getmidiinrealtime(); - midi_inhead = newhead; - sys_pollmidiinqueue(); -} - -void sys_pollmidiqueue() { -#if 0 - static double lasttime; - double newtime = sys_getrealtime(); - if (newtime - lasttime > 0.007) - post("delay %d", (int)(1000 * (newtime - lasttime))); - lasttime = newtime; -#endif -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) sys_alsa_poll_midi(); - else -#endif /* ALSA */ - sys_poll_midi(); /* OS dependent poll for MIDI input */ - sys_pollmidioutqueue(); - sys_pollmidiinqueue(); -} - -/******************** dialog window and device listing ********************/ - -#ifdef USEAPI_ALSA -void midi_alsa_init(); -#endif -#ifndef USEAPI_PORTMIDI -#ifdef USEAPI_OSS -void midi_oss_init(); -#endif -#endif - -/* last requested parameters */ -static int midi_nmidiindev; -static int midi_midiindev[MAXMIDIINDEV]; -static int midi_nmidioutdev; -static int midi_midioutdev[MAXMIDIOUTDEV]; - -void sys_get_midi_apis(char *buf) { - int n = 0; - strcpy(buf, "{ "); - sprintf(buf + strlen(buf), "{default-MIDI %d} ", API_DEFAULT); n++; -#ifdef USEAPI_ALSA - sprintf(buf + strlen(buf), "{ALSA-MIDI %d} ", API_ALSA); n++; -#endif - strcat(buf, "}"); -} -void sys_get_midi_params(int *pnmidiindev, int *pmidiindev, int *pnmidioutdev, int *pmidioutdev) { - *pnmidiindev = midi_nmidiindev; for (int i=0; i<MAXMIDIINDEV; i++) pmidiindev [i] = midi_midiindev[i]; - *pnmidioutdev = midi_nmidioutdev; for (int i=0; i<MAXMIDIOUTDEV; i++) pmidioutdev[i] = midi_midioutdev[i]; -} -static void sys_save_midi_params(int nmidiindev, int *midiindev, int nmidioutdev, int *midioutdev) { - midi_nmidiindev = nmidiindev; for (int i=0; i<MAXMIDIINDEV; i++) midi_midiindev [i] = midiindev[i]; - midi_nmidioutdev = nmidioutdev; for (int i=0; i<MAXMIDIOUTDEV; i++) midi_midioutdev[i] = midioutdev[i]; -} - -void sys_open_midi(int nmidiindev, int *midiindev, int nmidioutdev, int *midioutdev, int enable) { -#ifdef USEAPI_ALSA - midi_alsa_init(); -#endif -#ifndef USEAPI_PORTMIDI -#ifdef USEAPI_OSS - midi_oss_init(); -#endif -#endif - if (enable) { -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) sys_alsa_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev); - else -#endif /* ALSA */ - sys_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev); - } - sys_save_midi_params(nmidiindev, midiindev, nmidioutdev, midioutdev); - sys_vgui("set pd_whichmidiapi %d\n", sys_midiapi); -} - -/* open midi using whatever parameters were last used */ -void sys_reopen_midi() { - int nmidiindev, midiindev[MAXMIDIINDEV]; - int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; - sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev); - sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 1); -} - -#define MAXNDEV 50 -#define DEVDESCSIZE 80 -#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */ - -void sys_listmididevs() { - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0; -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) - midi_alsa_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); - else -#endif /* ALSA */ - midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); - if (!nindevs) post("no midi input devices found"); - else post("MIDI input devices:"); for (int i=0; i<nindevs; i++) post("%d. %s", i+1, indevlist + i * DEVDESCSIZE); - if (!noutdevs) post("no midi output devices found"); - else post("MIDI output devices:"); for (int i=0; i<noutdevs; i++) post("%d. %s", i+DEVONSET, outdevlist + i * DEVDESCSIZE); -} - -void sys_set_midi_api(int which) { - sys_midiapi = which; - if (sys_verbose) post("sys_midiapi %d", sys_midiapi); -} - -void glob_midi_properties(t_pd *dummy, t_floatarg flongform); - -void glob_midi_setapi(t_pd *dummy, t_floatarg f) { - int newapi = int(f); - if (newapi) { - if (newapi == sys_midiapi) { - //if (!midi_isopen()) s_reopen_midi(); - } else { -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) sys_alsa_close_midi(); - else -#endif - sys_close_midi(); - sys_midiapi = newapi; - /* bash device params back to default */ - midi_nmidiindev = midi_nmidioutdev = 1; - //midi_midiindev[0] = midi_midioutdev[0] = DEFAULTMIDIDEV; - //midi_midichindev[0] = midi_midichoutdev[0] = SYS_DEFAULTCH; - sys_reopen_midi(); - } - glob_midi_properties(0, 0); - } else /* if (midi_isopen()) */ { - sys_close_midi(); - //midi_state = 0; - } -} - -extern t_class *glob_pdobject; - -/* start a midi settings dialog window */ -void glob_midi_properties(t_pd *dummy, t_floatarg flongform) { - /* these are the devices you're using: */ - int nindev, midiindev[MAXMIDIINDEV]; - int noutdev, midioutdev[MAXMIDIOUTDEV]; - char midiinstr[16*4+1],midioutstr[16*4+1],*s; - /* these are all the devices on your system: */ - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0; - char indevl[MAXNDEV*(DEVDESCSIZE+4)+80]; - char outdevl[MAXNDEV*(DEVDESCSIZE+4)+80]; - midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); - *indevl=0; for (int i=0; i< nindevs; i++) sprintf( indevl+strlen( indevl), "\"%s\" ", indevlist + i * DEVDESCSIZE); - *outdevl=0; for (int i=0; i<noutdevs; i++) sprintf(outdevl+strlen(outdevl), "\"%s\" ", outdevlist + i * DEVDESCSIZE); - sys_get_midi_params(&nindev, midiindev, &noutdev, midioutdev); - if (nindev > 1 || noutdev > 1) flongform = 1; - s=midiinstr ; *s=0; for(int i=0; i<16; ++i) {sprintf(s,"%3d ", nindev>i && midiindev[i] >=0? midiindev[i]:-1); s+=strlen(s);} - s=midioutstr; *s=0; for(int i=0; i<16; ++i) {sprintf(s,"%3d ",noutdev>i && midioutdev[i]>=0?midioutdev[i]:-1); s+=strlen(s);} - sys_vgui("pdtk_midi_dialog %%s {%s} %s {%s} %s %d\n", indevl,midiinstr,outdevl,midioutstr,!!flongform); -} - -/* new values from dialog window */ -void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { - int i, nindev, noutdev, newmidiindev[16], newmidioutdev[16], alsadevin, alsadevout; - for (int i=0; i<16; i++) { - newmidiindev[i] = atom_getintarg(i , argc, argv); - newmidioutdev[i] = atom_getintarg(i+16, argc, argv); - } - for (i=0, nindev=0; i<16; i++) {if ( newmidiindev[i] >= 0) { newmidiindev[nindev] = newmidiindev[i]; nindev++;}} - for (i=0, noutdev=0; i<16; i++) {if (newmidioutdev[i] >= 0) {newmidioutdev[noutdev] = newmidioutdev[i]; noutdev++;}} - alsadevin = atom_getintarg(32, argc, argv); - alsadevout = atom_getintarg(33, argc, argv); -#ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) { - sys_alsa_close_midi(); - sys_open_midi(alsadevin, newmidiindev, alsadevout, newmidioutdev, 1); - } else -#endif - { - sys_close_midi(); - sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev, 1); - } -} - -/* tb { */ -void glob_midi_getindevs(t_pd *dummy, t_symbol *s, int ac, t_atom *av) { - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0; t_symbol *selector = gensym("midiindev"); t_symbol *pd = gensym("pd"); - t_atom argv[MAXNDEV]; int f = ac ? (int)atom_getfloatarg(0,ac,av) : -1; - midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); - if (f<0) { - for (int i=0; i<nindevs; i++) SETSYMBOL(argv+i, gensym(indevlist + i * DEVDESCSIZE)); - typedmess(pd->s_thing, selector, nindevs, argv); - } else if (f < nindevs) { - SETSYMBOL(argv, gensym(indevlist + f * DEVDESCSIZE)); - typedmess(pd->s_thing, selector, 1, argv); - } -} -void glob_midi_getoutdevs(t_pd *dummy, t_symbol *s, int ac, t_atom *av) { - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0; t_symbol *selector = gensym("midioutdev"); t_symbol *pd = gensym("pd"); - t_atom argv[MAXNDEV]; int f = ac ? (int)atom_getfloatarg(0,ac,av) : -1; - midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); - if (f<0) { - for (int i=0; i<noutdevs; i++) SETSYMBOL(argv+i, gensym(outdevlist + i*DEVDESCSIZE)); - typedmess(pd->s_thing, selector, noutdevs, argv); - } else if (f < noutdevs) { - SETSYMBOL(argv, gensym(outdevlist + f*DEVDESCSIZE)); - typedmess(pd->s_thing, selector, 1, argv); - } -} - -#define FOO(N,D,M) \ - int nindev, midiindev[MAXMIDIINDEV], noutdev, midioutdev[MAXMIDIOUTDEV]; \ - t_atom argv[MAXNDEV]; sys_get_midi_params(&nindev, midiindev, &noutdev, midioutdev); \ - for (int i=0; i<N; i++) SETFLOAT(argv+i, D[i]); \ - typedmess(gensym("pd")->s_thing, gensym(M), nindev, argv); -void glob_midi_getcurrentindevs( t_pd *dummy) {FOO( nindev,midiindev ,"midicurrentindev" )} -void glob_midi_getcurrentoutdevs(t_pd *dummy) {FOO(noutdev,midioutdev,"midicurrentoutdev")} diff --git a/desiredata/src/s_midi_alsa.c b/desiredata/src/s_midi_alsa.c deleted file mode 100644 index d4becccc..00000000 --- a/desiredata/src/s_midi_alsa.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* MIDI I/O for Linux using ALSA */ - -#include <stdio.h> -#ifdef UNISTD -#include <unistd.h> -#endif -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <alsa/asoundlib.h> -#include "desire.h" -using namespace desire; - -#define MAX_EVENT_SIZE 256 - -static int alsa_nmidiin; -static int alsa_midiinfd[MAXMIDIINDEV]; -static int alsa_nmidiout; -static int alsa_midioutfd[MAXMIDIOUTDEV]; -static snd_seq_t *midi_handle; -static snd_midi_event_t *midiev; - -static unsigned short CombineBytes(unsigned char First, unsigned char Second) { - return ((unsigned short)Second << 7) | (unsigned short)First; -} - -void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { - char portname[50]; - int err = 0; - snd_seq_client_info_t *alsainfo; - /* do we want to connect pd automatically with other devices ?; see below! */ - /* LATER: think about a flag to enable/disable automatic connection (sometimes it could be a pain) */ - int autoconnect = 1; - alsa_nmidiin = 0; - alsa_nmidiout = 0; - if (nmidiout == 0 && nmidiin == 0) return; - if (nmidiin>MAXMIDIINDEV) {post( "midi input ports reduced to maximum %d", MAXMIDIINDEV); nmidiin =MAXMIDIINDEV;} - if (nmidiout>MAXMIDIOUTDEV) {post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV); nmidiout=MAXMIDIOUTDEV;} - if (nmidiin>0 && nmidiout>0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0); - else if (nmidiin > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0); - else if (nmidiout > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0); - if (err!=0) { - sys_setalarm(1000000); - post("couldn't open alsa sequencer"); - return; - } - int client; - for (int i=0; i<nmidiin; i++) { - sprintf(portname,"Pure Data Midi-In %d",i+1); - int port = snd_seq_create_simple_port(midi_handle,portname, - SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); - if (port < 0) goto error; - alsa_midiinfd[i] = port; - } - for (int i=0; i<nmidiout; i++) { - sprintf(portname,"Pure Data Midi-Out %d",i+1); - int port = snd_seq_create_simple_port(midi_handle,portname, - SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); - if (port < 0) goto error; - alsa_midioutfd[i] = port; - } - snd_seq_client_info_malloc(&alsainfo); - snd_seq_get_client_info(midi_handle,alsainfo); - snd_seq_client_info_set_name(alsainfo,"Pure Data"); - client = snd_seq_client_info_get_client(alsainfo); - snd_seq_set_client_info(midi_handle,alsainfo); - snd_seq_client_info_free(alsainfo); - post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout); - sys_setalarm(0); - snd_midi_event_new(MAX_EVENT_SIZE,&midiev); - alsa_nmidiout = nmidiout; - alsa_nmidiin = nmidiin; - /* JMZ: connect all available devices to pd */ - if (autoconnect) { - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - snd_seq_port_subscribe_t *subs; - snd_seq_addr_t other, topd, frompd; - /* since i don't know how to connect multiple ports (connect everything to each port, modulo,...), - * i only fully connect where we have only one single port */ - if(alsa_nmidiin ) { topd.client = client; topd.port = alsa_midiinfd [0];} - if(alsa_nmidiout) {frompd.client = client; frompd.port = alsa_midioutfd[0];} - snd_seq_port_subscribe_alloca(&subs); - snd_seq_client_info_alloca(&cinfo); - snd_seq_port_info_alloca(&pinfo); - snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(midi_handle, cinfo) >= 0) { - /* reset query info */ - int client_id=snd_seq_client_info_get_client(cinfo); - if((SND_SEQ_CLIENT_SYSTEM != client_id)&&(client != client_id)) { /* skipping port 0 and ourself */ - snd_seq_port_info_set_client(pinfo, client_id); - snd_seq_port_info_set_port(pinfo, -1); - while (snd_seq_query_next_port(midi_handle, pinfo) >= 0) { - other.client=client_id; - other.port =snd_seq_port_info_get_port(pinfo); - if(1==alsa_nmidiin) /* only autoconnect 1st port */ { - snd_seq_port_subscribe_set_sender(subs, &other); - snd_seq_port_subscribe_set_dest(subs, &topd); - snd_seq_subscribe_port(midi_handle, subs); - } - if(1==alsa_nmidiout) /* only autoconnect 1st port */ { - snd_seq_port_subscribe_set_sender(subs, &frompd); - snd_seq_port_subscribe_set_dest(subs, &other); - snd_seq_subscribe_port(midi_handle, subs); - } - } - } - } - } - return; - error: - sys_setalarm(1000000); - post("couldn't open alsa MIDI output device"); - return; -} - -void sys_alsa_putmidimess(int portno, int a, int b, int c) { - int channel = a&15; - snd_seq_event_t ev; - snd_seq_ev_clear(&ev); - if (portno >= 0 && portno < alsa_nmidiout) { - if (a >= 224) snd_seq_ev_set_pitchbend(&ev,channel,CombineBytes(b,c)); - else if (a >= 208) snd_seq_ev_set_chanpress(&ev,channel,b); // touch - else if (a >= 192) snd_seq_ev_set_pgmchange(&ev,channel,b); - else if (a >= 176) snd_seq_ev_set_controller(&ev,channel,b,c); - else if (a >= 160) snd_seq_ev_set_keypress(&ev,channel,b,c);// polytouch - else if (a >= 144) { // note - channel = a-144; - if (c) snd_seq_ev_set_noteon(&ev,channel,b,c); - else snd_seq_ev_set_noteoff(&ev,channel,b,c); - } - snd_seq_ev_set_direct(&ev); - snd_seq_ev_set_subs(&ev); - snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]); - snd_seq_event_output_direct(midi_handle,&ev); - } -} - -void sys_alsa_putmidibyte(int portno, int byte) { - snd_seq_event_t ev; - snd_seq_ev_clear(&ev); - if (portno >= 0 && portno < alsa_nmidiout) { - // repack into 1 byte char and put somewhere to point at - unsigned char data = (unsigned char)byte; - snd_seq_ev_set_sysex(&ev,1,&data); //...set_variable *should* have worked but didn't - snd_seq_ev_set_direct(&ev); - snd_seq_ev_set_subs(&ev); - snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]); - snd_seq_event_output_direct(midi_handle,&ev); - } -} - -/* this version uses the asynchronous "read()" ... */ -void sys_alsa_poll_midi() { - unsigned char buf[MAX_EVENT_SIZE]; - int count, alsa_source; - snd_seq_event_t *midievent = NULL; - if (alsa_nmidiout == 0 && alsa_nmidiin == 0) return; - snd_midi_event_init(midiev); - if (!alsa_nmidiout && !alsa_nmidiin) return; - count = snd_seq_event_input_pending(midi_handle,1); - if (count != 0) count = snd_seq_event_input(midi_handle,&midievent); - if (midievent != NULL) { - count = snd_midi_event_decode(midiev,buf,sizeof(buf),midievent); - alsa_source = midievent->dest.port; - for(int i=0; i<count; i++) sys_midibytein(alsa_source, (buf[i] & 0xff)); - //post("received %d midi bytes",count); - } -} - -void sys_alsa_close_midi() { - alsa_nmidiin = alsa_nmidiout = 0; - if(midi_handle) { - snd_seq_close(midi_handle); - if(midiev) snd_midi_event_free(midiev); - } -} - -#define NSEARCH 10 -static int alsa_nmidiindevs, alsa_nmidioutdevs, alsa_initted; - -void midi_alsa_init() { - if (alsa_initted) return; - alsa_initted = 1; -} - -void midi_alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize) { - int ndev = min(maxndev,alsa_nmidiindevs); - for (int i=0; i<ndev; i++) sprintf(indevlist + i * devdescsize, "ALSA MIDI device #%d", i+1); - *nindevs = ndev; - ndev = min(maxndev,alsa_nmidioutdevs); - for (int i=0; i<ndev; i++) sprintf(outdevlist + i * devdescsize, "ALSA MIDI device #%d", i+1); - *noutdevs = ndev; -} diff --git a/desiredata/src/s_midi_mmio.c b/desiredata/src/s_midi_mmio.c deleted file mode 100644 index fc30be4b..00000000 --- a/desiredata/src/s_midi_mmio.c +++ /dev/null @@ -1,487 +0,0 @@ -/* Copyright (c) 1997-1999 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -#include "desire.h" -#include <stdio.h> -#include <windows.h> -#include <mmsystem.h> -using namespace desire; - -/* ------------- MIDI time stamping from audio clock ------------ */ -#ifdef MIDI_TIMESTAMP - -static double msw_hibuftime; -static double initsystime = -1; - -/* call this whenever we reset audio */ -static void msw_resetmidisync() { - initsystime = clock_getsystime(); - msw_hibuftime = sys_getrealtime(); -} - -/* call this whenever we're idled waiting for audio to be ready. The routine maintains a high and low water point - for the difference between real and DAC time. */ -static void msw_midisync() { - if (initsystime == -1) msw_resetmidisync(); - double jittersec = max(msw_dacjitterbufsallowed,msw_adcjitterbufsallowed) * REALDACBLKSIZE / sys_getsr(); - double diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime); - if (diff > msw_hibuftime) msw_hibuftime = diff; - if (diff < msw_hibuftime - jittersec) { - post("jitter excess %d %f", dac, diff); - msw_resetmidisync(); - } -} - -static double msw_midigettimefor(LARGE_INTEGER timestamp) { - /* this is broken now... used to work when "timestamp" was derived from QueryPerformanceCounter() instead of - the MS-approved timeGetSystemTime() call in the MIDI callback routine below. */ - return msw_tixtotime(timestamp) - msw_hibuftime; -} -#endif /* MIDI_TIMESTAMP */ - -/* ------------------------- MIDI output -------------------------- */ -static void msw_midiouterror(const char *s, int err) { - char t[256]; - midiOutGetErrorText(err, t, 256); - error(s,t); -} - -static HMIDIOUT hMidiOut[MAXMIDIOUTDEV]; /* output device */ -static int msw_nmidiout; /* number of devices */ - -static void msw_open_midiout(int nmidiout, int *midioutvec) { - UINT result, wRtn; - MIDIOUTCAPS midioutcaps; - if (nmidiout > MAXMIDIOUTDEV) nmidiout = MAXMIDIOUTDEV; - int dev = 0; - for (int i=0; i<nmidiout; i++) { - MIDIOUTCAPS m; - int devno = midioutvec[i]; - result = midiOutOpen(&hMidiOut[dev], devno, 0, 0, CALLBACK_NULL); - wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) &m, sizeof(m)); - if (result != MMSYSERR_NOERROR) { - error("midiOutOpen: %s",midioutcaps.szPname); - msw_midiouterror("midiOutOpen: %s", result); - } else { - if (sys_verbose) error("midiOutOpen: Open %s as Port %d", midioutcaps.szPname, dev); - dev++; - } - } - msw_nmidiout = dev; -} - -static void msw_close_midiout() { - for (int i=0; i<msw_nmidiout; i++) { - midiOutReset(hMidiOut[i]); - midiOutClose(hMidiOut[i]); - } - msw_nmidiout = 0; -} - -/* -------------------------- MIDI input ---------------------------- */ - -#define INPUT_BUFFER_SIZE 1000 // size of input buffer in events - -static void msw_midiinerror(const char *s, int err) { - char t[256]; - midiInGetErrorText(err, t, 256); - error(s,t); -} - -/* Structure to represent a single MIDI event. */ -#define EVNT_F_ERROR 0x00000001L -typedef struct evemsw_tag { - DWORD fdwEvent; - DWORD dwDevice; - LARGE_INTEGER timestamp; - DWORD data; -} EVENT; -typedef EVENT FAR *LPEVENT; - -/* Structure to manage the circular input buffer. */ -typedef struct circularBuffer_tag { - HANDLE hSelf; /* handle to this structure */ - HANDLE hBuffer; /* buffer handle */ - WORD wError; /* error flags */ - DWORD dwSize; /* buffer size (in EVENTS) */ - DWORD dwCount; /* byte count (in EVENTS) */ - LPEVENT lpStart; /* ptr to start of buffer */ - LPEVENT lpEnd; /* ptr to end of buffer (last byte + 1) */ - LPEVENT lpHead; /* ptr to head (next location to fill) */ - LPEVENT lpTail; /* ptr to tail (next location to empty) */ -} CIRCULARBUFFER; -typedef CIRCULARBUFFER FAR *LPCIRCULARBUFFER; - -/* Structure to pass instance data from the application to the low-level callback function. */ -typedef struct callbackInstance_tag { - HANDLE hSelf; - DWORD dwDevice; - LPCIRCULARBUFFER lpBuf; -} CALLBACKINSTANCEDATA; -typedef CALLBACKINSTANCEDATA FAR *LPCALLBACKINSTANCEDATA; - -/* Function prototypes */ -LPCALLBACKINSTANCEDATA FAR PASCAL AllocCallbackInstanceData(); -void FAR PASCAL FreeCallbackInstanceData(LPCALLBACKINSTANCEDATA lpBuf); -LPCIRCULARBUFFER AllocCircularBuffer(DWORD dwSize); -void FreeCircularBuffer(LPCIRCULARBUFFER lpBuf); -WORD FAR PASCAL GetEvent(LPCIRCULARBUFFER lpBuf, LPEVENT lpEvent); - -// Callback instance data pointers -LPCALLBACKINSTANCEDATA lpCallbackInstanceData[MAXMIDIINDEV]; - -UINT wNumDevices = 0; // Number of MIDI input devices opened -BOOL bRecordingEnabled = 1; // Enable/disable recording flag -int nNumBufferLines = 0; // Number of lines in display buffer -RECT rectScrollClip; // Clipping rectangle for scrolling -LPCIRCULARBUFFER lpInputBuffer; // Input buffer structure -EVENT incomingEvent; // Incoming MIDI event structure -MIDIINCAPS midiInCaps[MAXMIDIINDEV]; // Device capabilities structures -HMIDIIN hMidiIn[MAXMIDIINDEV]; // MIDI input device handles - -/* AllocCallbackInstanceData - Allocates a CALLBACKINSTANCEDATA structure. This structure is used to pass information - to the low-level callback function, each time it receives a message. Because this structure is accessed by the - low-level callback function, it must be allocated using GlobalAlloc() with the GMEM_SHARE and GMEM_MOVEABLE flags - and page-locked with GlobalPageLock(). - Return: A pointer to the allocated CALLBACKINSTANCE data structure. */ -LPCALLBACKINSTANCEDATA FAR PASCAL AllocCallbackInstanceData() { - HANDLE hMem; - LPCALLBACKINSTANCEDATA lpBuf; - /* Allocate and lock global memory. */ - hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, (DWORD)sizeof(CALLBACKINSTANCEDATA)); - if(!hMem) return 0; - lpBuf = (LPCALLBACKINSTANCEDATA)GlobalLock(hMem); - if(!lpBuf) {GlobalFree(hMem); return 0;} - /* Page lock the memory. */ - //GlobalPageLock((HGLOBAL)HIWORD(lpBuf)); - /* Save the handle. */ - lpBuf->hSelf = hMem; - return lpBuf; -} - -/* FreeCallbackInstanceData - Frees the given CALLBACKINSTANCEDATA structure. - * Params: lpBuf - Points to the CALLBACKINSTANCEDATA structure to be freed. */ -void FAR PASCAL FreeCallbackInstanceData(LPCALLBACKINSTANCEDATA lpBuf) { - HANDLE hMem; - /* Save the handle until we're through here. */ - hMem = lpBuf->hSelf; - /* Free the structure. */ - //GlobalPageUnlock((HGLOBAL)HIWORD(lpBuf)); - GlobalUnlock(hMem); - GlobalFree(hMem); -} - -/* AllocCircularBuffer - Allocates memory for a CIRCULARBUFFER structure - * and a buffer of the specified size. Each memory block is allocated - * with GlobalAlloc() using GMEM_SHARE and GMEM_MOVEABLE flags, locked - * with GlobalLock(), and page-locked with GlobalPageLock(). - * Params: dwSize - The size of the buffer, in events. - * Return: A pointer to a CIRCULARBUFFER structure identifying the allocated display buffer. NULL if the buffer could not be allocated. */ - -LPCIRCULARBUFFER AllocCircularBuffer(DWORD dwSize) { - HANDLE hMem; - LPCIRCULARBUFFER lpBuf; - LPEVENT lpMem; - /* Allocate and lock a CIRCULARBUFFER structure. */ - hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, (DWORD)sizeof(CIRCULARBUFFER)); - if(!hMem) return 0; - lpBuf = (LPCIRCULARBUFFER)GlobalLock(hMem); - if(!lpBuf) {GlobalFree(hMem); return 0;} - /* Page lock the memory. Global memory blocks accessed by low-level callback functions must be page locked. */ -#ifndef _WIN32 - GlobalSmartPageLock((HGLOBAL)HIWORD(lpBuf)); -#endif - /* Save the memory handle. */ - lpBuf->hSelf = hMem; - /* Allocate and lock memory for the actual buffer. */ - hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, dwSize * sizeof(EVENT)); - if(!hMem) { -#ifndef _WIN32 - GlobalSmartPageUnlock((HGLOBAL)HIWORD(lpBuf)); -#endif - GlobalUnlock(lpBuf->hSelf); - GlobalFree(lpBuf->hSelf); - return 0; - } - lpMem = (LPEVENT)GlobalLock(hMem); - if(!lpMem) { - GlobalFree(hMem); -#ifndef _WIN32 - GlobalSmartPageUnlock((HGLOBAL)HIWORD(lpBuf)); -#endif - GlobalUnlock(lpBuf->hSelf); - GlobalFree(lpBuf->hSelf); - return NULL; - } - /* Page lock the memory. Global memory blocks accessed by low-level callback functions must be page locked. */ -#ifndef _WIN32 - GlobalSmartPageLock((HGLOBAL)HIWORD(lpMem)); -#endif - /* Set up the CIRCULARBUFFER structure. */ - lpBuf->hBuffer = hMem; - lpBuf->wError = 0; - lpBuf->dwSize = dwSize; - lpBuf->dwCount = 0L; - lpBuf->lpStart = lpMem; - lpBuf->lpEnd = lpMem + dwSize; - lpBuf->lpTail = lpMem; - lpBuf->lpHead = lpMem; - return lpBuf; -} - -/* FreeCircularBuffer - Frees the memory for the given CIRCULARBUFFER structure and the memory for the buffer it references. - * Params: lpBuf - Points to the CIRCULARBUFFER to be freed. */ -void FreeCircularBuffer(LPCIRCULARBUFFER lpBuf) { - HANDLE hMem; - /* Free the buffer itself. */ -#ifndef _WIN32 - GlobalSmartPageUnlock((HGLOBAL)HIWORD(lpBuf->lpStart)); -#endif - GlobalUnlock(lpBuf->hBuffer); - GlobalFree(lpBuf->hBuffer); - /* Free the CIRCULARBUFFER structure. */ - hMem = lpBuf->hSelf; -#ifndef _WIN32 - GlobalSmartPageUnlock((HGLOBAL)HIWORD(lpBuf)); -#endif - GlobalUnlock(hMem); - GlobalFree(hMem); -} - -/* GetEvent - Gets a MIDI event from the circular input buffer. Events - * are removed from the buffer. The corresponding PutEvent() function - * is called by the low-level callback function, so it must reside in - * the callback DLL. PutEvent() is defined in the CALLBACK.C module. - * - * Params: lpBuf - Points to the circular buffer. - * lpEvent - Points to an EVENT structure that is filled with the retrieved event. - * Return: Returns non-zero if successful, zero if there are no events to get. */ -WORD FAR PASCAL GetEvent(LPCIRCULARBUFFER lpBuf, LPEVENT lpEvent) { - /* If no event available, return */ - if (!wNumDevices || lpBuf->dwCount <= 0) return 0; - /* Get the event. */ - *lpEvent = *lpBuf->lpTail; - /* Decrement the byte count, bump the tail pointer. */ - --lpBuf->dwCount; - ++lpBuf->lpTail; - /* Wrap the tail pointer, if necessary. */ - if (lpBuf->lpTail >= lpBuf->lpEnd) lpBuf->lpTail = lpBuf->lpStart; - return 1; -} - -/* PutEvent - Puts an EVENT in a CIRCULARBUFFER. If the buffer is full, - * it sets the wError element of the CIRCULARBUFFER structure - * to be non-zero. - * - * Params: lpBuf - Points to the CIRCULARBUFFER. - * lpEvent - Points to the EVENT. */ - -void FAR PASCAL PutEvent(LPCIRCULARBUFFER lpBuf, LPEVENT lpEvent) { - /* If the buffer is full, set an error and return. */ - if(lpBuf->dwCount >= lpBuf->dwSize){ - lpBuf->wError = 1; - return; - } - /* Put the event in the buffer, bump the head pointer and the byte count. */ - *lpBuf->lpHead = *lpEvent; - ++lpBuf->lpHead; - ++lpBuf->dwCount; - /* Wrap the head pointer, if necessary. */ - if(lpBuf->lpHead >= lpBuf->lpEnd) lpBuf->lpHead = lpBuf->lpStart; -} - -/* midiInputHandler - Low-level callback function to handle MIDI input. - * Installed by midiInOpen(). The input handler takes incoming - * MIDI events and places them in the circular input buffer. It then - * notifies the application by posting a MM_MIDIINPUT message. - * - * This function is accessed at interrupt time, so it should be as - * fast and efficient as possible. You can't make any - * Windows calls here, except PostMessage(). The only Multimedia - * Windows call you can make are timeGetSystemTime(), midiOutShortMsg(). - * - * Param: hMidiIn - Handle for the associated input device. - * wMsg - One of the MIM_***** messages. - * dwInstance - Points to CALLBACKINSTANCEDATA structure. - * dwParam1 - MIDI data. - * dwParam2 - Timestamp (in milliseconds) */ -void FAR PASCAL midiInputHandler(HMIDIIN hMidiIn, WORD wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { - EVENT event; - switch(wMsg) { - case MIM_OPEN: break; - /* The only error possible is invalid MIDI data, so just pass the invalid data on so we'll see it. */ - case MIM_ERROR: - case MIM_DATA: - event.fdwEvent = (wMsg == MIM_ERROR) ? EVNT_F_ERROR : 0; - event.dwDevice = ((LPCALLBACKINSTANCEDATA)dwInstance)->dwDevice; - event.data = dwParam1; -#ifdef MIDI_TIMESTAMP - event.timestamp = timeGetSystemTime(); -#endif - /* Put the MIDI event in the circular input buffer. */ - PutEvent(((LPCALLBACKINSTANCEDATA)dwInstance)->lpBuf, (LPEVENT)&event); - break; - default: break; - } -} - -void msw_open_midiin(int nmidiin, int *midiinvec) { - UINT wRtn; - unsigned int i; - unsigned int ndev = 0; - /* Allocate a circular buffer for low-level MIDI input. This buffer is filled by the low-level callback function - and emptied by the application. */ - lpInputBuffer = AllocCircularBuffer((DWORD)(INPUT_BUFFER_SIZE)); - if (!lpInputBuffer) { - printf("Not enough memory available for input buffer.\n"); - return; - } - /* Open all MIDI input devices after allocating and setting up instance data for each device. The instance data is - used to pass buffer management information between the application and the low-level callback function. It also - includes a device ID, a handle to the MIDI Mapper, and a handle to the application's display window, so the callback - can notify the window when input data is available. A single callback function is used to service all opened input devices. */ - for (i=0; (i<(unsigned)nmidiin) && (i<MAXMIDIINDEV); i++) { - if ((lpCallbackInstanceData[ndev] = AllocCallbackInstanceData()) == NULL) { - printf("Not enough memory available.\n"); - FreeCircularBuffer(lpInputBuffer); - return; - } - lpCallbackInstanceData[i]->dwDevice = i; - lpCallbackInstanceData[i]->lpBuf = lpInputBuffer; - wRtn = midiInOpen((LPHMIDIIN)&hMidiIn[ndev], midiinvec[i], (DWORD)midiInputHandler, - (DWORD)lpCallbackInstanceData[ndev], CALLBACK_FUNCTION); - if (wRtn) { - FreeCallbackInstanceData(lpCallbackInstanceData[ndev]); - msw_midiinerror("midiInOpen: %s", wRtn); - } else ndev++; - } - /* Start MIDI input. */ - for (i=0; i<ndev; i++) { - if (hMidiIn[i]) midiInStart(hMidiIn[i]); - } - wNumDevices = ndev; -} - -static void msw_close_midiin() { - unsigned int i; - /* Stop, reset, close MIDI input. Free callback instance data. */ - for (i=0; (i<wNumDevices) && (i<MAXMIDIINDEV); i++) { - if (hMidiIn[i]) { - if (sys_verbose) post("closing MIDI input %d...", i); - midiInStop(hMidiIn[i]); - midiInReset(hMidiIn[i]); - midiInClose(hMidiIn[i]); - FreeCallbackInstanceData(lpCallbackInstanceData[i]); - } - } - /* Free input buffer. */ - if (lpInputBuffer) FreeCircularBuffer(lpInputBuffer); - if (sys_verbose) post("...done"); - wNumDevices = 0; -} - -/* ------------------- public routines -------------------------- */ - -void sys_putmidimess(int portno, int a, int b, int c) { - DWORD foo; - MMRESULT res; - if (portno >= 0 && portno < msw_nmidiout) { - foo = (a & 0xff) | ((b & 0xff) << 8) | ((c & 0xff) << 16); - res = midiOutShortMsg(hMidiOut[portno], foo); - if (res != MMSYSERR_NOERROR) post("MIDI out error %d", res); - } -} - -void sys_putmidibyte(int portno, int byte) { - MMRESULT res; - if (portno >= 0 && portno < msw_nmidiout) { - res = midiOutShortMsg(hMidiOut[portno], byte); - if (res != MMSYSERR_NOERROR) post("MIDI out error %d", res); - } -} - -void sys_poll_midi() { - static EVENT msw_nextevent; - static int msw_isnextevent; -#ifdef MIDI_TIMESTAMP - static double msw_nexteventtime; -#endif - while (1) { - if (!msw_isnextevent) { - if (!GetEvent(lpInputBuffer, &msw_nextevent)) break; - msw_isnextevent = 1; -#ifdef MIDI_TIMESTAMP - msw_nexteventtime = msw_midigettimefor(&foo.timestamp); -#endif - } -#ifdef MIDI_TIMESTAMP - if (0.001 * clock_gettimesince(initsystime) >= msw_nexteventtime) -#endif - { - int msgtype = ((msw_nextevent.data & 0xf0) >> 4) - 8; - int commandbyte = msw_nextevent.data & 0xff; - int byte1 = (msw_nextevent.data >> 8) & 0xff; - int byte2 = (msw_nextevent.data >> 16) & 0xff; - int portno = msw_nextevent.dwDevice; - switch (msgtype) { - case 0: case 1: case 2: case 3: case 6: - sys_midibytein(portno, commandbyte); - sys_midibytein(portno, byte1); - sys_midibytein(portno, byte2); - break; - case 4: case 5: - sys_midibytein(portno, commandbyte); - sys_midibytein(portno, byte1); - break; - case 7: - sys_midibytein(portno, commandbyte); - break; - } - msw_isnextevent = 0; - } - } -} - -void sys_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { - if (nmidiout) msw_open_midiout(nmidiout, midioutvec); - if (nmidiin) { - post("Warning: midi input is dangerous in Microsoft Windows; see Pd manual)"); - msw_open_midiin(nmidiin, midiinvec); - } -} - -void sys_close_midi() { - msw_close_midiin(); - msw_close_midiout(); -} - -#if 0 -/* list the audio and MIDI device names */ -void sys_listmididevs() { - /* for MIDI and audio in and out, get the number of devices. Then get the capabilities of each device and print its description. */ - UINT ndevices = midiInGetNumDevs(); - for (unsigned i=0; i<ndevices; i++) { - MIDIINCAPS m; UINT wRtn = midiInGetDevCaps( i, (LPMIDIINCAPS) &m, sizeof(m)); - if (wRtn) msw_midiinerror("midiInGetDevCaps: %s", wRtn); else error("MIDI input device #%d: %s", i+1, m.szPname); - } - ndevices = midiOutGetNumDevs(); - for (unsigned i=0; i<devices; i++) { - MIDIOUTCAPS m; UINT wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) &m, sizeof(m)); - if (wRtn) msw_midiouterror("midiOutGetDevCaps: %s", wRtn); else error("MIDI output device #%d: %s", i+1, m.szPname); - } -} -#endif - -void midi_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize) { - int nin = min(maxndev,int( midiInGetNumDevs())); - int nout = min(maxndev,int(midiOutGetNumDevs())); - for (int i=0; i<nin; i++) { - MIDIINCAPS m; UINT wRtn = midiInGetDevCaps(i, (LPMIDIINCAPS) &m, sizeof(m)); - strncpy(indevlist + i*devdescsize, (wRtn ? "???" : m.szPname), devdescsize); indevlist[(i+1)*devdescsize - 1] = 0;} - for (int i=0; i<nout; i++) { - MIDIOUTCAPS m; UINT wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) &m, sizeof(m)); - strncpy(outdevlist + i*devdescsize, (wRtn ? "???" : m.szPname), devdescsize); outdevlist[(i+1)*devdescsize - 1] = 0;} - *nindevs = nin; - *noutdevs = nout; -} diff --git a/desiredata/src/s_midi_none.c b/desiredata/src/s_midi_none.c deleted file mode 100644 index bae33783..00000000 --- a/desiredata/src/s_midi_none.c +++ /dev/null @@ -1,15 +0,0 @@ -/* This is for compiling pd without any midi support. by matju, 2006.11.21 */ - -#include "desire.h" - -void sys_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) {} -void sys_close_midi(void) {} -void sys_putmidimess(int portno, int a, int b, int c) {} -void sys_putmidibyte(int portno, int byte) {} -void sys_poll_midi(void) {} -void midi_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int maxndev, int devdescsize) -{ - *nindevs = 0; - *noutdevs = 0; -} diff --git a/desiredata/src/s_midi_oss.c b/desiredata/src/s_midi_oss.c deleted file mode 100644 index aa7b9d46..00000000 --- a/desiredata/src/s_midi_oss.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* MIDI I/O for Linux using OSS */ - -#include <stdio.h> -#ifdef UNISTD -#include <unistd.h> -#endif -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include "desire.h" -using namespace desire; - -static int oss_nmidiin; static int oss_midiinfd [MAXMIDIINDEV]; -static int oss_nmidiout; static int oss_midioutfd[MAXMIDIOUTDEV]; - -static void oss_midiout(int fd, int n) { - char b = n; - if ((write(fd, (char *) &b, 1)) != 1) perror("midi write"); -} - -#define O_MIDIFLAG O_NDELAY -#define SETALARM sys_setalarm(1000000) -#define ERR(mode) do {if (sys_verbose) error("device %d: tried %s %s; returned %d", devno, namebuf, mode, fd);} while (0) - -void sys_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { - for (int i=0; i<nmidiout; i++) oss_midioutfd[i] = -1; - oss_nmidiin = 0; - for (int i=0; i<nmidiin; i++) { - int fd = -1, outdevindex = -1; - char namebuf[80]; - int devno = midiinvec[i]; - for (int j=0; j<nmidiout; j++) if (midioutvec[j]==midiinvec[i]) outdevindex=j; - /* try to open the device for read/write. */ - if (outdevindex>=0) { - if (devno==0 && fd<0) {strcat(namebuf, "/dev/midi"); SETALARM; fd = open(namebuf, O_RDWR | O_MIDIFLAG); ERR("READ/WRITE");} - if (fd<0) {sprintf(namebuf, "/dev/midi%2.2d", devno); SETALARM; fd = open(namebuf, O_RDWR | O_MIDIFLAG); ERR("READ/WRITE");} - if (fd<0) {sprintf(namebuf, "/dev/midi%d", devno); SETALARM; fd = open(namebuf, O_RDWR | O_MIDIFLAG); ERR("READ/WRITE");} - } - if (outdevindex >= 0 && fd >= 0) oss_midioutfd[outdevindex] = fd; - if (devno==1 && fd<0) {strcpy(namebuf,"/dev/midi"); SETALARM; fd = open(namebuf, O_RDONLY | O_MIDIFLAG); ERR("READONLY");} - if (fd < 0) {sprintf(namebuf, "/dev/midi%2.2d", devno); SETALARM; fd = open(namebuf, O_RDONLY | O_MIDIFLAG); ERR("READONLY");} - if (fd < 0) {sprintf(namebuf, "/dev/midi%d", devno); SETALARM; fd = open(namebuf, O_RDONLY | O_MIDIFLAG); ERR("READONLY");} - if (fd >= 0) oss_midiinfd[oss_nmidiin++] = fd; - else post("couldn't open MIDI input device %d", devno); - } - oss_nmidiout = 0; - for (int i=0; i<nmidiout; i++) { - int fd = oss_midioutfd[i]; - char namebuf[80]; - int devno = midioutvec[i]; - if (devno==1 && fd<0) {strcpy(namebuf,"/dev/midi"); SETALARM; fd = open(namebuf, O_WRONLY | O_MIDIFLAG); ERR("WRITEONLY");} - if (fd<0) {sprintf(namebuf,"/dev/midi%2.2d", devno); SETALARM; fd = open(namebuf, O_WRONLY | O_MIDIFLAG); ERR("WRITEONLY");} - if (fd<0) {sprintf(namebuf,"/dev/midi%d", devno); SETALARM; fd = open(namebuf, O_WRONLY | O_MIDIFLAG); ERR("WRITEONLY");} - if (fd >= 0) oss_midioutfd[oss_nmidiout++] = fd; - else post("couldn't open MIDI output device %d", devno); - } - if (oss_nmidiin < nmidiin || oss_nmidiout < nmidiout || sys_verbose) - post("opened %d MIDI input device(s) and %d MIDI output device(s).", oss_nmidiin, oss_nmidiout); - sys_setalarm(0); -} - -#define md_msglen(x) (((x)<0xC0)?2:((x)<0xE0)?1:((x)<0xF0)?2:((x)==0xF2)?2:((x)<0xF4)?1:0) - -void sys_putmidimess(int portno, int a, int b, int c) { - if (portno >= 0 && portno < oss_nmidiout) { - int n=md_msglen(a); /* 0..2 */ - if (n>=0) oss_midiout(oss_midioutfd[portno],a); - if (n>=1) oss_midiout(oss_midioutfd[portno],b); - if (n>=2) oss_midiout(oss_midioutfd[portno],c); - } -} - -void sys_putmidibyte(int portno, int byte) { - if (portno >= 0 && portno < oss_nmidiout) oss_midiout(oss_midioutfd[portno], byte); -} - -#if 0 /* this is the "select" version which doesn't work with OSS driver for emu10k1 (it doesn't implement select.) */ -void sys_poll_midi() { - int throttle = 100; - struct timeval timout; - int did = 1, maxfd = 0; - while (did) { - fd_set readset, writeset, exceptset; - did = 0; - if (throttle-- < 0) break; - timout.tv_sec = 0; - timout.tv_usec = 0; - FD_ZERO(&writeset); - FD_ZERO(&readset); - FD_ZERO(&exceptset); - for (int i=0; i<oss_nmidiin; i++) { - if (oss_midiinfd[i] > maxfd) maxfd = oss_midiinfd[i]; - FD_SET(oss_midiinfd[i], &readset); - } - select(maxfd+1, &readset, &writeset, &exceptset, &timout); - for (int i=0; i<oss_nmidiin; i++) if (FD_ISSET(oss_midiinfd[i], &readset)) { - char c; - int ret = read(oss_midiinfd[i], &c, 1); - if (ret <= 0) error("Midi read error"); - else sys_midibytein(i, (c & 0xff)); - did = 1; - } - } -} -#else -void sys_poll_midi() { - int throttle = 100; - int did = 1; - while (did) { - did = 0; - if (throttle-- < 0) break; - for (int i=0; i<oss_nmidiin; i++) { - char c; - int ret = read(oss_midiinfd[i], &c, 1); - if (ret<0) { - if (errno != EAGAIN) perror("MIDI"); - } else if (ret != 0) { - sys_midibytein(i, c&0xff); - did = 1; - } - } - } -} -#endif - -void sys_close_midi() { - for (int i=0; i<oss_nmidiin ; i++) close(oss_midiinfd [i]); - for (int i=0; i<oss_nmidiout; i++) close(oss_midioutfd[i]); - oss_nmidiin = oss_nmidiout = 0; -} - -#define NSEARCH 10 -static int oss_nmidiindevs, oss_nmidioutdevs, oss_initted; - -void midi_oss_init() { - if (oss_initted) return; - oss_initted = 1; - for (int i=0; i<NSEARCH; i++) { - int fd; - char namebuf[80]; - oss_nmidiindevs = i; - if (i == 0) {fd = open("/dev/midi", O_RDONLY|O_NDELAY); if (fd>=0) {close(fd); continue;}} - sprintf(namebuf, "/dev/midi%2.2d", i); fd = open(namebuf, O_RDONLY|O_NDELAY); if (fd>=0) {close(fd); continue;} - sprintf(namebuf, "/dev/midi%d", i); fd = open(namebuf, O_RDONLY|O_NDELAY); if (fd>=0) {close(fd); continue;} - break; - } - for (int i=0; i<NSEARCH; i++) { - int fd; - char namebuf[80]; - oss_nmidioutdevs = i; - if (i == 0) {fd = open("/dev/midi", O_WRONLY|O_NDELAY); if (fd>=0) {close(fd); continue;}} - sprintf(namebuf, "/dev/midi%2.2d", i); fd = open(namebuf, O_WRONLY|O_NDELAY); if (fd>=0) {close(fd); continue;} - sprintf(namebuf, "/dev/midi%d", i); fd = open(namebuf, O_WRONLY|O_NDELAY); if (fd>=0) {close(fd); continue;} - break; - } -} - -void midi_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize) { - int ndev; - ndev = min(maxndev, oss_nmidiindevs); - for (int i=0; i<ndev; i++) sprintf( indevlist + i*devdescsize, "OSS MIDI device #%d", i+1); - *nindevs = ndev; - ndev = min(maxndev,oss_nmidioutdevs); - for (int i=0; i<ndev; i++) sprintf(outdevlist + i*devdescsize, "OSS MIDI device #%d", i+1); - *noutdevs = ndev; -} diff --git a/desiredata/src/s_midi_pm.c b/desiredata/src/s_midi_pm.c deleted file mode 100644 index 19b17a65..00000000 --- a/desiredata/src/s_midi_pm.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler, -* Winfried Ritsch, Karl MacMillan, and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - - this file calls portmidi to do MIDI I/O for MSW and Mac OSX. - applied sysexin/midiin patch by Nathaniel Dose, july 2007. - -*/ - - -#include "desire.h" -#include <stdio.h> -#ifdef UNISTD -#include <unistd.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <portmidi.h> -#include <porttime.h> - -static PmStream *mac_midiindevlist[MAXMIDIINDEV]; -static PmStream *mac_midioutdevlist[MAXMIDIOUTDEV]; -static int mac_nmidiindev; -static int mac_nmidioutdev; - -void sys_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { - PmError err; - Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */ - mac_nmidiindev = 0; - for (int i=0; i<nmidiin; i++) { - int found = 0,count = Pm_CountDevices(); - for (int j=0, devno=0; j<count && !found; j++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(j); - if (info->input) { - if (devno == midiinvec[i]) { - err = Pm_OpenInput(&mac_midiindevlist[mac_nmidiindev],j,NULL,100,NULL,NULL); - if (err != pmNoError) post("could not open midi input %d (%s): %s", j, info->name, Pm_GetErrorText(err)); - else {mac_nmidiindev++; if (sys_verbose) post("Midi Input (%s) opened.", info->name);} - found = 1; - } - devno++; - } - } - if (!found) post("could not find midi device %d",midiinvec[i]); - } - mac_nmidioutdev = 0; - for (int i=0; i<nmidiout; i++) { - int found = 0,count = Pm_CountDevices(); - for (int j=0, devno=0; j<count && !found; j++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(j); - if (info->output) { - if (devno == midioutvec[i]) { - err = Pm_OpenOutput(&mac_midioutdevlist[mac_nmidioutdev],j,NULL,0,NULL,NULL,0); - if (err != pmNoError) post("could not open midi output %d (%s): %s",j,info->name,Pm_GetErrorText(err)); - else {mac_nmidioutdev++; if (sys_verbose) post("Midi Output (%s) opened.",info->name);} - found = 1; - } - devno++; - } - } - if (!found) post("could not find midi device %d",midioutvec[i]); - } -} - -void sys_close_midi () { - for (int i=0; i< mac_nmidiindev; i++) Pm_Close(mac_midiindevlist[i]); - mac_nmidiindev = 0; - for (int i=0; i<mac_nmidioutdev; i++) Pm_Close(mac_midioutdevlist[i]); - mac_nmidioutdev = 0; -} - -void sys_putmidimess(int portno, int a, int b, int c) { - PmEvent buffer; - /* post("put 1 msg %d %d", portno, mac_nmidioutdev); */ - if (portno >= 0 && portno < mac_nmidioutdev) { - buffer.message = Pm_Message(a, b, c); - buffer.timestamp = 0; - /* post("put msg"); */ - Pm_Write(mac_midioutdevlist[portno], &buffer, 1); - } -} - -static void writemidi4(PortMidiStream* stream, int a, int b, int c, int d) { - PmEvent buffer; - buffer.timestamp = 0; - buffer.message = ((a & 0xff) | ((b & 0xff) << 8) | ((c & 0xff) << 16) | ((d & 0xff) << 24)); - Pm_Write(stream, &buffer, 1); -} - -void sys_putmidibyte(int portno, int byte) { - /* try to parse the bytes into MIDI messages so they can fit into PortMidi buffers. */ - static int mess[4]; - static int nbytes = 0, sysex = 0, i; - if (byte >= 0xf8) /* MIDI real time */ - writemidi4(mac_midioutdevlist[portno], byte, 0, 0, 0); - else if (byte == 0xf0) { - mess[0] = 0xf0; - nbytes = 1; - sysex = 1; - } else if (byte == 0xf7) { - mess[nbytes] = byte; - for (i = nbytes+1; i<4; i++) mess[i] = 0; - writemidi4(mac_midioutdevlist[portno], mess[0], mess[1], mess[2], mess[3]); - sysex = 0; - nbytes = 0; - } else if (byte >= 0x80) { - sysex = 0; - if (byte == 0xf4 || byte == 0xf5 || byte == 0xf6) { - writemidi4(mac_midioutdevlist[portno], byte, 0, 0, 0); - nbytes = 0; - } else { - mess[0] = byte; - nbytes = 1; - } - } else if (sysex) { - mess[nbytes] = byte; - nbytes++; - if (nbytes == 4) { - writemidi4(mac_midioutdevlist[portno], mess[0], mess[1], mess[2], mess[3]); - nbytes = 0; - } - } else if (nbytes) { - int status = mess[0]; - if (status < 0xf0) status &= 0xf0; - /* 2 byte messages: */ - if (status == 0xc0 || status == 0xd0 || status == 0xf1 || status == 0xf3) { - writemidi4(mac_midioutdevlist[portno], mess[0], byte, 0, 0); - nbytes = (status < 0xf0 ? 1 : 0); - } else { - if (nbytes == 1) { - mess[1] = byte; - nbytes = 2; - } else { - writemidi4(mac_midioutdevlist[portno], - mess[0], mess[1], byte, 0); - nbytes = (status < 0xf0 ? 1 : 0); - } - } - } -} - -/* this is non-zero if we are in the middle of transmitting sysex */ -int nd_sysex_mode=0; - -/* send in 4 bytes of sysex data. if one of the bytes is 0xF7 (sysex end) stop and unset nd_sysex_mode */ -void nd_sysex_inword(int midiindev, int status, int data1, int data2, int data3) { - if (nd_sysex_mode) {sys_midibytein(midiindev, status); if (status == 0xF7) nd_sysex_mode = 0;} - if (nd_sysex_mode) {sys_midibytein(midiindev, data1); if (data1 == 0xF7) nd_sysex_mode = 0;} - if (nd_sysex_mode) {sys_midibytein(midiindev, data2); if (data2 == 0xF7) nd_sysex_mode = 0;} - if (nd_sysex_mode) {sys_midibytein(midiindev, data3); if (data3 == 0xF7) nd_sysex_mode = 0;} -} - -void sys_poll_midi() { - PmEvent buffer; - for (int i=0; i<mac_nmidiindev; i++) { - int nmess = Pm_Read(mac_midiindevlist[i], &buffer, 1); - if (nmess > 0) { - PmMessage msg = buffer.message; - int status = Pm_MessageStatus(msg); - if(status == 0xf0 || !(status&0x80)) { - /* sysex header or data */ - for(int j=0; j<4; ++j,msg >>= 8) { - int data = msg&0xff; - sys_midibytein(i, data); - if(data == 0xf7) break; /* sysex end */ - } - } else { - int data1 = Pm_MessageData1(msg); - int data2 = Pm_MessageData2(msg); - /* non-sysex */ - sys_midibytein(i, status); - switch(status>>4) { - case 0x8: /* note off */ - case 0x9: /* note on */ - case 0xa: /* poly pressure */ - case 0xb: /* control change */ - case 0xe: /* pitch bend */ - sys_midibytein(i,data1); - sys_midibytein(i,data2); - break; - case 0xc: /* program change */ - case 0xd: /* channel pressure */ - sys_midibytein(i,data1); - break; - case 0xf: /* system common/realtime messages */ - switch(status) { - case 0xf1: /* time code */ - case 0xf3: /* song select */ - case 0xf6: /* tune request */ - sys_midibytein(i,data1); - break; - case 0xf2: /* song position pointer */ - sys_midibytein(i,data1); - sys_midibytein(i,data2); - break; - case 0xf7: // from Nathaniel; don't know whether it'll work in this context. - nd_sysex_mode=1; - nd_sysex_inword(i,status,data1,data2,((msg>>24)&0xFF)); - break; - default: // from Nathaniel too. - if (nd_sysex_mode) nd_sysex_inword(i,status,data1,data2,((msg>>24)&0xFF)); - break; - } - } - } - } - } -} - -#if 0 -/* lifted from pa_devs.c in portaudio */ -void sys_listmididevs() { - for (int i=0; i<Pm_CountDevices(); i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - printf("%d: %s, %s", i, info->interf, info->name); - if (info->input) printf(" (input)"); - if (info->output) printf(" (output)"); - printf("\n"); - } -} -#endif - -void midi_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize) { - int nindev=0, noutdev=0; - for (int i=0; i<Pm_CountDevices(); i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - /* post("%d: %s, %s (%d,%d)", i, info->interf, info->name,info->input, info->output); */ - if (info->input && nindev < maxndev) {strcpy(indevlist + nindev * devdescsize, info->name); nindev++;} - if (info->output && noutdev < maxndev) {strcpy(outdevlist + noutdev * devdescsize, info->name); noutdev++;} - } - *nindevs = nindev; - *noutdevs = noutdev; -} diff --git a/desiredata/src/s_path.c b/desiredata/src/s_path.c deleted file mode 100644 index 1354e607..00000000 --- a/desiredata/src/s_path.c +++ /dev/null @@ -1,344 +0,0 @@ -/* Copyright (c) 1999 Guenter Geiger and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* This file implements the loader for linux, which includes a little bit of path handling. - * Generalized by MSP to provide an open_via_path function and lists of files for all purposes. */ -/* #define DEBUG(x) x */ -#define DEBUG(x) - -#include <stdlib.h> -#ifdef UNISTD -#include <unistd.h> -#include <sys/stat.h> -#endif -#ifdef MSW -#include <io.h> -#endif - -#include <string.h> -#include "desire.h" -#include <stdio.h> -#include <fcntl.h> -#include <ctype.h> -#include <vector> - -extern t_namelist *sys_externlist; -t_namelist *sys_searchpath; -t_namelist *sys_helppath; - -/* change '/' characters to the system's native file separator */ -void sys_bashfilename(const char *from, char *to) { - char c; - while ((c = *from++)) { -#ifdef MSW - if (c == '/') c = '\\'; -#endif - *to++ = c; - } - *to = 0; -} - -/* change the system's native file separator to '/' characters */ -void sys_unbashfilename(const char *from, char *to) { - char c; - while ((c = *from++)) { -#ifdef MSW - if (c == '\\') c = '/'; -#endif - *to++ = c; - } - *to = 0; -} - -/******************* Utility functions used below ******************/ - -/* copy until delimiter and return position after delimiter in string */ -/* if it was the last substring, return NULL */ - -static const char *strtokcpy(char *&to, const char *from, int delim) { - int size = 0; - while (from[size] != (char)delim && from[size] != '\0') size++; - to = (char *)malloc(size+1); - strncpy(to,from,size); - to[size] = '\0'; - if (from[size] == '\0') return NULL; - return size ? from+size+1 : 0; -} - -/* add a single item to a namelist. If "allowdup" is true, duplicates -may be added; othewise they're dropped. */ -t_namelist *namelist_append(t_namelist *listwas, const char *s, int allowdup) { - t_namelist *nl, *nl2 = (t_namelist *)getbytes(sizeof(*nl)); - nl2->nl_next = 0; - nl2->nl_string = strdup(s); - sys_unbashfilename(nl2->nl_string, nl2->nl_string); - if (!listwas) return nl2; - for (nl = listwas; ;) { - if (!allowdup && !strcmp(nl->nl_string, s)) return listwas; - if (!nl->nl_next) break; - nl = nl->nl_next; - } - nl->nl_next = nl2; - return listwas; -} - -/* add a colon-separated list of names to a namelist */ - -#ifdef MSW -#define SEPARATOR ';' /* in MSW the natural separator is semicolon instead */ -#else -#define SEPARATOR ':' -#endif - -t_namelist *namelist_append_files(t_namelist *listwas, const char *s) { - const char *npos = s; - t_namelist *nl = listwas; - do { - char *temp; - npos = strtokcpy(temp, npos, SEPARATOR); - if (!*temp) continue; - nl = namelist_append(nl, temp, 0); - free(temp); - } while (npos); - return nl; -} - -void namelist_free(t_namelist *listwas) { - t_namelist *nl2; - for (t_namelist *nl = listwas; nl; nl = nl2) { - nl2 = nl->nl_next; - free(nl->nl_string); - free(nl); - } -} - -char *namelist_get(t_namelist *namelist, int n) { - int i=0; - for (t_namelist *nl = namelist; i < n && nl; nl = nl->nl_next) {if (i==n) return nl->nl_string; else i++;} - return 0; -} - -static t_namelist *pd_extrapath; - -int sys_usestdpath = 1; - -void sys_setextrapath(const char *p) { - namelist_free(pd_extrapath); - pd_extrapath = namelist_append(0, p, 0); -} - -#ifdef MSW -#define MSWOPENFLAG(bin) (bin ? _O_BINARY : _O_TEXT) -#else -#define MSWOPENFLAG(bin) 0 -#endif - -/* try to open a file in the directory "dir", named "name""ext", for reading. "Name" may have slashes. - The directory is copied to "dirresult" which must be at least "size" bytes. "nameresult" is set - to point to the filename (copied elsewhere into the same buffer). The "bin" flag requests opening - for binary (which only makes a difference on Windows). */ -int sys_trytoopenone(const char *dir, const char *name, const char* ext, char **dirresult, char **nameresult, int bin) { - bool needslash = (*dir && dir[strlen(dir)-1] != '/'); - asprintf(dirresult,"%s%s%s%s", dir, needslash ? "/" : "", name, ext); - sys_bashfilename(*dirresult, *dirresult); - DEBUG(post("looking for %s",*dirresult)); - /* see if we can open the file for reading */ - int fd = open(*dirresult,O_RDONLY | MSWOPENFLAG(bin)); - if (fd<0) { - if (sys_verbose) post("tried %s and failed", *dirresult); - return -1; - } -#ifdef UNISTD /* in unix, further check that it's not a directory */ - struct stat statbuf; - int ok = (fstat(fd, &statbuf) >= 0) && !S_ISDIR(statbuf.st_mode); - if (!ok) { - if (sys_verbose) post("tried %s; stat failed or directory", *dirresult); - close (fd); - return -1; - } -#endif - if (sys_verbose) post("tried %s and succeeded", *dirresult); - sys_unbashfilename(*dirresult, *dirresult); - char *slash = strrchr(*dirresult, '/'); - if (slash) { - *slash = 0; - *nameresult = slash + 1; - } else *nameresult = *dirresult; - return fd; -} - -/* check if we were given an absolute pathname, if so try to open it and return 1 to signal the caller to cancel any path searches */ -int sys_open_absolute(const char *name, const char* ext, char **dirresult, char **nameresult, int bin, int *fdp) { - if (name[0] == '/' -#ifdef MSW - || (name[1] == ':' && name[2] == '/') -#endif - ) { - int dirlen = strrchr(name, '/') - name; - char *dirbuf = new char[dirlen+1]; - *fdp = sys_trytoopenone(name, name+dirlen+1, ext, dirresult, nameresult, bin); - delete[] dirbuf; - return 1; - } else return 0; -} - -/* search for a file in a specified directory, then along the globally -defined search path, using ext as filename extension. The -fd is returned, the directory ends up in the "dirresult" which must be at -least "size" bytes. "nameresult" is set to point to the filename, which -ends up in the same buffer as dirresult. Exception: -if the 'name' starts with a slash or a letter, colon, and slash in MSW, -there is no search and instead we just try to open the file literally. */ - -/* see also canvas_openfile() which, in addition, searches down the -canvas-specific path. */ - -static int do_open_via_path( -const char *dir, const char *name, const char *ext, char **dirresult, char **nameresult, int bin, t_namelist *searchpath) { - int fd = -1; - /* first check if "name" is absolute (and if so, try to open) */ - if (sys_open_absolute(name, ext, dirresult, nameresult, bin, &fd)) return fd; - /* otherwise "name" is relative; try the directory "dir" first. */ - if ((fd = sys_trytoopenone(dir, name, ext, dirresult, nameresult, bin)) >= 0) return fd; - /* next go through the search path */ - for (t_namelist *nl=searchpath; nl; nl=nl->nl_next) - if ((fd = sys_trytoopenone(nl->nl_string, name, ext, dirresult, nameresult, bin)) >= 0) return fd; - /* next look in "extra" */ - if (sys_usestdpath && (fd = sys_trytoopenone(pd_extrapath->nl_string, name, ext, dirresult, nameresult, bin)) >= 0) - return fd; - *dirresult = 0; - *nameresult = *dirresult; - return -1; -} - -extern "C" int open_via_path2(const char *dir, const char *name, const char *ext, char **dirresult, char **nameresult, int bin) { - return do_open_via_path(dir, name, ext, dirresult, nameresult, bin, sys_searchpath); -} - -/* open via path, using the global search path. */ -extern "C" int open_via_path(const char *dir, const char *name, const char *ext, -char *dirresult, char **nameresult, unsigned int size, int bin) { - char *dirr; - int r = do_open_via_path(dir, name, ext, &dirr, nameresult, bin, sys_searchpath); - if (dirr) {strncpy(dirresult,dirr,size); dirresult[size-1]=0; free(dirr);} - return r; -} - -/* Open a help file using the help search path. We expect the ".pd" suffix here, - even though we have to tear it back off for one of the search attempts. */ -extern "C" void open_via_helppath(const char *name, const char *dir) { - char *realname=0, *dirbuf, *basename; - int suffixed = strlen(name) > 3 && !strcmp(name+strlen(name)-3, ".pd"); - asprintf(&realname,"%.*s-help.pd",strlen(name)-3*suffixed,name); - int fd; - if ((fd = do_open_via_path(dir,realname,"",&dirbuf,&basename,0,sys_helppath))>=0) goto gotone; - free(realname); - asprintf(&realname,"help-%s",name); - if ((fd = do_open_via_path(dir,realname,"",&dirbuf,&basename,0,sys_helppath))>=0) goto gotone; - free(realname); - if ((fd = do_open_via_path(dir, name,"",&dirbuf,&basename,0,sys_helppath))>=0) goto gotone; - post("sorry, couldn't find help patch for \"%s\"", name); - return; -gotone: - close(fd); if (realname) free(realname); - glob_evalfile(0, gensym((char*)basename), gensym(dirbuf)); -} - -extern "C" int sys_argparse(int argc, char **argv); - -#define NUMARGS 1000 -#define foreach(ITER,COLL) for(typeof(COLL.begin()) ITER = COLL.begin(); ITER != (COLL).end(); ITER++) - -static int sys_argparse(std::vector<char *> args) { - size_t argc = args.size(); - char **argv = new char *[argc]; - for (size_t i=0; i<argc; i++) argv[i] = args[i]; - int r = sys_argparse(argc,argv); - delete[] argv; - return r; -} - -extern "C" int sys_parsercfile(char *filename) { - std::vector<char*> argv; - char buf[1000]; - char c[MAXPDSTRING]; - int retval = 1; /* that's what we will return at the end; for now, let's think it'll be an error */ - /* parse a startup file */ - FILE* file = fopen(filename, "r"); - if (!file) return 1; - post("reading startup file: %s", filename); - /* tb originally introduced comments in pdrc file. desire.tk doesn't support them. */ - while ((fgets(c,MAXPDSTRING,file)) != 0) { - if (c[strlen(c)-1] !='\n') { - error("startup file contains a line that's too long"); - while(fgetc(file) != '\n') {} - } - if (c[0] != '#') { - long j=0; - long n; - while (sscanf(c+j,"%999s%ln",buf,&n) != EOF) {argv.push_back(strdup(buf)); j+=n;} - } - } - /* parse the options */ - fclose(file); - if (sys_verbose) { - if (argv.size()) { - post("startup args from RC file:"); - foreach(a,argv) post("%s",*a); - } else post("no RC file arguments found"); - } -// if (sys_argparse(argv.size(),argv.data())) { - if (sys_argparse(argv)) { - post("error parsing RC arguments"); - goto cleanup; - } - retval=0; /* we made it without an error */ - cleanup: /* prevent memleak */ - foreach(a,argv) free(*a); - return retval; -} - -#define STARTUPNAME ".pdrc" -extern "C" int sys_rcfile () { - char *fname, *home = getenv("HOME"); - asprintf(&fname,"%s/%s",home? home : ".",STARTUPNAME); - int r = sys_parsercfile(fname); - free(fname); - return r; -} - -void sys_doflags() { - int beginstring = 0, state = 0, len = strlen(sys_flags->s_name); - int rcargc = 0; - char *rcargv[MAXPDSTRING]; - if (len > MAXPDSTRING) {post("flags: %s: too long", sys_flags->s_name); return;} - for (int i=0; i<len+1; i++) { - int c = sys_flags->s_name[i]; - if (state == 0) { - if (c && !isspace(c)) { - beginstring = i; - state = 1; - } - } else { - if (!c || isspace(c)) { - char *foo = (char *)malloc(i - beginstring + 1); - if (!foo) return; - strncpy(foo, sys_flags->s_name + beginstring, i - beginstring); - foo[i - beginstring] = 0; - rcargv[rcargc] = foo; - rcargc++; - if (rcargc >= MAXPDSTRING) break; - state = 0; - } - } - } - if (sys_argparse(rcargc, rcargv)) post("error parsing startup arguments"); -} - -extern "C" void glob_update_path () { - t_namelist *nl; - sys_vgui("global pd_path; set pd_path {"); - for (nl=sys_searchpath; nl; nl=nl->nl_next) sys_vgui("%s ",nl->nl_string); - sys_vgui("}\n"); -} diff --git a/desiredata/src/s_watchdog.c b/desiredata/src/s_watchdog.c deleted file mode 100644 index 49bffbb6..00000000 --- a/desiredata/src/s_watchdog.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 1997-2000 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* This file is compiled into the separate program, "pd-watchdog," which -tries to prevent Pd from locking up the processor if it's at realtime -priority. Linux only. Invoked from s_inter.c. */ - -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> -#include <signal.h> -#include <stdio.h> - -int main(int argc, char **argv) { - int happy = 1; - while (1) { - struct timeval timout; - fd_set readset; - if (happy) {timout.tv_sec = 5; timout.tv_usec = 0;} - else {timout.tv_sec = 2; timout.tv_usec = 0;} - FD_ZERO(&readset); - FD_SET(0, &readset); - select(1, &readset, 0, 0, &timout); - if (FD_ISSET(0, &readset)) { - char buf[100]; - happy = 1; - if (read(0, &buf, 100) <= 0) return 0; - continue; - } - happy = 0; - kill(getppid(), SIGHUP); - fprintf(stderr, "watchdog: signaling pd...\n"); - } -} diff --git a/desiredata/src/tests/abstr-test.pd b/desiredata/src/tests/abstr-test.pd deleted file mode 100644 index dce22c6b..00000000 --- a/desiredata/src/tests/abstr-test.pd +++ /dev/null @@ -1,3 +0,0 @@ -#N canvas 0 0 450 300 10; -#X obj 30 36 abstr; -#X obj 101 36 abstr2; diff --git a/desiredata/src/tests/abstr.pd b/desiredata/src/tests/abstr.pd deleted file mode 100644 index 91250635..00000000 --- a/desiredata/src/tests/abstr.pd +++ /dev/null @@ -1,11 +0,0 @@ -#N canvas 0 0 450 300 10; -#X obj 77 5 inlet; -#X obj 189 6 inlet; -#X obj 171 256 outlet; -#X obj 133 6 inlet; -#X obj 245 7 inlet; -#X connect 0 0 2 0; -#X connect 1 0 2 0; -#X connect 3 0 2 0; -#X connect 4 0 2 0; -#X coords 0 0 1 1 0 0 0; diff --git a/desiredata/src/tests/abstr2.pd b/desiredata/src/tests/abstr2.pd deleted file mode 100644 index c3a9639c..00000000 --- a/desiredata/src/tests/abstr2.pd +++ /dev/null @@ -1,15 +0,0 @@ -#N canvas 0 0 450 300 10; -#X obj 19 29 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 39 29 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X obj 59 29 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 256; -#X obj 19 52 vsl 15 128 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X obj 19 11 hsl 128 15 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X obj 136 29 vradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 --1 0; -#X obj 38 156 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 --1 6; diff --git a/desiredata/src/tests/all_guis_and_gop.pd b/desiredata/src/tests/all_guis_and_gop.pd deleted file mode 100644 index 2be10062..00000000 --- a/desiredata/src/tests/all_guis_and_gop.pd +++ /dev/null @@ -1,116 +0,0 @@ -#N canvas 339 27 590 690 10; -#X obj 98 29 +; -#X floatatom 99 83 5 0 0 0 - - -; -#X symbolatom 99 108 10 0 0 0 - - -; -#X obj 158 27 bng 42 250 50 0 empty empty button-label 50 8 0 8 -258699 --1 -1; -#X obj 158 87 tgl 15 0 empty empty hello? 20 8 0 9 -24198 -1 -1 0 1 -; -#X obj 227 140 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 0 256; -#X obj 5 13 vsl 25 150 0 127 0 0 empty empty vslider-hello -2 -6 0 -9 -241291 -1 -1 0 0; -#X obj 43 201 hsl 100 10 0 127 0 0 empty empty hello-hslider 10 6 0 -9 -262144 -1 -258699 0 0; -#X obj 67 159 hradio 15 1 0 8 empty empty hello-hradio 0 -6 0 9 -261681 --1 -1 0; -#X obj 68 24 vradio 15 1 0 8 empty empty hello-vradio 0 -6 0 9 -262144 --1 -1 0; -#X obj 435 73 vu 15 120 empty vumeter-label -1 -8 0 8 -166441 -1 1 -0; -#X obj 306 9 cnv 15 100 60 empty empty empty 20 12 0 14 -233017 -66577 -0; -#N canvas 0 0 450 300 graph2 0; -#X array array1 100 float 1; -#A 0 -0.0571427 -0.0428571 -0.0857141 -0.171428 -0.185714 -0.199999 --0.206428 -0.212856 -0.219285 -0.225714 -0.232142 -0.238571 -0.244999 --0.251428 -0.257856 -0.264285 -0.270713 -0.277142 -0.28357 -0.289999 --0.296427 -0.302856 -0.309285 -0.315713 -0.322142 -0.32857 -0.331427 --0.334285 -0.337142 -0.339999 -0.342856 -0.345713 -0.34857 -0.351427 --0.354284 -0.357141 -0.359999 -0.362856 -0.365713 -0.35857 -0.351427 --0.329999 -0.30857 -0.279999 -0.25619 -0.23238 -0.208571 -0.18 0.162856 -0.305712 0.419998 0.448569 0.491426 0.57714 0.591425 0.605711 0.305712 -0.14857 0.105713 -0.00857189 -0.122857 -0.237142 -0.322856 -0.40857 --0.479998 -0.50857 -0.565712 -0.594283 -0.608569 -0.608569 -0.608569 --0.594283 -0.565712 -0.546664 -0.527617 -0.494284 -0.460951 0.0342851 --0.0514288 -0.165714 -0.201428 -0.251428 -0.265714 -0.294285 -0.337142 --0.337142 -0.365713 -0.365713 -0.40857 -0.437141 -0.451427 -0.451427 --0.451427 -0.479998 -0.494284 -0.477141 -0.482855 -0.48857 -0.494284 --0.499998; -#X coords 0 1 99 -1 200 140 1; -#X restore 199 178 graph; -#X floatatom 432 22 5 0 0 0 - - -; -#X floatatom 479 23 5 -99 42 2 floatatom-label - -; -#X obj 225 74 nbx 5 14 -1e+37 1e+37 0 0 empty empty numbox2-label 60 -8 0 9 -260818 -62784 -1 0 256; -#X floatatom 237 48 5 0 0 0 - - -; -#X msg 98 57; -#N canvas 0 0 450 300 foo 0; -#X obj 148 99 +; -#X floatatom 149 153 5 0 0 0 - - -; -#X symbolatom 149 178 10 0 0 0 - - -; -#X obj 208 97 bng 42 250 50 0 empty empty button-label 50 8 0 8 -258699 --1 -1; -#X obj 208 157 tgl 15 0 empty empty hello? 20 8 0 9 -24198 -1 -1 0 -1; -#X obj 277 210 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 --262144 -1 -1 0 256; -#X obj 55 83 vsl 25 150 0 127 0 0 empty empty vslider-hello -2 -6 0 -9 -241291 -1 -1 0 0; -#X obj 93 271 hsl 100 10 0 127 0 0 empty empty hello-hslider 10 6 0 -9 -262144 -1 -258699 0 0; -#X obj 117 229 hradio 15 1 0 8 empty empty hello-hradio 0 -6 0 9 -261681 --1 -1 0; -#X obj 118 94 vradio 15 1 0 8 empty empty hello-vradio 0 -6 0 9 -262144 --1 -1 0; -#X obj 485 143 vu 15 120 empty vumeter-label -1 -8 0 8 -166441 -1 1 -0; -#X obj 356 79 cnv 15 100 60 empty empty empty 20 12 0 14 -233017 -66577 -0; -#N canvas 0 0 450 300 graph2 0; -#X array array1 100 float 1; -#A 0 -0.0571427 -0.0428571 -0.0857141 -0.171428 -0.185714 -0.199999 --0.206428 -0.212856 -0.219285 -0.225714 -0.232142 -0.238571 -0.244999 --0.251428 -0.257856 -0.264285 -0.270713 -0.277142 -0.28357 -0.289999 --0.296427 -0.302856 -0.309285 -0.315713 -0.322142 -0.32857 -0.331427 --0.334285 -0.337142 -0.339999 -0.342856 -0.345713 -0.34857 -0.351427 --0.354284 -0.357141 -0.359999 -0.362856 -0.365713 -0.35857 -0.351427 --0.329999 -0.30857 -0.279999 -0.25619 -0.23238 -0.208571 -0.18 0.162856 -0.305712 0.419998 0.448569 0.491426 0.57714 0.591425 0.605711 0.305712 -0.14857 0.105713 -0.00857189 -0.122857 -0.237142 -0.322856 -0.40857 --0.479998 -0.50857 -0.565712 -0.594283 -0.608569 -0.608569 -0.608569 --0.594283 -0.565712 -0.546664 -0.527617 -0.494284 -0.460951 0.0342851 --0.0514288 -0.165714 -0.201428 -0.251428 -0.265714 -0.294285 -0.337142 --0.337142 -0.365713 -0.365713 -0.40857 -0.437141 -0.451427 -0.451427 --0.451427 -0.479998 -0.494284 -0.477141 -0.482855 -0.48857 -0.494284 --0.499998; -#X coords 0 1 99 -1 200 140 1; -#X restore 249 248 graph; -#X floatatom 482 92 5 0 0 0 - - -; -#X floatatom 529 93 5 -99 42 2 floatatom-label - -; -#X obj 275 144 nbx 5 14 -1e+37 1e+37 0 0 empty empty numbox2-label -60 8 0 9 -260818 -62784 -1 0 256; -#X floatatom 287 118 5 0 0 0 - - -; -#X msg 148 127; -#X obj 15 17 bng 15 250 50 0 empty empty i_shouldn't_be_visible_in_parent -0 -6 0 9 -262144 -1 -1; -#X connect 3 0 4 0; -#X connect 4 0 5 0; -#X connect 6 0 7 0; -#X connect 8 0 7 0; -#X connect 9 0 8 0; -#X connect 13 0 10 0; -#X connect 14 0 10 1; -#X connect 15 0 5 0; -#X connect 16 0 15 0; -#X coords 0 -1 1 1 400 300 1 50 50; -#X restore 99 336 pd foo; -#X connect 3 0 4 0; -#X connect 4 0 5 0; -#X connect 6 0 7 0; -#X connect 8 0 7 0; -#X connect 9 0 8 0; -#X connect 13 0 10 0; -#X connect 14 0 10 1; -#X connect 15 0 5 0; -#X connect 16 0 15 0; diff --git a/desiredata/src/tests/all_guis_and_gop.pd.gif b/desiredata/src/tests/all_guis_and_gop.pd.gif Binary files differdeleted file mode 100644 index 288c6902..00000000 --- a/desiredata/src/tests/all_guis_and_gop.pd.gif +++ /dev/null diff --git a/desiredata/src/tests/bof.pd b/desiredata/src/tests/bof.pd deleted file mode 100644 index 706950cf..00000000 --- a/desiredata/src/tests/bof.pd +++ /dev/null @@ -1,27 +0,0 @@ -#N canvas 0 0 675 450 10; -#X obj 23 28 +; -#X obj 35 206 adc~; -#X obj 99 124 -; -#X obj 142 214 * 42; -#X msg 130 47 foo; -#X msg 280 91 0; -#X msg 280 70 set \$1; -#X obj 280 46 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 0 -0; -#X obj 228 54 vsl 15 128 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 0 0; -#X obj 254 64 vradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 --1 0; -#X floatatom 381 79 5 0 0 0 - - -; -#X obj 372 109 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 8 --262144 -1 -1 0 0 256; -#X symbolatom 352 42 10 0 0 0 - - -; -#X obj -43 -41 lop~; -#X text 11 3 there's a [lop~] top left \, but negative coords are buggy. -; -#X connect 0 0 1 0; -#X connect 0 0 2 1; -#X connect 2 0 3 0; -#X connect 4 0 2 0; -#X connect 6 0 5 0; -#X connect 7 0 6 0; diff --git a/desiredata/src/tests/chun.pd b/desiredata/src/tests/chun.pd deleted file mode 100644 index 0ee7d48a..00000000 --- a/desiredata/src/tests/chun.pd +++ /dev/null @@ -1,36 +0,0 @@ -#N canvas 385 550 450 300 10; -#X obj 151 212 dac~; -#X obj 132 139 *~ 0.02; -#X msg 231 120 0; -#X obj 252 95 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 235 154 0.2; -#X obj 274 140 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 45 105 delread~ down; -#X obj 21 26 delread~ up; -#X obj 15 132 *~ 0.8; -#X obj 126 41 osc~ 500; -#X obj 133 11 osc~ 40; -#X obj 225 19 +~ 1; -#X obj 219 46 *~ 500; -#X floatatom 337 69 5 0 0 0 - - -; -#X obj 46 78 delwrite~ down 20; -#X obj 15 156 delwrite~ up 20; -#X text 323 50 tweak me; -#X connect 1 0 0 0; -#X connect 1 0 0 1; -#X connect 2 0 1 1; -#X connect 3 0 2 0; -#X connect 4 0 1 1; -#X connect 5 0 4 0; -#X connect 6 0 8 0; -#X connect 6 0 1 0; -#X connect 7 0 14 0; -#X connect 8 0 15 0; -#X connect 9 0 14 0; -#X connect 10 0 11 0; -#X connect 11 0 12 0; -#X connect 12 0 9 0; -#X connect 13 0 6 0; -#X connect 13 0 7 0; diff --git a/desiredata/src/tests/city.pd b/desiredata/src/tests/city.pd deleted file mode 100644 index 9b30647c..00000000 --- a/desiredata/src/tests/city.pd +++ /dev/null @@ -1,128 +0,0 @@ -#N canvas 0 0 450 300 10; -#X obj 23 20 +; -#X obj 53 20 +; -#X obj 23 50 +; -#X obj 53 50 +; -#X obj 83 20 +; -#X obj 113 20 +; -#X obj 83 50 +; -#X obj 113 50 +; -#X obj 23 80 +; -#X obj 53 80 +; -#X obj 23 110 +; -#X obj 53 110 +; -#X obj 83 80 +; -#X obj 113 80 +; -#X obj 83 110 +; -#X obj 113 110 +; -#X obj 143 20 +; -#X obj 173 20 +; -#X obj 143 50 +; -#X obj 173 50 +; -#X obj 203 20 +; -#X obj 233 20 +; -#X obj 203 50 +; -#X obj 233 50 +; -#X obj 143 80 +; -#X obj 173 80 +; -#X obj 143 110 +; -#X obj 173 110 +; -#X obj 203 80 +; -#X obj 233 80 +; -#X obj 203 110 +; -#X obj 233 110 +; -#X obj 23 140 +; -#X obj 53 140 +; -#X obj 23 170 +; -#X obj 53 170 +; -#X obj 83 140 +; -#X obj 113 140 +; -#X obj 83 170 +; -#X obj 113 170 +; -#X obj 23 200 +; -#X obj 53 200 +; -#X obj 23 230 +; -#X obj 53 230 +; -#X obj 83 200 +; -#X obj 113 200 +; -#X obj 83 230 +; -#X obj 113 230 +; -#X obj 143 140 +; -#X obj 173 140 +; -#X obj 143 170 +; -#X obj 173 170 +; -#X obj 203 140 +; -#X obj 233 140 +; -#X obj 203 170 +; -#X obj 233 170 +; -#X obj 143 200 +; -#X obj 173 200 +; -#X obj 143 230 +; -#X obj 173 230 +; -#X obj 203 200 +; -#X obj 233 200 +; -#X obj 203 230 +; -#X obj 233 230 +; -#X connect 0 0 1 0; -#X connect 0 0 2 0; -#X connect 1 0 4 0; -#X connect 2 0 3 0; -#X connect 2 0 8 0; -#X connect 4 0 5 0; -#X connect 4 0 6 0; -#X connect 5 0 16 0; -#X connect 6 0 7 0; -#X connect 8 0 9 0; -#X connect 8 0 10 0; -#X connect 9 0 12 0; -#X connect 10 0 11 0; -#X connect 10 0 32 0; -#X connect 12 0 13 0; -#X connect 12 0 14 0; -#X connect 14 0 15 0; -#X connect 16 0 17 0; -#X connect 16 0 18 0; -#X connect 17 0 20 0; -#X connect 18 0 19 0; -#X connect 18 0 24 0; -#X connect 20 0 21 0; -#X connect 20 0 22 0; -#X connect 22 0 23 0; -#X connect 24 0 25 0; -#X connect 24 0 26 0; -#X connect 25 0 28 0; -#X connect 26 0 27 0; -#X connect 28 0 29 0; -#X connect 28 0 30 0; -#X connect 30 0 31 0; -#X connect 32 0 33 0; -#X connect 32 0 34 0; -#X connect 33 0 36 0; -#X connect 34 0 35 0; -#X connect 34 0 40 0; -#X connect 36 0 37 0; -#X connect 36 0 38 0; -#X connect 37 0 48 0; -#X connect 38 0 39 0; -#X connect 40 0 41 0; -#X connect 40 0 42 0; -#X connect 41 0 44 0; -#X connect 42 0 43 0; -#X connect 44 0 45 0; -#X connect 44 0 46 0; -#X connect 46 0 47 0; -#X connect 48 0 49 0; -#X connect 48 0 50 0; -#X connect 49 0 52 0; -#X connect 50 0 51 0; -#X connect 50 0 56 0; -#X connect 52 0 53 0; -#X connect 52 0 54 0; -#X connect 54 0 55 0; -#X connect 56 0 57 0; -#X connect 56 0 58 0; -#X connect 57 0 60 0; -#X connect 58 0 59 0; -#X connect 60 0 61 0; -#X connect 60 0 62 0; -#X connect 62 0 63 0; diff --git a/desiredata/src/tests/desire_demo.pd b/desiredata/src/tests/desire_demo.pd deleted file mode 100644 index 07237ef9..00000000 --- a/desiredata/src/tests/desire_demo.pd +++ /dev/null @@ -1,262 +0,0 @@ -#N canvas 426 124 578 817 10; -#X text 39 17 DesireData; -#X text 60 120 Object creation; -#X text 60 200 Wire connection; -#X text 100 140 Auto-completion; -#X text 100 160 Object history; -#X text 100 220 Multi connection; -#X text 100 240 Detach wire; -#X text 60 280 Patch editing; -#X text 100 300 Canvas zoom; -#X text 100 320 Object insertion; -#X text 100 360 Subpatcherize; -#X text 60 500 Keyboard driven control; -#X text 100 520 Keyboard navigation; -#X text 100 540 Key commands; -#X text 100 580 Keyboard Macro; -#X text 60 40 General; -#X text 100 60 Customization; -#X text 100 80 Localization; -#X text 100 380 In/outlet expansion; -#X text 100 400 Fast copy; -#X text 100 420 Grid \, snap to; -#X text 100 440 Pointer sensitivity; -#N canvas 432 483 474 248 example 0; -#X text 100 60 - Canvas \, object colors; -#X text 100 100 - Font selection; -#X text 100 120 - Keyboard shortcuts; -#X text 100 80 - Menu \, button \, scroll \, status bars; -#X restore 280 60 pd example; -#N canvas 334 257 617 645 example 0; -#X text 100 40 French; -#X text 100 80 Catalan; -#X text 100 120 Spanish; -#X text 100 160 German; -#X text 100 200 Norwegian; -#X text 100 240 Portuguese; -#X text 100 280 Italian; -#X text 100 320 Basque; -#X text 100 360 Japanese; -#X text 100 400 Polish; -#X text 100 440 Danish; -#X text 100 480 Chinese; -#X text 100 520 Dutch; -#X text 100 560 Turkish; -#X text 100 600 Russian; -#X text 240 40 Patrice Colet; -#X text 240 80 Nria Verges; -#X text 240 120 Mario Mora \, Ramiro Cosentino; -#X text 240 160 Max Neupert \, Georg Holzmann \, Thomas Grill; -#X text 240 200 Gisle Frysland; -#X text 240 240 Nuno Godinho; -#X text 240 280 Davide Morelli \, Federico Ferri; -#X text 240 320 Ibon Rodriguez Garcia; -#X text 240 360 Kentaro Fukuchi; -#X text 240 400 Michal Seta; -#X text 240 440 Steffen Leve Poulsen; -#X text 240 480 Chun Lee; -#X text 240 520 Tim Vets; -#X text 240 560 Koray Tahiroglu; -#X text 240 600 Ilya Dmitrichenko; -#X restore 280 80 pd example; -#N canvas 357 386 641 323 example 0; -#X text 20 20 Auto completion; -#X text 40 60 By hitting Tab key while typing object name \, a popup -window will appear with the names of possible objects.; -#X text 40 120 One can continue typing to further eliminate proposed -object names; -#X restore 280 140 pd example; -#N canvas 514 542 496 300 example 0; -#X text 20 20 Object history; -#X text 60 40 Object creation history is stored \, so that one can -quickly create objects in the pase by using the Up and Down key; -#X restore 280 160 pd example; -#N canvas 479 532 496 300 example 0; -#X text 20 20 Multiple connections; -#X text 40 40 By holding down the Shift key whilst making the connection -\, one can make multiple connections at once; -#X obj 200 140 +; -#X obj 100 220 +; -#X obj 200 220 +; -#X obj 300 220 +; -#X restore 280 220 pd example; -#N canvas 513 611 496 300 example 0; -#X text 20 20 Detach wire; -#X text 40 40 by holding down the Ctrl key while clicking on a wire -\, one can detatch it and reconnect it elsewhere; -#X obj 200 120 +; -#X obj 200 220 +; -#X obj 300 160 +; -#X connect 2 0 3 0; -#X restore 280 240 pd example; -#N canvas 345 474 485 342 example 0; -#X text 20 20 Canvas zoom; -#X text 40 40 By using (default) Ctrl+ and Ctrl- key \, one can zoom -in/out of a patch for better readibility; -#X obj 100 120 +; -#X obj 100 200 +; -#X obj 200 120 +; -#X obj 200 200 +; -#X connect 2 0 5 0; -#X connect 4 0 3 0; -#X restore 280 300 pd example; -#X text 100 340 Object chaining; -#N canvas 449 514 516 424 example 0; -#X text 20 20 Object insertion; -#X text 40 40 One can insert object into a existing path without breaking -the connection; -#X text 40 80 1 right click on the selected wire \, then select insert -; -#X text 40 120 2 moving desired object into the wire while holding -down ctrl key.; -#X text 40 160 3 (default) Ctrl+i shortcut on selected wire; -#X obj 100 240 +; -#X obj 100 380 +; -#X obj 200 300 +; -#X connect 5 0 6 0; -#X restore 280 320 pd example; -#N canvas 239 402 496 300 example 0; -#X text 20 20 Object chaining; -#X text 40 40 By hitting Ctrl+6 (default) on a selected object \, one -can create a new object directly beneath it and automatically connected -; -#X obj 100 140 +; -#X restore 280 340 pd example; -#N canvas 470 257 517 360 example 0; -#X text 20 20 Subpatcherize; -#X text 40 40 One can select a group of object and encaptulate them -into a subpatch automatically; -#X obj 60 140 +; -#X obj 140 140 +; -#X obj 60 200 +; -#X obj 140 200 +; -#X obj 100 260 +; -#X text 40 100 This feature is experimental; -#X connect 2 0 4 0; -#X connect 3 0 5 0; -#X connect 4 0 6 0; -#X connect 5 0 6 1; -#X restore 280 360 pd example; -#N canvas 670 392 532 419 example 0; -#X text 20 20 In/outlet expansion; -#X text 40 40 This feature allows user to extend the in/outlet of a -selected object without the need to disconnect/reconnect wires; -#X obj 100 140 +; -#X obj 200 140 +; -#X obj 100 260 +; -#X obj 300 140 +; -#X obj 100 380 +; -#X obj 200 380 +; -#X obj 300 380 +; -#X connect 2 0 4 0; -#X connect 3 0 4 0; -#X connect 4 0 6 0; -#X connect 4 0 7 0; -#X connect 4 0 8 0; -#X connect 5 0 4 0; -#X restore 280 380 pd example; -#N canvas 188 196 496 300 example 0; -#X text 20 20 Fast copy; -#X text 40 40 Using left click+ctrl+shift key \, one can copy a selected -region of objects; -#X obj 60 120 +; -#X obj 60 200 +; -#X connect 2 0 3 0; -#X restore 280 400 pd example; -#N canvas 184 310 496 300 example 0; -#X text 20 20 Grid; -#X text 40 40 A background grid can displayed to aid the positioning -of objects. The grid size is configurable. Additionally \, objects -can be snapped to the grid.; -#X restore 280 420 pd example; -#N canvas 408 467 496 300 example 0; -#X text 20 20 Pointer sensitivity; -#X text 40 40 The mouse pointer sensitivity can be dynamically changed -to aid various operations when patching.; -#X obj 60 140 +; -#X obj 200 140 +; -#X obj 60 240 +; -#X obj 200 240 +; -#X restore 280 440 pd example; -#N canvas 366 409 625 453 example 0; -#X text 20 20 Keyboard navigation; -#X text 40 40 This feature aims to eliminate the needs for mouse when -editing a patch; -#X text 40 80 ctrl+arrow keys: navigate; -#X text 40 100 Tab: switch between objects and wires; -#X text 40 120 shift+ctrl+arrow keys: add current object into selection -; -#X obj 331 412 dac~; -#X obj 312 339 *~ 0.02; -#X msg 411 320 0; -#X obj 432 295 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 415 354 0.2; -#X obj 454 300 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 225 305 delread~ down; -#X obj 201 226 delread~ up; -#X obj 195 332 *~ 0.8; -#X obj 306 241 osc~ 500; -#X obj 313 211 osc~ 40; -#X obj 405 219 +~ 1; -#X obj 399 246 *~ 500; -#X floatatom 517 269 5 0 0 0 - - -; -#X obj 226 278 delwrite~ down 20; -#X obj 195 356 delwrite~ up 20; -#X text 503 250 tweak me; -#X text 40 160 shift+ctrl+a: deselect all; -#X connect 6 0 5 0; -#X connect 6 0 5 1; -#X connect 7 0 6 1; -#X connect 8 0 7 0; -#X connect 9 0 6 1; -#X connect 10 0 9 0; -#X connect 11 0 13 0; -#X connect 11 0 6 0; -#X connect 12 0 19 0; -#X connect 13 0 20 0; -#X connect 14 0 19 0; -#X connect 15 0 16 0; -#X connect 16 0 17 0; -#X connect 17 0 14 0; -#X connect 18 0 11 0; -#X connect 18 0 12 0; -#X restore 280 520 pd example; -#N canvas 247 392 496 300 example 0; -#X text 20 20 Key commands; -#X text 40 40 A (emacs style:)) command prompt can be invoked which -give user access to all canvas function.; -#X text 40 100 the prompt supports completion \, as well as history -; -#X text 40 140 Alt+x to active the prompt; -#X text 40 160 Ctrl+g to cancell the prompt; -#X restore 280 540 pd example; -#X text 100 560 Misc functions; -#N canvas 199 234 496 300 example 0; -#X text 20 20 Misc functions; -#X text 40 40 other keyboard related functions includes multiple wire -connections \, object creation \, object selection; -#X restore 280 560 pd example; -#N canvas 407 352 599 423 example 0; -#X text 20 20 Keyboard Macro; -#X text 40 40 User can record a series of keyboard/mouse events as -macro to be reused.; -#X text 40 100 Alt+m to start/stop recording; -#X text 40 120 Ctrl+m to play the last macro; -#X text 40 140 Ctrl+M to copy the macro to clipboard; -#X restore 280 580 pd example; -#X text 100 460 Copy to clipboard; -#N canvas 707 580 496 300 example 0; -#X text 20 20 Copy to clipboard; -#X text 40 40 In desiredata \, object copying (Ctrl+c) will also copy -the patch into the system clipboard.; -#X obj 100 160 +; -#X obj 100 240 +; -#X obj 200 160 +; -#X obj 200 240 +; -#X text 40 100 Inversely \, a .pd file in the clipboard can be poasted -in the patch; -#X connect 2 0 5 0; -#X connect 4 0 3 0; -#X restore 280 460 pd example; diff --git a/desiredata/src/tests/desiredata-presentation-piksel06.pd b/desiredata/src/tests/desiredata-presentation-piksel06.pd deleted file mode 100644 index fee64d2d..00000000 --- a/desiredata/src/tests/desiredata-presentation-piksel06.pd +++ /dev/null @@ -1,26 +0,0 @@ -#N canvas 0 0 640 480 10; -#X text 100 140 Zoomable patches (and def Canvas item); -#X text 100 160 Client-side selection and clipboard; -#X text 100 180 Client-side undo and redo: multiple \, atomic \, labeled -\, history; -#X text 100 200 Class browser and class name completions; -#X text 100 220 Internationalization (the Patching-in-Tongues project) -; -#X text 100 240 Keyboard-based Navigation and Edition; -#X text 100 260 Server Preferences (.pdrc Editor); -#X text 100 280 Client Preferences (.ddrc Editor); -#X text 100 300 Canvas Actions; -#X text 100 320 #V for visual attributes; -#V bg 255 255 0; -#X text 100 340 Dialog autogeneration with def Dialog add; -#X text 100 360 ClientClassTreeDialog; -#X text 100 380 Deconstructors; -#X text 100 400 desire.h; -#X text 100 420 what is happening to desire.c these days; -#X obj 94 31 bng 32 250 50 0 empty empty DesireData-0.39.A 40 15 1 -19 -262088 -1 -1; -#X text 295 270 tab support in all dialogs; -#X obj 0 0 + 242; -#V pretty 1; -#X text 99 440 scaling of selection or complete patch; -#X coords 0 0 1 1 0 0 0; diff --git a/desiredata/src/tests/gop-one.pd b/desiredata/src/tests/gop-one.pd deleted file mode 100644 index b1414997..00000000 --- a/desiredata/src/tests/gop-one.pd +++ /dev/null @@ -1,18 +0,0 @@ -#N canvas 447 533 552 376 10; -#X obj 5 24 vsl 10 50 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X obj 20 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 20 58 5 0 0 0 - - -; -#X obj 41 21 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X obj 6 124 outlet; -#X obj 80 0 inlet; -#X obj 136 8 inlet; -#X connect 0 0 2 0; -#X connect 1 0 4 0; -#X connect 2 0 4 0; -#X connect 3 0 4 0; -#X connect 5 0 0 0; -#X connect 6 0 1 0; -#X coords 0 0 1 1 60 85 1 0 0; diff --git a/desiredata/src/tests/gop-three.pd b/desiredata/src/tests/gop-three.pd deleted file mode 100644 index 7ab5cb13..00000000 --- a/desiredata/src/tests/gop-three.pd +++ /dev/null @@ -1,41 +0,0 @@ -#N canvas 238 407 695 410 10; -#N canvas 0 0 450 300 three 0; -#X obj 89 21 gop-two; -#X obj 22 65 vsl 10 50 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X obj 41 61 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 63 61 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X floatatom 41 101 5 0 0 0 - - -; -#X obj 259 3 inlet; -#X obj 339 4 inlet; -#X obj 51 237 outlet; -#X connect 0 0 7 0; -#X connect 1 0 4 0; -#X connect 2 0 0 1; -#X connect 4 0 0 0; -#X connect 5 0 1 0; -#X connect 6 0 2 0; -#X coords 0 0 1 1 250 150 1 0 0; -#X restore 182 100 pd three; -#X obj 100 165 vsl 10 50 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X floatatom 121 202 5 0 0 0 - - -; -#X obj 121 262 print A; -#X obj 182 262 print B; -#X obj 100 43 random 127; -#X obj 100 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 100 68 t f f; -#X obj 425 62 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 460 120 gop-two; -#X connect 0 0 4 0; -#X connect 1 0 2 0; -#X connect 2 0 3 0; -#X connect 5 0 7 0; -#X connect 6 0 5 0; -#X connect 7 0 1 0; -#X connect 7 1 0 0; -#X connect 8 0 0 1; diff --git a/desiredata/src/tests/gop-two.pd b/desiredata/src/tests/gop-two.pd deleted file mode 100644 index 080cf53f..00000000 --- a/desiredata/src/tests/gop-two.pd +++ /dev/null @@ -1,19 +0,0 @@ -#N canvas 373 135 592 432 10; -#X obj 80 20 gop-one; -#X obj 9 44 vsl 10 50 0 127 0 0 empty empty empty 0 -6 0 8 -262144 --1 -1 0 1; -#X obj 25 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 50 40 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X floatatom 29 82 5 0 0 0 - - -; -#X obj 81 162 outlet; -#X obj 168 11 inlet; -#X obj 237 12 inlet; -#X connect 0 0 5 0; -#X connect 1 0 4 0; -#X connect 2 0 0 1; -#X connect 4 0 0 0; -#X connect 6 0 1 0; -#X connect 7 0 2 0; -#X coords 0 0 1 1 150 120 1 0 0; diff --git a/desiredata/src/tests/sub.pd b/desiredata/src/tests/sub.pd deleted file mode 100644 index 1a9e570b..00000000 --- a/desiredata/src/tests/sub.pd +++ /dev/null @@ -1,21 +0,0 @@ -#N canvas 586 146 668 714 10; -#X obj 86 58 +; -#X obj 107 130 -; -#N canvas 0 0 450 300 foo 0; -#X obj 110 30 inlet; -#X obj 110 100 + 1.618; -#X obj 110 130 * 3.14159; -#X obj 110 180 outlet; -#X connect 0 0 1 0; -#X connect 1 0 2 0; -#X connect 2 0 3 0; -#X restore 224 153 pd foo; -#X obj 101 73 +; -#X obj 122 145 -; -#X msg 220 120 42; -#X floatatom 220 180 8 0 0 0 - - -; -#X text 220 200 137.03; -#X connect 0 0 1 0; -#X connect 2 0 6 0; -#X connect 3 0 4 0; -#X connect 5 0 2 0; diff --git a/desiredata/src/tests/subgop-test.pd b/desiredata/src/tests/subgop-test.pd deleted file mode 100644 index 48fb0bb1..00000000 --- a/desiredata/src/tests/subgop-test.pd +++ /dev/null @@ -1,8 +0,0 @@ -#N canvas 0 0 450 300 10; -#N canvas 0 0 450 300 foo 1; -#X obj 10 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 276 183 print; -#X coords 0 -1 1 1 85 60 1 0 0; -#X restore 145 113 pd foo; -#X obj 319 154 pack; diff --git a/desiredata/src/u_pdreceive.c b/desiredata/src/u_pdreceive.c deleted file mode 100644 index e58fb177..00000000 --- a/desiredata/src/u_pdreceive.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright (c) 2000 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */ - -/* the "pdreceive" command. This is a standalone program that receives messages -from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to -standard output. */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#ifdef MSW -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <netdb.h> -#include <stdio.h> -#include <unistd.h> -#define SOCKET_ERROR -1 -#endif - -typedef struct _fdpoll { - int fd; - char *inbuf; - int inhead; - int intail; - int udp; -} t_fdpoll; - -static int nfdpoll; -static t_fdpoll *fdpoll; -static int maxfd; -static int sockfd; -static int protocol; - -static void sockerror(const char *s); -static void x_closesocket(int fd); -static void dopoll(); -#define BUFSIZE 4096 - -int main(int argc, char **argv) {{ // open extra scope because of goto and decls - int portno; - struct sockaddr_in server; - if (argc < 2 || sscanf(argv[1],"%d",&portno)<1 || portno<=0) goto usage; - if (argc >= 3) { - if (!strcmp(argv[2],"tcp")) protocol = SOCK_STREAM; - else if (!strcmp(argv[2],"udp")) protocol = SOCK_DGRAM; - else goto usage; - } else protocol = SOCK_STREAM; -#ifdef MSW - short version = MAKEWORD(2, 0); - WSADATA nobby; - if (WSAStartup(version, &nobby)) sockerror("WSAstartup"); -#endif - sockfd = socket(AF_INET, protocol, 0); - if (sockfd < 0) { - sockerror("socket()"); - exit(1); - } - maxfd = sockfd + 1; - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; -#ifdef IRIX - /* this seems to work only in IRIX but is unnecessary in Linux. Not sure what MSW needs in place of this. */ - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) fprintf(stderr, "setsockopt failed\n"); -#endif - /* assign client port number */ - server.sin_port = htons((unsigned short)portno); - /* name the socket */ - if (bind(sockfd, (struct sockaddr *)&server, sizeof(server))<0) {sockerror("bind"); x_closesocket(sockfd); return 0;} - if (protocol == SOCK_STREAM) if (listen(sockfd, 5) < 0) {sockerror("listen"); x_closesocket(sockfd); return 1;} - /* now loop forever selecting on sockets */ - while (1) dopoll(); - } // close extra scope so that we can goto. -usage: - fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n"); - fprintf(stderr, "(default is tcp)\n"); - return 1; -} - -static void addport(int fd) { - fdpoll = (t_fdpoll *)realloc(fdpoll, (nfdpoll+1)*sizeof(t_fdpoll)); - t_fdpoll *fp = fdpoll + nfdpoll; - fp->fd = fd; - nfdpoll++; - if (fd >= maxfd) maxfd = fd + 1; - fp->inhead = fp->intail = 0; - if (!(fp->inbuf = (char *) malloc(BUFSIZE))) {fprintf(stderr, "out of memory"); exit(1);} - printf("number_connected %d;\n", nfdpoll); -} - -static void rmport(t_fdpoll *x) { - t_fdpoll *fp = fdpoll; - for (int i=nfdpoll; i--; fp++) { - if (fp == x) { - x_closesocket(fp->fd); - free(fp->inbuf); - for (;i--;fp++) fp[0] = fp[1]; - fdpoll = (t_fdpoll *)realloc(fdpoll, (nfdpoll-1)*sizeof(t_fdpoll)); - nfdpoll--; - printf("number_connected %d;\n", nfdpoll); - return; - } - } - fprintf(stderr, "warning: item removed from poll list but not found"); -} - -static void doconnect() { - int fd = accept(sockfd, 0, 0); - if (fd < 0) perror("accept"); - else addport(fd); -} - -static void udpread() { - char buf[BUFSIZE]; - int ret = recv(sockfd, buf, BUFSIZE, 0); - if (ret<0) { - sockerror("recv (udp)"); - x_closesocket(sockfd); - exit(1); - } else if (ret>0) { -#ifdef MSW - for (int j=0; j<ret; j++) putchar(buf[j]); -#else - if (write(1, buf, ret) < ret) {perror("write"); exit(1);} -#endif - } -} - -static int tcpmakeoutput(t_fdpoll *x) { - char messbuf[BUFSIZE+1], *bp = messbuf; - int inhead = x->inhead; - int intail = x->intail; - char *inbuf = x->inbuf; - if (intail == inhead) return 0; - for (int indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1)) { - /* search for a semicolon. */ - char c = *bp++ = inbuf[indx]; - if (c == ';') { - intail = (indx+1)&(BUFSIZE-1); - if (inbuf[intail] == '\n') intail = (intail+1)&(BUFSIZE-1); - *bp++ = '\n'; -#ifdef MSW - for (int j=0; j<bp-messbuf; j++) putchar(messbuf[j]); -#else - if (write(1, messbuf, bp-messbuf)<bp-messbuf) {perror("write"); exit(1);} -#endif - x->inhead = inhead; - x->intail = intail; - return 1; - } - } - return 0; -} - -static void tcpread(t_fdpoll *x) { - int readto = x->inhead >= x->intail ? BUFSIZE : x->intail-1; - int ret; - /* the input buffer might be full. If so, drop the whole thing */ - if (readto == x->inhead) { - fprintf(stderr, "pd: dropped message from gui\n"); - x->inhead = x->intail = 0; - readto = BUFSIZE; - } else { - ret = recv(x->fd, x->inbuf + x->inhead, readto - x->inhead, 0); - if (ret < 0) { - sockerror("recv (tcp)"); - rmport(x); - } else if (ret == 0) rmport(x); - else { - x->inhead += ret; - if (x->inhead >= BUFSIZE) x->inhead = 0; - while (tcpmakeoutput(x)) {} - } - } -} - -static void dopoll() { - fd_set readset, writeset, exceptset; - FD_ZERO(&writeset); - FD_ZERO(&readset); - FD_ZERO(&exceptset); - FD_SET(sockfd, &readset); - if (protocol == SOCK_STREAM) { - t_fdpoll *fp = fdpoll; - for (int i=nfdpoll; i--; fp++) FD_SET(fp->fd, &readset); - } - if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0) {perror("select"); exit(1);} - if (protocol == SOCK_STREAM) { - for (int i=0; i<nfdpoll; i++) if (FD_ISSET(fdpoll[i].fd, &readset)) tcpread(&fdpoll[i]); - if (FD_ISSET(sockfd, &readset)) doconnect(); - } else { - if (FD_ISSET(sockfd, &readset)) udpread(); - } -} - -static void sockerror(const char *s) { -#ifdef MSW - int err = WSAGetLastError(); - if (err == 10054) return; - else if (err == 10044) fprintf(stderr,"Warning: you might not have TCP/IP \"networking\" turned on\n"); -#else - int err = errno; -#endif - fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); -} - -static void x_closesocket(int fd) { -#ifdef MSW - closesocket(fd); -#else - close(fd); -#endif -} diff --git a/desiredata/src/u_pdsend.c b/desiredata/src/u_pdsend.c deleted file mode 100644 index 8bcf8880..00000000 --- a/desiredata/src/u_pdsend.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (c) 2000 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */ - -/* the "pdsend" command. This is a standalone program that forwards messages -from its standard input to Pd via the netsend/netreceive ("FUDI") protocol. */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#ifdef MSW -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <netdb.h> -#include <stdio.h> -#include <unistd.h> -#define SOCKET_ERROR -1 -#endif - -void sockerror(const char *s); -void x_closesocket(int fd); -#define BUFSIZE 4096 - -int main(int argc, char **argv) { - int sockfd, portno, protocol; - struct sockaddr_in server; - struct hostent *hp; - const char *hostname; -#ifdef MSW - short version = MAKEWORD(2, 0); - WSADATA nobby; -#endif - if (argc<2 || sscanf(argv[1], "%d", &portno)<1 || portno<=0) goto usage; - if (argc>=3) hostname = argv[2]; else hostname = "127.0.0.1"; - if (argc >= 4) { - if (!strcmp(argv[3], "tcp")) protocol = SOCK_STREAM; - else if (!strcmp(argv[3], "udp")) protocol = SOCK_DGRAM; - else goto usage; - } else protocol = SOCK_STREAM; -#ifdef MSW - if (WSAStartup(version, &nobby)) sockerror("WSAstartup"); -#endif - sockfd = socket(AF_INET, protocol, 0); - if (sockfd < 0) {sockerror("socket()"); return 1;} - /* connect socket using hostname provided in command line */ - server.sin_family = AF_INET; - hp = gethostbyname(hostname); - if (!hp) {fprintf(stderr, "%s: unknown host\n", hostname); x_closesocket(sockfd); return 1;} - memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); - server.sin_port = htons((unsigned short)portno); - if (connect(sockfd, (struct sockaddr *)&server, sizeof(server))<0) {sockerror("connect"); x_closesocket(sockfd); return 1;} - /* now loop reading stdin and sending it to socket */ - while (1) { - char buf[BUFSIZE], *bp; - unsigned int nsent, nsend; - if (!fgets(buf, BUFSIZE, stdin)) break; - nsend = strlen(buf); - for (bp = buf, nsent = 0; nsent < nsend;) { - int res = send(sockfd, buf, nsend-nsent, 0); - if (res<0) {sockerror("send"); goto done;} - nsent += res; - bp += res; - } - } -done: - if (ferror(stdin)) perror("stdin"); - return 0; -usage: - fprintf(stderr, "usage: pdsend <portnumber> [host] [udp|tcp]\n"); - fprintf(stderr, "(default is localhost and tcp)\n"); - return 1; -} - -void sockerror(const char *s) { -#ifdef MSW - int err = WSAGetLastError(); - if (err == 10054) return; - else if (err == 10044) fprintf(stderr,"Warning: you might not have TCP/IP \"networking\" turned on\n"); -#else - int err = errno; -#endif - fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); -} - -void x_closesocket(int fd) { -#ifdef MSW - closesocket(fd); -#else - close(fd); -#endif -} diff --git a/desiredata/src/unused.tcl b/desiredata/src/unused.tcl deleted file mode 100644 index 98601545..00000000 --- a/desiredata/src/unused.tcl +++ /dev/null @@ -1,78 +0,0 @@ -if {$tk} { - set main [Client new] - set window_list [list $main] -} else { - set cmdline(console) 0 - #foreach dir $auto_path { - # set file $dir/libtclreadline[info sharedlibextension] - # puts "trying $file" - # if {![catch {load $file}]} {puts "found tclreadline !"} - #} - package require tclreadline - proc ::tclreadline::prompt1 {} {return "desire> "} - ::tclreadline::Loop - #while {1} { - # #set line [::tclreadline::readline read] - # puts -nonewline "desire> " - # flush stdout - # set line [gets stdin] - # if {[catch {puts [eval $line]}]} { - # puts "error: $::errorInfo" - # } - #} - #vwait foo -} - - -#lappend ::auto_path /usr/local/lib/graphviz -catch {package require Tcldot} -def Canvas graphviz_sort {} { - error "this code has to be rewritten to use the new containers" - set nodes {} - set gwidth 0; set gh 0 - #toplevel .graph -height 600 -width 800 - #set c [canvas .graph.c -height 600 -width 800] - #pack $c - set g [dotnew digraph] - $g setnodeattribute style filled color white - foreach child $@children { - lappend nodes [$g addnode $child label "[$child text]" shape "record" height "0.1"] - lappend nodes $child - } - puts "$nodes" - foreach wire $@wires { - mset {from outlet to inlet} [$wire report] - set n1 [lindex $nodes [expr [lsearch $nodes $from]-1]] - set n2 [lindex $nodes [expr [lsearch $nodes $to]-1]] - $n1 addedge $n2 - } - #$g layout - ;# see what render produces - #if {$debug} {puts [$g render]} - #eval [$g render] - set f {} - set fd [open graph.txt w] - $g write $fd plain - close $fd - - set fd [open graph.txt r] - set contents [read $fd] - close $fd - exec rm graph.txt - mset {x1 y1 x2 y2} [[$self widget] bbox all] - set width [expr $x2 - $x1] - set height [expr $y2 - $y1] - foreach line [split $contents "\n"] { - switch [lindex $line 0] { - graph {set gw [lindex $line 2]; set gh [lindex $line 3]} - node { - set w [expr $width/$gw] - set h [expr $height/$gh] - set id [lindex $line 1] - set x [lindex $line 2]; set y [lindex $line 3] - $id moveto [expr $x*$w] [expr ($gh-$y)*$h] - } - edge {break} - } - } -} diff --git a/desiredata/src/valgrind3.supp b/desiredata/src/valgrind3.supp deleted file mode 100644 index 7ec16dbb..00000000 --- a/desiredata/src/valgrind3.supp +++ /dev/null @@ -1,89 +0,0 @@ -{ - supp01 - Memcheck:Param - ioctl(arg) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_prepare - fun:snd_pcm_hw_params - fun:_Z12alsaio_setupP9_alsa_deviPiS1_ii - fun:_Z15alsa_open_audioiPiiS_iS_iS_ii - fun:sys_open_audio -} -{ - supp02 - Memcheck:Param - ioctl(arg) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_prepare - fun:_Z15alsa_open_audioiPiiS_iS_iS_ii - fun:sys_open_audio -} -{ - supp03 - Memcheck:Param - ioctl(generic) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_link - fun:_Z15alsa_open_audioiPiiS_iS_iS_ii - fun:sys_open_audio -} -{ - supp04 - Memcheck:Cond - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libc-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - fun:dlopen - fun:_Z15sys_do_load_libP6_glistPc - fun:sys_load_lib -} -{ - supp05 - Memcheck:Cond - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libc-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - fun:dlopen - fun:_Z15sys_do_load_libP6_glistPc - fun:sys_load_lib -} -{ - supp06 - Memcheck:Param - ioctl(arg) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_start - fun:_Z15alsa_open_audioiPiiS_iS_iS_ii - fun:sys_open_audio -} -{ - supp07 - Memcheck:Param - ioctl(arg) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_drop - fun:snd_pcm_close - fun:_Z16alsa_close_audiov - fun:sys_close_audio -} -{ - supp08 - Memcheck:Param - ioctl(arg) - obj:/lib/ld-2.3.6.so - fun:snd_pcm_hw_free - fun:snd_pcm_close - fun:_Z16alsa_close_audiov - fun:sys_close_audio -} - |