From 4fe8863a1176f7fe4057d82b2844dd7127b13bca Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Wed, 16 Mar 2005 04:59:36 +0000 Subject: much cleaner Window GUI code fixed bug with param method updated build system minimal feedback attribute for parameter reporting clean handling of plugin deletion (potentially open editor window etc.) updated for new flext function naming names containing spaces are now correctly dumped added event processing (like Midi in) more consistent MIDI functionality trying to catch crashing plugins svn path=/trunk/; revision=2630 --- externals/grill/vst/pd/help-vst~.pd | 389 ++++++++++++++++++++-------------- externals/grill/vst/readme.txt | 4 + externals/grill/vst/src/editor.h | 5 +- externals/grill/vst/src/editorwin.hpp | 197 ++++++++++------- externals/grill/vst/src/main.cpp | 126 +++++------ externals/grill/vst/src/vstedit.cpp | 52 +++-- externals/grill/vst/src/vsthost.cpp | 159 +++++++++++--- externals/grill/vst/src/vsthost.h | 74 +++++-- externals/grill/vst/src/vstmaster.cpp | 2 +- externals/grill/vst/src/vstparam.cpp | 1 + externals/grill/vst/vst.vcproj | 3 + 11 files changed, 644 insertions(+), 368 deletions(-) (limited to 'externals/grill/vst') diff --git a/externals/grill/vst/pd/help-vst~.pd b/externals/grill/vst/pd/help-vst~.pd index db5c5af9..d1a93cc4 100644 --- a/externals/grill/vst/pd/help-vst~.pd +++ b/externals/grill/vst/pd/help-vst~.pd @@ -1,16 +1,11 @@ -#N canvas 125 128 857 564 12; -#X obj 26 190 dac~; +#N canvas 80 16 858 559 12; #X obj 26 94 noise~; -#X obj 93 189 print A; -#X obj 443 431 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 -1; -#X msg 442 453 vis \$1; -#X obj 231 430 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 -1; -#X msg 230 452 edit \$1; -#X msg 298 452 getedit; -#X msg 505 453 getvis; -#N canvas 367 122 562 438 info 0; +#X obj 229 189 print A; +#X obj 27 393 tgl 15 0 empty empty empty 0 -6 0 8 -261689 -1 -1 1 1 +; +#X msg 27 435 edit \$1; +#X msg 97 435 getedit; +#N canvas 367 122 570 368 info 0; #X msg 92 160 getversion; #X msg 92 105 getname; #X msg 93 183 getvendor; @@ -20,11 +15,6 @@ #X msg 93 134 getdll; #X obj 24 290 s \$0-vst; #X msg 98 323 print; -#X msg 99 370 echo \$1; -#X obj 98 353 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1 -; -#X msg 171 369 getecho; -#X text 248 351 old stuff; #X text 169 220 is synth?; #X text 177 183 get vendor string; #X text 179 161 get version; @@ -46,90 +36,139 @@ #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 8 0 7 0; -#X connect 9 0 7 0; -#X connect 10 0 9 0; -#X connect 11 0 7 0; -#X connect 19 0 7 0; +#X connect 15 0 7 0; +#X connect 16 0 7 0; +#X connect 18 0 7 0; #X connect 20 0 7 0; -#X connect 22 0 7 0; -#X connect 24 0 7 0; -#X restore 445 110 pd info; +#X restore 516 114 pd info; #X obj 96 96 r \$0-vst; -#X obj 229 479 s \$0-vst; -#X obj 441 479 s \$0-vst; -#X text 256 429 display edit window; -#X text 466 429 make edit window (in)visible; -#X msg 105 295 getplug; -#X obj 26 323 s \$0-vst; -#X text 65 249 set/get plugin; -#X text 511 110 further information; +#X obj 26 462 s \$0-vst; +#X text 52 392 display edit window; +#X msg 104 309 getplug; +#X obj 25 337 s \$0-vst; +#X text 64 263 set/get plugin; +#X text 582 114 further information; #X obj 23 15 cnv 15 800 58 empty empty vst~ 10 32 0 24 -260818 -1 0 ; -#X text 90 170 attribute outlet; -#X text 103 137 inlets outlets [plugname]; -#N canvas 367 122 521 329 win 0; -#X obj 11 287 s \$0-vst; -#X msg 28 84 getx; -#X text 135 77 get window coordinates; -#X msg 73 84 gety; -#X obj 25 26 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --225271 -1 -1 0 256; -#X msg 26 44 x \$1; -#X obj 95 26 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --225271 -1 -1 0 256; -#X msg 96 42 y \$1; -#X text 165 26 set window coordinates; -#X text 161 43 (position of the actual VST interface); -#X text 132 92 (position of the actual VST interface); -#X obj 67 130 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1 -; -#X msg 66 149 caption \$1; -#X msg 161 149 getcaption; -#X text 69 173 set/get window caption and borders; -#X text 68 238 set/get window title; -#X msg 168 214 gettitle; -#X msg 65 214 title KARL; +#X text 226 170 attribute outlet; +#X text 103 132 inlets outlets [plugname]; +#N canvas 351 2 626 581 win 0; +#X obj 23 202 s \$0-vst; +#X msg 122 83 getx; +#X msg 181 85 gety; +#X obj 122 37 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +10 -225271 -1 -1 0 256; +#X msg 123 55 x \$1; +#X obj 192 37 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +10 -225271 -1 -1 0 256; +#X msg 193 53 y \$1; +#X text 264 74 (position of the actual VST interface); +#X obj 117 208 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 +1; +#X msg 116 227 caption \$1; +#X msg 211 227 getcaption; +#X text 119 251 set/get window caption and borders; +#X text 118 316 set/get window title; +#X msg 218 292 gettitle; +#X msg 115 292 title KARL; +#X obj 120 124 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +10 -225271 -1 -1 0 256; +#X obj 190 124 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +10 -225271 -1 -1 0 256; +#X msg 121 142 w \$1; +#X msg 120 170 getw; +#X msg 191 140 h \$1; +#X msg 175 170 geth; +#X text 265 144 set and get editor window size; +#X text 267 59 set and get editor position; +#X obj 122 458 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225271 -1 +-1; +#X text 280 457 send editor window to front; +#X msg 223 457 front; +#X obj 145 457 delay 100; +#X obj 123 500 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 +1; +#X msg 145 497 handle \$1; +#X text 230 498 set/unset handle for window (taskbar button); +#X obj 118 374 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 +1; +#X msg 117 396 vis \$1; +#X msg 186 396 getvis; +#X text 141 372 make edit window (in)visible; #X connect 1 0 0 0; -#X connect 3 0 0 0; -#X connect 4 0 5 0; -#X connect 5 0 0 0; -#X connect 6 0 7 0; -#X connect 7 0 0 0; -#X connect 11 0 12 0; -#X connect 12 0 0 0; +#X connect 2 0 0 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 8 0 9 0; +#X connect 9 0 0 0; +#X connect 10 0 0 0; #X connect 13 0 0 0; -#X connect 16 0 0 0; +#X connect 14 0 0 0; +#X connect 15 0 17 0; +#X connect 16 0 19 0; #X connect 17 0 0 0; -#X restore 446 244 pd win; -#X text 512 244 manipulating the edit window; -#X msg 28 296 plug \$1; -#X obj 27 240 bng 25 250 50 0 empty empty empty 0 -6 0 8 -225271 -1 +#X connect 18 0 0 0; +#X connect 19 0 0 0; +#X connect 20 0 0 0; +#X connect 23 0 26 0; +#X connect 25 0 0 0; +#X connect 26 0 25 0; +#X connect 27 0 28 0; +#X connect 28 0 0 0; +#X connect 30 0 31 0; +#X connect 31 0 0 0; +#X connect 32 0 0 0; +#X restore 515 244 pd win; +#X text 581 244 manipulating the edit window; +#X msg 27 310 plug \$1; +#X obj 26 254 bng 25 250 50 0 empty empty empty 0 -6 0 8 -261689 -1 -1; -#X obj 27 271 openpanel; -#N canvas 461 281 502 347 midi 0; -#X obj 20 279 s \$0-vst; -#X msg 238 147 ctlchg 3 123; -#X text 116 28 note on; -#X text 287 29 note off; -#X text 348 146 control change; -#X text 312 233 pitch bend; -#X text 319 174 program change; -#X msg 237 175 progchg 2; -#X msg 197 30 noteoff 10; -#X text 315 282 after touch; -#X obj 238 213 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +#X obj 26 285 openpanel; +#N canvas 294 23 530 659 midi 0; +#X obj 16 256 s \$0-vst; +#X msg 198 201 ctlchg 3 123; +#X text 204 70 note on; +#X text 375 71 note off; +#X text 308 200 control change; +#X text 272 287 pitch bend; +#X text 279 228 program change; +#X msg 197 229 progchg 2; +#X msg 285 72 noteoff 10; +#X text 275 336 after touch; +#X obj 198 267 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +10 -225271 -1 -1 0 256; +#X obj 198 318 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 -1 -1 0 256; -#X obj 238 264 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +#X msg 197 287 pbend \$1; +#X msg 196 337 atouch \$1; +#X obj 109 136 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 -1 -1 0 256; -#X msg 237 233 pbend \$1; -#X msg 236 283 atouch \$1; -#X obj 35 71 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 --225271 -1 -1 0 256; -#X msg 20 29 note 10 100; -#X msg 36 94 note \$1 100; -#X msg 193 94 noteoff \$1; -#X obj 194 72 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 +#X msg 108 71 note 10 100; +#X msg 108 152 note \$1 100; +#X msg 284 126 noteoff \$1; +#X obj 285 109 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 -1 -1 0 256; +#X text 25 520 MIDI messages have the following format:; +#X text 23 544 [event midi subtype chn b2 b3 delta note-length note-offset +detune off-velocity(; +#X obj 90 371 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1 +; +#X msg 90 390 events \$1; +#X msg 90 415 getevents; +#X text 177 393 enable event processing; +#X text 25 463 if enabled vst~ will output events generated by the +plugin as [event ...( messages through the dump outlet; +#X msg 108 93 note 10 0; +#X text 188 93 "note off"; +#X obj 107 12 nbx 5 14 0 15 0 0 empty empty empty 0 -6 0 10 -225271 +-1 -1 0 256; +#X msg 106 28 channel \$1; +#X msg 207 28 getchannel; +#X text 305 20 set/get MIDI channel; +#X text 25 585 subtypes are note \, noteoff \, atouch \, patouch \, +ctlchg \, progchg \, pbend; #X connect 1 0 0 0; #X connect 7 0 0 0; #X connect 8 0 0 0; @@ -142,24 +181,31 @@ #X connect 16 0 0 0; #X connect 17 0 0 0; #X connect 18 0 17 0; -#X restore 445 208 pd midi; +#X connect 21 0 22 0; +#X connect 22 0 0 0; +#X connect 23 0 0 0; +#X connect 26 0 0 0; +#X connect 28 0 29 0; +#X connect 29 0 0 0; +#X connect 30 0 0 0; +#X restore 516 212 pd midi; #X text 134 33 based on the work of Jarno Seppanen and Mark Williamson ; -#X obj 723 444 loadbang; -#X msg 723 471 \; pd dsp 1; -#X obj 230 324 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 +#X obj 742 456 loadbang; +#X msg 742 483 \; pd dsp 1; +#X obj 518 449 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1; -#X obj 228 373 s \$0-vst; -#X msg 229 346 bypass \$1; -#X msg 311 346 getbypass; -#X text 255 323 bypass plugin; -#X obj 231 240 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 +#X obj 516 498 s \$0-vst; +#X msg 517 471 bypass \$1; +#X msg 599 471 getbypass; +#X text 543 448 bypass plugin; +#X obj 518 357 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1; -#X obj 229 289 s \$0-vst; -#X text 256 239 mute output; -#X msg 230 262 mute \$1; -#X msg 312 262 getmute; -#N canvas 200 110 481 432 parameters 0; +#X obj 516 406 s \$0-vst; +#X text 543 356 mute output; +#X msg 517 379 mute \$1; +#X msg 599 379 getmute; +#N canvas 200 110 493 444 parameters 0; #X obj 114 125 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -225271 -1 -1 0 1; #X msg 111 142 param 2 \$1; @@ -199,7 +245,7 @@ #X connect 17 0 18 0; #X connect 18 0 2 0; #X connect 19 0 2 0; -#X restore 444 143 pd parameters; +#X restore 515 147 pd parameters; #N canvas 0 0 462 312 programs 0; #X obj 39 245 s \$0-vst; #X msg 162 106 getprogram; @@ -230,19 +276,50 @@ #X connect 10 0 0 0; #X connect 12 0 14 0; #X connect 14 0 0 0; -#X restore 445 175 pd programs; -#X text 561 144 VST parameters; -#X text 562 175 VST programs; +#X restore 516 179 pd programs; +#X text 632 148 VST parameters; +#X text 633 179 VST programs; #X text 134 53 http://grrrr.org; -#X text 513 209 midi messages for VST synths; -#X msg 47 413 subplug AudioTrack; -#X obj 32 498 s \$0-vst; -#X msg 54 468 getsubplug; -#X obj 26 140 vst~ 2 2 @pnames 100; -#X text 229 501 you can also alt-click on the vst~ object; -#X msg 32 382 getpluglist; -#X msg 52 440 subplug C4; -#N canvas 105 36 474 631 time 0; +#X text 584 213 midi messages for VST synths; +#X msg 276 313 subplug AudioTrack; +#X obj 261 398 s \$0-vst; +#X msg 283 368 getsubplug; +#X obj 26 135 vst~ 2 2 @pnames 100; +#X msg 261 282 getpluglist; +#X text 580 271 sequencer stuff; +#X text 133 14 VST plugins for PD \, (C)2003-2005 Thomas Grill; +#X msg 281 340 subplug X-Noise; +#N canvas 0 0 466 316 out 0; +#X obj 79 164 *~; +#X obj 79 194 dac~ 1 2 3 4; +#X obj 109 164 *~; +#X obj 139 164 *~; +#X obj 169 164 *~; +#X obj 266 26 inlet; +#X obj 49 26 inlet~; +#X obj 102 26 inlet~; +#X obj 154 26 inlet~; +#X obj 206 26 inlet~; +#X obj 265 108 line~; +#X msg 266 82 \$1 1 20; +#X connect 0 0 1 0; +#X connect 2 0 1 1; +#X connect 3 0 1 2; +#X connect 4 0 1 3; +#X connect 5 0 11 0; +#X connect 6 0 0 0; +#X connect 7 0 2 0; +#X connect 8 0 3 0; +#X connect 9 0 4 0; +#X connect 10 0 4 1; +#X connect 10 0 3 1; +#X connect 10 0 2 1; +#X connect 10 0 0 1; +#X connect 11 0 10 0; +#X restore 26 192 pd out; +#X obj 72 175 hsl 128 15 0.001 1 1 1 empty empty gain -2 -6 0 8 -261689 +-1 -1 4100 1; +#N canvas 105 36 490 647 seq 0; #X obj 17 225 s \$0-vst; #X msg 112 78 samplepos \$1; #X obj 111 60 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 @@ -276,15 +353,15 @@ -1 -1 0 256; #X msg 112 379 looplength \$1; #X msg 227 379 getlooplength; -#X obj 112 512 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 +#X obj 115 521 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271 -1 -1 0 256; -#X msg 113 528 smpteoffset \$1; -#X msg 235 528 getsmpteoffset; -#X msg 113 570 smpterate \$1; -#X msg 227 570 getsmpterate; -#X obj 113 553 hradio 15 1 0 6 empty empty empty 0 -6 0 8 -225271 -1 +#X msg 116 537 smpteoffset \$1; +#X msg 238 537 getsmpteoffset; +#X msg 116 579 smpterate \$1; +#X msg 230 579 getsmpterate; +#X obj 116 562 hradio 15 1 0 6 empty empty empty 0 -6 0 8 -225271 -1 -1 0; -#X text 227 552 24/25/24/30/29.97df/30df; +#X text 230 561 24/25/24/30/29.97df/30df; #X obj 112 415 nbx 5 14 1 128 0 1 empty empty empty 0 -6 0 10 -225271 -1 -1 4 256; #X msg 113 433 timenom \$1; @@ -333,35 +410,35 @@ #X connect 35 0 36 0; #X connect 36 0 0 0; #X connect 37 0 0 0; -#X restore 446 280 pd time; -#X text 513 278 sequencer stuff; -#X text 133 14 VST plugins for PD \, (C)2003-2005 Thomas Grill; -#X text 443 319 Attention: this vst~ version will crash when a plugin -is unloaded with the editor window open!; -#X connect 1 0 50 0; -#X connect 1 0 50 1; -#X connect 3 0 4 0; -#X connect 4 0 12 0; -#X connect 5 0 6 0; -#X connect 6 0 11 0; -#X connect 7 0 11 0; -#X connect 8 0 12 0; -#X connect 10 0 50 0; -#X connect 15 0 16 0; -#X connect 24 0 16 0; -#X connect 25 0 26 0; -#X connect 26 0 24 0; -#X connect 29 0 30 0; -#X connect 31 0 33 0; -#X connect 33 0 32 0; -#X connect 34 0 32 0; -#X connect 36 0 39 0; -#X connect 39 0 37 0; -#X connect 40 0 37 0; -#X connect 47 0 48 0; -#X connect 49 0 48 0; -#X connect 50 0 0 0; -#X connect 50 1 0 1; -#X connect 50 2 2 0; -#X connect 52 0 48 0; -#X connect 53 0 48 0; +#X restore 515 273 pd seq; +#X text 23 508 on the vst~ object box; +#X text 24 491 you can also alt-click; +#X obj 27 413 pipe 100; +#X text 261 243 functions for plugin shells; +#X text 259 259 (like Waves); +#X connect 0 0 44 0; +#X connect 0 0 44 1; +#X connect 2 0 54 0; +#X connect 3 0 7 0; +#X connect 4 0 7 0; +#X connect 6 0 44 0; +#X connect 9 0 10 0; +#X connect 18 0 10 0; +#X connect 19 0 20 0; +#X connect 20 0 18 0; +#X connect 23 0 24 0; +#X connect 25 0 27 0; +#X connect 27 0 26 0; +#X connect 28 0 26 0; +#X connect 30 0 33 0; +#X connect 33 0 31 0; +#X connect 34 0 31 0; +#X connect 41 0 42 0; +#X connect 43 0 42 0; +#X connect 44 0 49 0; +#X connect 44 1 49 1; +#X connect 44 2 1 0; +#X connect 45 0 42 0; +#X connect 48 0 42 0; +#X connect 50 0 49 4; +#X connect 54 0 3 0; diff --git a/externals/grill/vst/readme.txt b/externals/grill/vst/readme.txt index fc55be79..6cebdeb7 100644 --- a/externals/grill/vst/readme.txt +++ b/externals/grill/vst/readme.txt @@ -58,6 +58,10 @@ Version history: - pre19: better shell support - pre19: restructured code and added time info - pre19: support for event processing (like MIDI in) +- pre21: consistent MIDI handling, correct handling of parameters with spaces +- pre22: cleaner GUI code, all kinds of window handling +- pre22: catch exceptions like crashing plugs +- pre23: security measures for open edit window 0.0.0: - version of mark@junklight.com diff --git a/externals/grill/vst/src/editor.h b/externals/grill/vst/src/editor.h index ad03f59c..7c5831e7 100644 --- a/externals/grill/vst/src/editor.h +++ b/externals/grill/vst/src/editor.h @@ -2,7 +2,7 @@ vst~ - VST plugin object for PD based on the work of Jarno Seppänen and Mark Williamson -Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net) +Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ @@ -20,6 +20,7 @@ void MoveEditor(VSTPlugin *p,int x,int y); void SizeEditor(VSTPlugin *p,int x,int y); void TitleEditor(VSTPlugin *p,const char *t); void CaptionEditor(VSTPlugin *p,bool c); -bool IsEditorShown(const VSTPlugin *p); +void HandleEditor(VSTPlugin *p,bool h); +void FrontEditor(VSTPlugin *p); #endif // __EDITOR_H diff --git a/externals/grill/vst/src/editorwin.hpp b/externals/grill/vst/src/editorwin.hpp index 29e63db6..9d97771b 100644 --- a/externals/grill/vst/src/editorwin.hpp +++ b/externals/grill/vst/src/editorwin.hpp @@ -2,7 +2,7 @@ vst~ - VST plugin object for PD based on the work of Jarno Seppänen and Mark Williamson -Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net) +Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ @@ -37,12 +37,13 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) // Initialize the window. plug->StartEditing(hwnd); break; + case WM_CLOSE: #ifdef FLEXT_LOGGING flext::post("WM_CLOSE"); #endif - // plug could already have been unloaded... - plug->StopEditing(); // this sets plug->hwnd = NULL + plug->StopEditing(); + DestroyWindow(hwnd); break; case WM_DESTROY: @@ -57,7 +58,26 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) case WM_ENTERIDLE: plug->EditorIdle(); break; +#if 0 + case WM_WINDOWPOSCHANGED: { + // ignore after WM_CLOSE so that x,y positions are preserved + if(!plug->IsEdited()) break; + WINDOWPOS *w = (WINDOWPOS *)lp; + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int cpx = winfo.rcWindow.left-winfo.rcClient.left; + int cpy = winfo.rcWindow.top-winfo.rcClient.top; + int csx = winfo.rcWindow.right-winfo.rcClient.right-cpx; + int csy = winfo.rcWindow.bottom-winfo.rcClient.bottom-cpy; + // send normalized coordinates to plugin + plug->SetPos(w->x+cpx,w->y+cpy,false); + plug->SetSize(w->cx+csx,w->cy+csy,false); + return 0; + } +#else case WM_MOVE: { // ignore after WM_CLOSE so that x,y positions are preserved if(!plug->IsEdited()) break; @@ -65,12 +85,36 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) WORD wx = LOWORD(lp),wy = HIWORD(lp); short x = reinterpret_cast(wx),y = reinterpret_cast(wy); // x and y are the coordinates of the client rect (= actual VST interface) - plug->SetPos(x,y,false); -#ifdef FLEXT_LOGGING - flext::post("WM_MOVE x/y=%i/%i",x,y); -#endif + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int px = winfo.rcWindow.left-winfo.rcClient.left; + int py = winfo.rcWindow.top-winfo.rcClient.top; + // send normalized coordinates to plugin + plug->SetPos(x+px,y+py,false); + break; + } + + case WM_SIZE: { + if(!plug->IsEdited()) break; + + WORD wx = LOWORD(lp),wy = HIWORD(lp); + short x = reinterpret_cast(wx),y = reinterpret_cast(wy); + // x and y are the coordinates of the client rect (= actual VST interface) + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int px = winfo.rcWindow.left-winfo.rcClient.left; + int py = winfo.rcWindow.top-winfo.rcClient.top; + int sx = winfo.rcWindow.right-winfo.rcClient.right-px; + int sy = winfo.rcWindow.bottom-winfo.rcClient.bottom-py; + // send normalized coordinates to plugin + plug->SetSize(x+sx,y+sy,false); break; } +#endif #if 0 // NOT needed for Windows case WM_PAINT: { @@ -86,16 +130,9 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) break; } #endif - -#if 0 //def FLEXT_LOGGING - case WM_SIZE: { - WORD wx = LOWORD(lp),wy = HIWORD(lp); - short x = reinterpret_cast(wx),y = reinterpret_cast(wy); - // x and y are the coordinates of the client rect (= actual VST interface) - flext::post("WM_SIZE x/y=%i/%i",x,y); - break; - } -#endif + case WM_SHOWWINDOW: + plug->Visible(wp != FALSE,false); + break; default: #ifdef FLEXT_LOGGING @@ -107,22 +144,25 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) return res; } -static void windowsize(HWND wnd,int x,int y,int w,int h,bool caption,LONG flags = 0) +static void windowsize(HWND wnd,int x,int y,int w,int h) { - WINDOWINFO winfo; + // pre correction + WINDOWINFO winfo; winfo.cbSize = sizeof(winfo); GetWindowInfo(wnd,&winfo); + int sx1 = (winfo.rcWindow.right-winfo.rcClient.right)-(winfo.rcWindow.left-winfo.rcClient.left); + int sy1 = (winfo.rcWindow.bottom-winfo.rcClient.bottom)-(winfo.rcWindow.top-winfo.rcClient.top); - int cy = caption?GetSystemMetrics(SM_CYCAPTION):0; + // First reflect new state in flags + SetWindowPos(wnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); - SetWindowPos(wnd,HWND_TOP, - x-(winfo.rcClient.left-winfo.rcWindow.left), - y-(winfo.rcClient.top-winfo.rcWindow.top), - w+winfo.cxWindowBorders*2, - h+cy+winfo.cyWindowBorders*2, - flags - ); + // post correction + GetWindowInfo(wnd,&winfo); + int sx2 = (winfo.rcWindow.right-winfo.rcClient.right)-(winfo.rcWindow.left-winfo.rcClient.left); + int sy2 = (winfo.rcWindow.bottom-winfo.rcClient.bottom)-(winfo.rcWindow.top-winfo.rcClient.top); + // set pos, size and flags + SetWindowPos(wnd,NULL,x,y,w+sx2-sx1,h+sy2-sy1,SWP_NOZORDER); } static void threadfun(flext::thr_params *p) @@ -137,14 +177,18 @@ static void threadfun(flext::thr_params *p) wndmap[thrid] = plug; mapmutex.Unlock(); - char tmp[256]; sprintf(tmp,"vst~ - %s",plug->GetName()); - HWND wnd = CreateWindow( + // Get size from plugin + ERect r; + plug->GetEditorRect(r); + + HWND wnd = CreateWindowEx( + plug->GetHandle()?WS_EX_APPWINDOW:WS_EX_TOOLWINDOW, WCLNAME,tmp, - (plug->GetCaption()?WS_BORDER|WS_CAPTION:0)|WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, + WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, // no border for the beginning to set proper coordinates + plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top, NULL,NULL, hinstance,NULL ); @@ -152,34 +196,30 @@ static void threadfun(flext::thr_params *p) if(!wnd) FLEXT_LOG1("wnd == NULL: %i",GetLastError()); else { -// plug->Dispatch(effEditOpen , 0 , 0 , wnd, 0.0f ); // Done in WNDPROC!! - /* - CString str = theApp->GetProfileString( "VSTPos" , plug->GetName() , "10,10"); - int idx = str.Find(","); - CString x = str.Left( idx ); - CString y = str.Right( idx ); - printf(" index is %d left is %s and right is %s" , idx , x , y); - */ - -// plug->Dispatch(effEditTop,0,0, 0,0.0f); - // printf("Dispatched to the top\n"); - - SetTimer(wnd,0,TIMER_INTERVAL,NULL); - - ERect r; - plug->GetEditorRect(r); - windowsize(wnd,plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top,plug->GetCaption(),SWP_SHOWWINDOW); -#ifdef FLEXT_LOGGING - flext::post("Editor rect left/top=%i/%i, right/bottom=%i/%i",r.left,r.top,r.right,r.bottom); -#endif + // idle timer + SetTimer(wnd,0,TIMER_INTERVAL,NULL); + + // set caption style + CaptionEditor(plug,plug->GetCaption()); + + if(plug->IsVisible()) { + SetForegroundWindow(wnd); + ShowWindow(wnd,1); + + // notify plugin + // plug->Dispatch(effEditTop,0,0,0,0); + } + else + ShowWindow(wnd,0); - // SetFocus(); + try + { - // Message pump + // Message loop MSG msg; BOOL bRet; while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) { - if (bRet == -1) { + if(bRet == -1) { // handle the error and possibly exit FLEXT_LOG1("GetMessage error: %i",GetLastError()); } @@ -188,9 +228,18 @@ static void threadfun(flext::thr_params *p) DispatchMessage(&msg); } } - } -// UnregisterClass(wcx.lpszClassName,hinstance); + } + + catch(exception &e) { + flext::post("vst~ - exception caught, exiting: %s",e.what()); + } + catch(...) { + flext::post("vst~ - exception caught, exiting"); + } + + if(plug) plug->EditingEnded(); + } mapmutex.Lock(); wndmap.erase(thrid); @@ -235,7 +284,7 @@ void StopEditor(VSTPlugin *p) flext::post("Stop editor 1"); #endif PostMessage(p->EditorHandle(),WM_CLOSE,0,0); - flext::StopThread(threadfun,reinterpret_cast(p)); +// flext::StopThread(threadfun,reinterpret_cast(p)); #ifdef FLEXT_LOGGING flext::post("Stop editor 2"); #endif @@ -249,21 +298,18 @@ void ShowEditor(VSTPlugin *p,bool show) void MoveEditor(VSTPlugin *p,int x,int y) { HWND wnd = p->EditorHandle(); - - WINDOWINFO winfo; - winfo.cbSize = sizeof(winfo); - GetWindowInfo(wnd,&winfo); - - SetWindowPos(wnd,NULL, - x-(winfo.rcClient.left-winfo.rcWindow.left),y-(winfo.rcClient.top-winfo.rcWindow.top), - 0,0, - SWP_NOSIZE|SWP_NOZORDER - ); + SetWindowPos(wnd,NULL,x,y,0,0,SWP_NOSIZE|SWP_NOZORDER); } void SizeEditor(VSTPlugin *p,int x,int y) { - SetWindowPos(p->EditorHandle(),NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER); + HWND wnd = p->EditorHandle(); + SetWindowPos(wnd,NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER); +} + +void FrontEditor(VSTPlugin *p) +{ + SetForegroundWindow(p->EditorHandle()); } void CaptionEditor(VSTPlugin *plug,bool c) @@ -274,18 +320,27 @@ void CaptionEditor(VSTPlugin *plug,bool c) else ns = style&~(WS_BORDER|WS_CAPTION); if(ns != style) { SetWindowLong(wnd,GWL_STYLE,ns); - - ERect r; plug->GetEditorRect(r); - windowsize(wnd,plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top,c,SWP_FRAMECHANGED); + windowsize(wnd,plug->GetX(),plug->GetY(),plug->GetW(),plug->GetH()); } } +void HandleEditor(VSTPlugin *plug,bool h) +{ + HWND wnd = plug->EditorHandle(); + bool v = plug->IsVisible(); + if(v) ShowWindow(wnd,FALSE); + SetWindowLong(wnd,GWL_EXSTYLE,h?WS_EX_APPWINDOW:WS_EX_TOOLWINDOW); + if(v) ShowWindow(wnd,TRUE); +} + void TitleEditor(VSTPlugin *p,const char *t) { SetWindowText(p->EditorHandle(),t); } +/* bool IsEditorShown(const VSTPlugin *p) { return IsWindowVisible(p->EditorHandle()) != FALSE; } +*/ \ No newline at end of file diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp index 9a4b3a6c..d1c369c3 100644 --- a/externals/grill/vst/src/main.cpp +++ b/externals/grill/vst/src/main.cpp @@ -26,7 +26,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #endif -#define VST_VERSION "0.1.0pre21" +#define VST_VERSION "0.1.0pre23" class vst @@ -64,12 +64,19 @@ protected: void mg_winx(int &x) const { x = plug?plug->GetX():0; } void mg_winy(int &y) const { y = plug?plug->GetY():0; } + void mg_winw(int &x) const { x = plug?plug->GetW():0; } + void mg_winh(int &y) const { y = plug?plug->GetH():0; } void ms_winx(int x) { if(plug) plug->SetX(x); } void ms_winy(int y) { if(plug) plug->SetY(y); } + void ms_winw(int x) { if(plug) plug->SetW(x); } + void ms_winh(int y) { if(plug) plug->SetH(y); } void ms_wincaption(bool c) { if(plug) plug->SetCaption(c); } void mg_wincaption(bool &c) const { c = plug && plug->GetCaption(); } + void ms_winhandle(bool c) { if(plug) plug->SetHandle(c); } + void mg_winhandle(bool &c) const { c = plug && plug->GetHandle(); } void ms_wintitle(const AtomList &t); void mg_wintitle(AtomList &t) const { if(plug) { t(1); SetString(t[0],plug->GetTitle()); } } + void m_winfront() const { if(plug) plug->ToFront(); } void mg_chnsin(int &c) const { c = plug?plug->GetNumInputs():0; } void mg_chnsout(int &c) const { c = plug?plug->GetNumOutputs():0; } @@ -98,13 +105,19 @@ protected: void m_ptext(int pnum); void m_ptexts(int argc,const t_atom *argv); -// void m_control(const t_symbol *ctrl_name,int ctrl_value); - void m_pitchbend(int ctrl_value) { if(plug) plug->AddPitchBend(ctrl_value ); } - void m_programchange(int ctrl_value) { if(plug) plug->AddProgramChange(ctrl_value ); } - void m_aftertouch(int ctrl_value) { if(plug) plug->AddAftertouch(ctrl_value ); } - void m_ctrlchange(int control,int ctrl_value) { if(plug) plug->AddControlChange(control,ctrl_value ); } + void mg_channel(int &chn) const { chn = plug?plug->GetChannel():0; } + void ms_channel(int chn) { if(plug) plug->SetChannel(chn); } + void m_note(int note,int vel); void m_noteoff(int note) { m_note(note,0); } + void m_programchange(int ctrl_value) { if(plug) plug->AddProgramChange(ctrl_value); } + void m_ctrlchange(int control,int ctrl_value) { if(plug) plug->AddControlChange(control,ctrl_value); } + void m_aftertouch(int ctrl_value) { if(plug) plug->AddAftertouch(ctrl_value); } + void m_polyaftertouch(int note,int ctrl_value) { if(plug) plug->AddPolyAftertouch(note,ctrl_value); } + void m_pitchbend(int ctrl_value) { if(plug) plug->AddPitchBend(ctrl_value); } + + void mg_dumpevents(bool &ev) const { ev = plug?plug->GetEvents():false; } + void ms_dumpevents(bool ev) { if(plug) plug->SetEvents(ev); } void mg_playing(bool &p) { p = plug && plug->GetPlaying(); } void ms_playing(bool p) { if(plug) plug->SetPlaying(p); } @@ -140,7 +153,7 @@ private: VSTPlugin *plug; std::string plugname,subplug; - bool echoparam,visible,bypass,mute; + bool visible,bypass,mute; int paramnames; int blsz; @@ -171,12 +184,17 @@ private: FLEXT_ATTRVAR_B(bypass) FLEXT_ATTRVAR_B(mute) -// FLEXT_CALLBACK_2(m_control,t_symptr,int) - FLEXT_CALLBACK_I(m_pitchbend) - FLEXT_CALLBACK_I(m_aftertouch) - FLEXT_CALLBACK_I(m_programchange) + FLEXT_CALLVAR_I(mg_channel,ms_channel) + FLEXT_CALLBACK_II(m_note) + FLEXT_CALLBACK_I(m_noteoff) FLEXT_CALLBACK_II(m_ctrlchange) + FLEXT_CALLBACK_I(m_aftertouch) + FLEXT_CALLBACK_II(m_polyaftertouch) + FLEXT_CALLBACK_I(m_pitchbend) + + FLEXT_CALLVAR_B(mg_dumpevents,ms_dumpevents) + FLEXT_CALLBACK_I(m_programchange) FLEXT_CALLVAR_I(mg_program,ms_program) FLEXT_CALLBACK_V(mg_progname) @@ -190,14 +208,14 @@ private: FLEXT_CALLBACK_I(m_ptext) FLEXT_CALLBACK_V(m_ptexts) - FLEXT_CALLBACK_II(m_note) - FLEXT_CALLBACK_I(m_noteoff) - - FLEXT_ATTRVAR_B(echoparam) FLEXT_CALLVAR_I(mg_winx,ms_winx) FLEXT_CALLVAR_I(mg_winy,ms_winy) + FLEXT_CALLVAR_I(mg_winw,ms_winw) + FLEXT_CALLVAR_I(mg_winh,ms_winh) FLEXT_CALLVAR_B(mg_wincaption,ms_wincaption) + FLEXT_CALLVAR_B(mg_winhandle,ms_winhandle) FLEXT_CALLVAR_V(mg_wintitle,ms_wintitle) + FLEXT_CALLBACK(m_winfront) FLEXT_CALLGET_I(mg_chnsin) FLEXT_CALLGET_I(mg_chnsout) @@ -250,12 +268,15 @@ void vst::Setup(t_classid c) FLEXT_CADDATTR_VAR1(c,"mute",mute); FLEXT_CADDMETHOD_(c,0,"print",m_print); - FLEXT_CADDMETHOD_II(c,0,"note",m_note); + FLEXT_CADDATTR_VAR(c,"channel",mg_channel,ms_channel); FLEXT_CADDMETHOD_I(c,0,"noteoff",m_noteoff); -// FLEXT_CADDMETHOD_2(c,0,"control",m_control,t_symptr,int); - FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); - FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); + FLEXT_CADDMETHOD_II(c,0,"note",m_note); + FLEXT_CADDMETHOD_II(c,0,"patouch",m_polyaftertouch); FLEXT_CADDMETHOD_II(c,0,"ctlchg",m_ctrlchange); + FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); + FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); + + FLEXT_CADDATTR_VAR(c,"events",mg_dumpevents,ms_dumpevents); FLEXT_CADDMETHOD_(c,0,"progchg",m_programchange); FLEXT_CADDATTR_VAR(c,"program",mg_program,ms_program); @@ -270,11 +291,14 @@ void vst::Setup(t_classid c) FLEXT_CADDMETHOD_(c,0,"getptext",m_ptext); FLEXT_CADDMETHOD_(c,0,"getptext",m_ptexts); - FLEXT_CADDATTR_VAR1(c,"echo",echoparam); FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); FLEXT_CADDATTR_VAR(c,"y",mg_winy,ms_winy); - FLEXT_CADDATTR_VAR(c,"caption",mg_wincaption,ms_wincaption); + FLEXT_CADDATTR_VAR(c,"w",mg_winw,ms_winw); + FLEXT_CADDATTR_VAR(c,"h",mg_winh,ms_winh); FLEXT_CADDATTR_VAR(c,"title",mg_wintitle,ms_wintitle); + FLEXT_CADDATTR_VAR(c,"caption",mg_wincaption,ms_wincaption); + FLEXT_CADDATTR_VAR(c,"handle",mg_winhandle,ms_winhandle); + FLEXT_CADDMETHOD_(c,0,"front",m_winfront); FLEXT_CADDATTR_GET(c,"ins",mg_chnsin); FLEXT_CADDATTR_GET(c,"outs",mg_chnsout); @@ -318,7 +342,7 @@ vst::vst(int argc,const t_atom *argv): plug(NULL),visible(false), blsz(0), vstfun(NULL),vstin(NULL),vstout(NULL),tmpin(NULL),tmpout(NULL), - echoparam(false),bypass(false),mute(false),paramnames(0) + bypass(false),mute(false),paramnames(0) { #if FLEXT_OS == FLEXT_OS_WIN // this is necessary for Waveshell @@ -346,9 +370,9 @@ vst::~vst() void vst::ClearPlug() { if(plug) { - plug->Edit(false); ClearBuf(); // needs valid plug - delete plug; plug = NULL; + VSTPlugin::Delete(plug); + plug = NULL; } } @@ -440,15 +464,17 @@ static std::string findFilePath(const std::string &path,const std::string &dllna return std::string(); } - +// \todo this should be in the background, because it can take some time +// ideally vst would get a response from VSTPlugin when readily, loaded and +// vst would dump out a respective signal to the patcher bool vst::LoadPlug() { if(plug) ClearPlug(); - plug = new VSTPlugin(this); + VSTPlugin *p = VSTPlugin::New(this); // try loading the dll from the raw filename - bool ok = plug->Instance(plugname.c_str(),subplug.c_str()); + bool ok = p->Instance(plugname.c_str(),subplug.c_str()); if(ok) FLEXT_LOG("raw filename loaded fine"); else { @@ -468,7 +494,7 @@ bool vst::LoadPlug() dllname += "\\"; dllname += name; - ok = plug->Instance(dllname.c_str()); + ok = p->Instance(dllname.c_str()); } #endif } @@ -497,7 +523,7 @@ bool vst::LoadPlug() realpath += plugname; FLEXT_LOG1("trying %s",(const char *)realpath.c_str()); - ok = plug->Instance(realpath.c_str()); + ok = p->Instance(realpath.c_str()); if(ok) { FLEXT_LOG("plugin loaded via VST_PATH"); break; @@ -505,7 +531,7 @@ bool vst::LoadPlug() } tok = strtok( NULL , ";" ); - if(!tok) post("%s - couldn't find plugin",thisName()); +// if(!tok) post("%s - couldn't find plugin",thisName()); } delete[] tok_path; @@ -514,10 +540,12 @@ bool vst::LoadPlug() if(!ok) { post("%s - unable to load plugin '%s'",thisName(),plugname.c_str()); - ClearPlug(); + VSTPlugin::Delete(p); } - else + else { + plug = p; InitPlug(); + } return ok; } @@ -674,32 +702,6 @@ void vst::CbSignal() flext_dsp::CbSignal(); } - -#if 0 - -void vst::m_control(const t_symbol *ctrl_name,int ctrl_value) -{ - if(!plug) return; - - int parm_num = 0; - - if (!*GetString(ctrl_name) || !strlen(GetString(ctrl_name))) { - error ("plugin~: control messages must have a name and a value"); - return; - } - //parm_num = vst_tilde_get_parm_number (x, ctrl_name->s_name); - //if (parm_num) - //{ - //vst_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value); - //} - //else - //{ - //vst_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value); - //} -} - -#endif - void vst::mg_progname(int argc,const t_atom *argv) const { if(plug) { @@ -788,8 +790,8 @@ void vst::m_print(int ac,const t_atom *av) } if ( header ) { - post("VST~ plugin: %s " , plug->GetName() ); - post("made by: %s " , plug->GetVendorName() ); + post("VST~ plugin: %s ", plug->GetName() ); + post("made by: %s ", plug->GetVendorName() ); post("parameters %d\naudio: %d in(s)/%d out(s) \nLoaded from library \"%s\".\n", plug->GetNumParams(), CntInSig(), @@ -868,12 +870,12 @@ void vst::ms_param(int pnum,float val) { if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - float xval = plug->GetParamValue( pnum ); +// float xval = plug->GetParamValue( pnum ); // if(xval <= 1.0f) // What's that???? if(true) { plug->SetParamFloat( pnum, val ); - if(echoparam) display_parameter(pnum , true ); +// if(echoparam) display_parameter(pnum , true ); } else FLEXT_ASSERT(false); diff --git a/externals/grill/vst/src/vstedit.cpp b/externals/grill/vst/src/vstedit.cpp index 804e83ca..1536b9d3 100644 --- a/externals/grill/vst/src/vstedit.cpp +++ b/externals/grill/vst/src/vstedit.cpp @@ -27,50 +27,56 @@ void VSTPlugin::StartEditing(WHandle h) { FLEXT_ASSERT(h != NULL); Dispatch(effEditOpen,0,0,hwnd = h); -// Dispatch(effEditTop); TitleEditor(this,title.c_str()); } void VSTPlugin::StopEditing() { - if(Is()) { - Dispatch(effEditClose); - hwnd = NULL; - } + if(Is() && IsEdited()) + Dispatch(effEditClose); } -void VSTPlugin::Visible(bool vis) +void VSTPlugin::Visible(bool vis,bool upd) { - if(Is() && IsEdited()) ShowEditor(this,vis); + visible = vis; + if(upd && Is() && IsEdited()) ShowEditor(this,vis); } -bool VSTPlugin::IsVisible() const -{ - return Is() && IsEdited() && IsEditorShown(this); +void VSTPlugin::SetPos(int x,int y,bool upd) +{ + posx = x; posy = y; + if(upd && Is() && IsEdited()) MoveEditor(this,posx,posy); } - -void VSTPlugin::SetPos(int x,int y,bool upd) +void VSTPlugin::SetSize(int x,int y,bool upd) { - if(Is()) { - posx = x; posy = y; - if(upd && IsEdited()) MoveEditor(this,posx,posy); - } + sizex = x; sizey = y; + if(upd && Is() && IsEdited()) SizeEditor(this,sizex,sizey); } void VSTPlugin::SetCaption(bool c) { - if(Is()) { - caption = c; - if(IsEdited()) CaptionEditor(this,c); - } + caption = c; + if(Is() && IsEdited()) CaptionEditor(this,c); +} + +void VSTPlugin::SetHandle(bool h) +{ + handle = h; + if(Is() && IsEdited()) HandleEditor(this,h); } void VSTPlugin::SetTitle(const char *t) { - if(Is()) { - title = t; - if(IsEdited()) TitleEditor(this,t); + title = t; + if(Is() && IsEdited()) TitleEditor(this,t); +} + +void VSTPlugin::ToFront() +{ + if(Is() && IsEdited()) { + FrontEditor(this); + Dispatch(effEditTop,0,0,vendorname); } } diff --git a/externals/grill/vst/src/vsthost.cpp b/externals/grill/vst/src/vsthost.cpp index 3b9d6241..5f2443fc 100644 --- a/externals/grill/vst/src/vsthost.cpp +++ b/externals/grill/vst/src/vsthost.cpp @@ -8,7 +8,9 @@ WARRANTIES, see the file, "license.txt," in this distribution. */ #include "vsthost.h" - +#include "editor.h" +#include +#include "flcontainers.h" const t_symbol *VSTPlugin::sym_param, @@ -22,8 +24,22 @@ const t_symbol *VSTPlugin::sym_ev_, *VSTPlugin::sym_midi[8]; + +class DelPlugin + : public Fifo::Cell +{ +public: + DelPlugin(VSTPlugin *p): plug(p) {} + VSTPlugin *plug; +}; + +static TypedLifo todel; +flext::ThrCond VSTPlugin::thrcond; + void VSTPlugin::Setup() { + LaunchThread(worker); + sym_param = flext::MakeSymbol("param"); sym_event = flext::MakeSymbol("event"); sym_evmidi = flext::MakeSymbol("midi"); @@ -34,22 +50,23 @@ void VSTPlugin::Setup() sym_evsysex = flext::MakeSymbol("sysex"); sym_ev_ = flext::MakeSymbol("???"); - sym_midi[0] = flext::MakeSymbol("noteon"); - sym_midi[1] = flext::MakeSymbol("noteoff"); - sym_midi[2] = flext::MakeSymbol("polyafter"); - sym_midi[3] = flext::MakeSymbol("cntl"); + sym_midi[0] = flext::MakeSymbol("noteoff"); + sym_midi[1] = flext::MakeSymbol("note"); + sym_midi[2] = flext::MakeSymbol("atouch"); + sym_midi[3] = flext::MakeSymbol("ctlchg"); sym_midi[4] = flext::MakeSymbol("progchg"); - sym_midi[5] = flext::MakeSymbol("chnafter"); - sym_midi[6] = flext::MakeSymbol("pitchbend"); - sym_midi[7] = sym__; + sym_midi[5] = flext::MakeSymbol("atouch"); + sym_midi[6] = flext::MakeSymbol("pbend"); + sym_midi[7] = flext::MakeSymbol("sysex"); } VSTPlugin::VSTPlugin(Responder *resp) : hdll(NULL),hwnd(NULL) , effect(NULL),pluginmain(NULL),audiomaster(NULL) , responder(resp) - , posx(0),posy(0),caption(true) - , midichannel(0),eventqusz(0) + , posx(0),posy(0),sizex(0),sizey(0) + , visible(true),caption(true),handle(false) + , midichannel(0),eventqusz(0),dumpevents(false) , paramnamecnt(0) , transchg(true) , playing(false),looping(false),feedback(false) @@ -67,7 +84,55 @@ VSTPlugin::~VSTPlugin() Free(); } +VSTPlugin *VSTPlugin::New(Responder *resp) +{ + FLEXT_ASSERT(resp); + return new VSTPlugin(resp); +} + +void VSTPlugin::Delete(VSTPlugin *p) +{ + FLEXT_ASSERT(p); + + // tell plugin to close editor! + StopEditor(p); + // transfer to deletion thread + todel.Push(new DelPlugin(p)); + thrcond.Signal(); +} + +void VSTPlugin::worker(thr_params *) +{ + TypedLifo tmp; + bool again = false; + for(;;) { + // wait for signal + if(again) { + thrcond.TimedWait(0.01); + again = false; + } + else + thrcond.Wait(); + + DelPlugin *p; + while((p = todel.Pop()) != NULL) { + // see if editing has stopped + if(p && p->plug->hwnd == NULL) { + // yes, it is now safe to delete the plug + delete p->plug; + delete p; + } + else { + tmp.Push(p); + again = true; + } + } + // put back remaining entries + while((p = tmp.Pop()) != NULL) todel.Push(p); + } +} + #if FLEXT_OS == FLEXT_OS_MAC OSStatus FSPathMakeFSSpec(const UInt8 *path,FSSpec *spec,Boolean *isDirectory) /* can be NULL */ { @@ -208,9 +273,17 @@ bool VSTPlugin::InstPlugin(long plugid) FLEXT_ASSERT(pluginmain && audiomaster); //This calls the "main" function and receives the pointer to the AEffect structure. - effect = pluginmain(audiomaster); - if(!effect || effect->magic != kEffectMagic) { - post("VST plugin : Unable to create effect"); + try { effect = pluginmain(audiomaster); } + catch(exception &e) { + flext::post("vst~ - caught exception while instantiating plugin: %s",e.what()); + } + catch(...) { + flext::post("vst~ - caught exception while instantiating plugin"); + } + + if(!effect) + return false; + else if(effect->magic != kEffectMagic) { effect = NULL; return false; } @@ -219,13 +292,19 @@ bool VSTPlugin::InstPlugin(long plugid) bool VSTPlugin::Instance(const char *name,const char *subname) { - bool ok = effect != NULL; + bool ok = false; + FLEXT_ASSERT(effect == NULL); + try { + +/* if(!ok && dllname != name) { FreePlugin(); // freshly load plugin ok = NewPlugin(name) && InstPlugin(); } +*/ + ok = NewPlugin(name) && InstPlugin(); if(ok && subname && *subname && Dispatch(effGetPlugCategory) == kPlugCategShell) { // sub plugin-name given -> scan plugs @@ -294,37 +373,53 @@ bool VSTPlugin::Instance(const char *name,const char *subname) Dispatch(effGetVendorString,0,0,vendorname); } + } + catch(exception &e) { + flext::post("vst~ - caught exception while loading plugin: %s",e.what()); + ok = false; + } + catch(...) { + flext::post("vst~ - Caught exception while loading plugin"); + ok = false; + } + if(!ok) Free(); return ok; } -void VSTPlugin::Free() // Called also in destruction +void VSTPlugin::Free() { - if(effect) { - Edit(false); + // This should only also in destruction - // shut down plugin - Dispatch(effMainsChanged, 0, 0); - Dispatch(effClose); - } + try { + if(effect) { + FLEXT_ASSERT(!IsEdited()); - // \TODO - // Here, we really have to wait until the editor thread has terminated - // otherwise WM_DESTROY etc. messages may still be pending - // in other words: this is a design flaw - // There should be a data stub accessible from the plugin object and the thread - // holding the necessary data, so that both can operate independently + // shut down plugin + Dispatch(effMainsChanged, 0, 0); + Dispatch(effClose); + } + } + catch(...) {} FreePlugin(); } void VSTPlugin::DspInit(float sr,int blsz) { - // sample rate and block size must _first_ be set - Dispatch(effSetSampleRate,0,0,NULL,samplerate = sr); - Dispatch(effSetBlockSize, 0,blsz); - // then signal that mains have changed! - Dispatch(effMainsChanged,0,1); + try { + // sample rate and block size must _first_ be set + Dispatch(effSetSampleRate,0,0,NULL,samplerate = sr); + Dispatch(effSetBlockSize, 0,blsz); + // then signal that mains have changed! + Dispatch(effMainsChanged,0,1); + } + catch(exception &e) { + flext::post("vst~ - caught exception while initializing dsp: %s",e.what()); + } + catch(...) { + flext::post("vst~ - caught exception while initializing dsp"); + } } void VSTPlugin::ListPlugs(const t_symbol *sym) const diff --git a/externals/grill/vst/src/vsthost.h b/externals/grill/vst/src/vsthost.h index bda1d538..0b1adef0 100644 --- a/externals/grill/vst/src/vsthost.h +++ b/externals/grill/vst/src/vsthost.h @@ -40,19 +40,27 @@ public: virtual void Respond(const t_symbol *sym,int argc = 0,const t_atom *argv = NULL) = 0; }; + class VSTPlugin: public flext { public: + static VSTPlugin *New(Responder *resp); + static void Delete(VSTPlugin *p); static void Setup(); + bool Instance(const char *plug,const char *subplug = NULL); + void DspInit(float samplerate,int blocksize); + +private: VSTPlugin(Responder *resp); ~VSTPlugin(); - bool Instance(const char *plug,const char *subplug = NULL); + static ThrCond thrcond; + static void worker(thr_params *p); + void Free(); - void DspInit(float samplerate,int blocksize); ////////////////////////////////////////////////////////////////////////////// @@ -119,81 +127,104 @@ private: public: void SetPos(int x,int y,bool upd = true); + void SetSize(int x,int y,bool upd = true); void SetX(int x,bool upd = true) { SetPos(x,posy,upd); } void SetY(int y,bool upd = true) { SetPos(posx,y,upd); } + void SetW(int x,bool upd = true) { SetSize(x,sizey,upd); } + void SetH(int y,bool upd = true) { SetSize(sizex,y,upd); } int GetX() const { return posx; } int GetY() const { return posy; } + int GetW() const { return sizex; } + int GetH() const { return sizey; } void SetCaption(bool b); bool GetCaption() const { return caption; } + void SetHandle(bool h); + bool GetHandle() const { return handle; } void SetTitle(const char *t); const char *GetTitle() const { return title.c_str(); } + void ToFront(); void Edit(bool open); - void StartEditing(WHandle h ); + void StartEditing(WHandle h); void StopEditing(); bool IsEdited() const { return hwnd != NULL; } WHandle EditorHandle() const { return hwnd; } + void EditingEnded() { hwnd = NULL; thrcond.Signal(); } void GetEditorRect(ERect &er) const { ERect *r; Dispatch(effEditGetRect,0,0,&r); er = *r; } void EditorIdle() { Dispatch(effEditIdle); } - void Visible(bool vis); - bool IsVisible() const; + void Visible(bool vis,bool upd = true); + bool IsVisible() const { return visible; } void Paint(ERect &r) const { Dispatch(effEditDraw,0,0,&r); } private: - int posx,posy; // Window position + bool visible; + int posx,posy,sizex,sizey; // Window position bool caption; // Window border + bool handle; // Window handle (like taskbar button) std::string title; // Window title ////////////////////////////////////////////////////////////////////////////// public: enum { - MIDI_NOTEON = 144, - MIDI_NOTEOFF = 128, - MIDI_POLYAFTERTOUCH = 160, - MIDI_CONTROLCHANGE = 176, - MIDI_PROGRAMCHANGE = 192, - MIDI_AFTERTOUCH = 208, - MIDI_PITCHBEND = 224 + MIDI_NOTEOFF = 0x80, + MIDI_NOTEON = 0x90, + MIDI_POLYAFTERTOUCH = 0xa0, + MIDI_CONTROLCHANGE = 0xb0, + MIDI_PROGRAMCHANGE = 0xc0, + MIDI_AFTERTOUCH = 0xd0, + MIDI_PITCHBEND = 0xe0, + MIDI_SYSEX = 0xf0, }; + void SetEvents(bool ev) { dumpevents = ev; } + bool GetEvents() const { return dumpevents; } + bool AddMIDI(unsigned char data0,unsigned char data1 = 0,unsigned char data2 = 0); static int range(int value,int mn = 0,int mx = 127) { return value < mn?mn:(value > mx?mx:value); } - bool AddNoteOn(unsigned char note,unsigned char speed,unsigned char midichannel = 0) + void SetChannel(int channel) { midichannel = range(channel,0,0xf); } + int GetChannel() const { return midichannel; } + + bool AddNoteOn(unsigned char note,unsigned char speed /*,unsigned char midichannel = 0*/) { - return AddMIDI((char)MIDI_NOTEON|midichannel,note,speed); + return AddMIDI(MIDI_NOTEON+midichannel,note,speed); } - bool AddNoteOff(unsigned char note,unsigned char midichannel = 0) + bool AddNoteOff(unsigned char note /*,unsigned char midichannel = 0*/) { - return AddMIDI((char)MIDI_NOTEOFF|midichannel,note,0); + return AddMIDI(MIDI_NOTEOFF+midichannel,note,0); } void AddControlChange(int control,int value) { - AddMIDI(MIDI_CONTROLCHANGE+(midichannel&0xf),range(control),range(value)); + AddMIDI(MIDI_CONTROLCHANGE+midichannel,range(control),range(value)); } void AddProgramChange(int value) { - AddMIDI(MIDI_PROGRAMCHANGE+(midichannel&0xf),range(value),0); + AddMIDI(MIDI_PROGRAMCHANGE+midichannel,range(value),0); } void AddPitchBend(int value) { - AddMIDI(MIDI_PITCHBEND+(midichannel&0xf),((value>>7)&127),(value&127)); + AddMIDI(MIDI_PITCHBEND+midichannel,((value>>7)&127),(value&127)); } void AddAftertouch(int value) { - AddMIDI((char)MIDI_AFTERTOUCH|midichannel,range(value)); + AddMIDI(MIDI_AFTERTOUCH+midichannel,range(value)); + } + + void AddPolyAftertouch(unsigned char note,int value) + { + AddMIDI(MIDI_POLYAFTERTOUCH+midichannel,note,range(value)); } private: @@ -205,6 +236,7 @@ private: int eventqusz; char midichannel; + bool dumpevents; ////////////////////////////////////////////////////////////////////////////// diff --git a/externals/grill/vst/src/vstmaster.cpp b/externals/grill/vst/src/vstmaster.cpp index 108d8079..00a93c80 100644 --- a/externals/grill/vst/src/vstmaster.cpp +++ b/externals/grill/vst/src/vstmaster.cpp @@ -16,7 +16,7 @@ static const char *product = "vst~"; void VSTPlugin::ProcessEvent(const VstEvent &ev) { - if(!responder) return; + if(!responder && dumpevents) return; if(ev.type == kVstMidiType) { const VstMidiEvent &mev = (const VstMidiEvent &)ev; diff --git a/externals/grill/vst/src/vstparam.cpp b/externals/grill/vst/src/vstparam.cpp index 30515b23..bb80263e 100644 --- a/externals/grill/vst/src/vstparam.cpp +++ b/externals/grill/vst/src/vstparam.cpp @@ -16,6 +16,7 @@ static void striptrail(char *txt) for(int i = strlen(txt)-1; i >= 0; --i) // cast to unsigned char since isspace functions don't want characters like 0x80 = -128 if(isspace(((unsigned char *)txt)[i])) txt[i] = 0; + else break; } void VSTPlugin::GetParamName(int numparam,char *name) const diff --git a/externals/grill/vst/vst.vcproj b/externals/grill/vst/vst.vcproj index 42d904ef..aa447805 100644 --- a/externals/grill/vst/vst.vcproj +++ b/externals/grill/vst/vst.vcproj @@ -247,6 +247,9 @@ + + -- cgit v1.2.1